From 840673e4e5ff178b34c9bce7b2ddfeb4bb9d4300 Mon Sep 17 00:00:00 2001 From: Carlos Ruiz Date: Fri, 13 Oct 2017 17:40:12 +0200 Subject: [PATCH 1/7] IDEMPIERE-2877 Adapt jasper reporting to latest (actually using deprecated methods) / thanks to Tiago Ceridorio (tifece) for the patch --- org.adempiere.ui.zk/META-INF/MANIFEST.MF | 1 + .../adempiere/webui/window/ZkJRViewer.java | 172 +++++++++++------- .../webui/window/ZkJRViewerProvider.java | 23 ++- 3 files changed, 131 insertions(+), 65 deletions(-) diff --git a/org.adempiere.ui.zk/META-INF/MANIFEST.MF b/org.adempiere.ui.zk/META-INF/MANIFEST.MF index 199ef6947b..827c76b5d7 100644 --- a/org.adempiere.ui.zk/META-INF/MANIFEST.MF +++ b/org.adempiere.ui.zk/META-INF/MANIFEST.MF @@ -17,6 +17,7 @@ Import-Package: javax.activation, net.sf.jasperreports.engine, net.sf.jasperreports.engine.export, net.sf.jasperreports.engine.util, + net.sf.jasperreports.export, org.adempiere.report.jasper, org.apache.commons.codec.binary, org.apache.ecs, diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkJRViewer.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkJRViewer.java index 5cca8ff1bd..5793692408 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkJRViewer.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkJRViewer.java @@ -3,24 +3,10 @@ package org.adempiere.webui.window; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; +import java.util.ArrayList; import java.util.logging.Level; import javax.activation.FileDataSource; -import javax.servlet.http.HttpServletRequest; - -import net.sf.jasperreports.engine.DefaultJasperReportsContext; -import net.sf.jasperreports.engine.JRException; -import net.sf.jasperreports.engine.JRExporterParameter; -import net.sf.jasperreports.engine.JasperPrint; -import net.sf.jasperreports.engine.JasperReport; -import net.sf.jasperreports.engine.export.JRCsvExporter; -import net.sf.jasperreports.engine.export.JRCsvExporterParameter; -import net.sf.jasperreports.engine.export.JRHtmlExporter; -import net.sf.jasperreports.engine.export.JRHtmlExporterParameter; -import net.sf.jasperreports.engine.export.JRPdfExporter; -import net.sf.jasperreports.engine.export.JRXlsExporter; -import net.sf.jasperreports.engine.export.JRXlsExporterParameter; -import net.sf.jasperreports.engine.util.LocalJasperReportsContext; import org.adempiere.exceptions.AdempiereException; import org.adempiere.webui.LayoutUtils; @@ -44,7 +30,6 @@ import org.compiere.util.Msg; import org.compiere.util.Util; import org.zkoss.util.media.AMedia; import org.zkoss.zk.ui.Component; -import org.zkoss.zk.ui.Executions; import org.zkoss.zk.ui.Page; import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.EventListener; @@ -59,13 +44,32 @@ import org.zkoss.zul.Separator; import org.zkoss.zul.Tab; import org.zkoss.zul.Toolbar; +import net.sf.jasperreports.engine.DefaultJasperReportsContext; +import net.sf.jasperreports.engine.JRException; +import net.sf.jasperreports.engine.JasperPrint; +import net.sf.jasperreports.engine.JasperReport; +import net.sf.jasperreports.engine.export.HtmlExporter; +import net.sf.jasperreports.engine.export.JRCsvExporter; +import net.sf.jasperreports.engine.export.JRPdfExporter; +import net.sf.jasperreports.engine.export.JRXlsExporter; +import net.sf.jasperreports.engine.util.LocalJasperReportsContext; +import net.sf.jasperreports.export.SimpleCsvExporterConfiguration; +import net.sf.jasperreports.export.SimpleExporterInput; +import net.sf.jasperreports.export.SimpleHtmlExporterOutput; +import net.sf.jasperreports.export.SimpleHtmlReportConfiguration; +import net.sf.jasperreports.export.SimpleOutputStreamExporterOutput; +import net.sf.jasperreports.export.SimpleWriterExporterOutput; +import net.sf.jasperreports.export.SimpleXlsReportConfiguration; + public class ZkJRViewer extends Window implements EventListener, ITabOnCloseHandler { /** - * + * */ private static final long serialVersionUID = -7047317766671393738L; private JasperPrint jasperPrint; + private java.util.List jasperPrintList; + private boolean isList; private Listbox previewType = new Listbox(); private Iframe iframe; private AMedia media; @@ -74,19 +78,31 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl private File attachment = null; /** Logger */ private static CLogger log = CLogger.getCLogger(ZkJRViewer.class); - + /** Window No */ private int m_WindowNo = -1; private long prevKeyEventTime = 0; private KeyEvent prevKeyEvent; private String m_title; // local title - embedded windows clear the title - + public ZkJRViewer(JasperPrint jasperPrint, String title) { super(); this.setTitle(title); m_title = title; this.jasperPrint = jasperPrint; + this.isList = false; + m_WindowNo = SessionManager.getAppDesktop().registerWindow(this); + setAttribute(IDesktop.WINDOWNO_ATTRIBUTE, m_WindowNo); + init(); + } + + public ZkJRViewer(java.util.List jasperPrintList, String title) { + super(); + this.setTitle(title); + m_title = title; + this.jasperPrintList = jasperPrintList; + this.isList = true; m_WindowNo = SessionManager.getAppDesktop().registerWindow(this); setAttribute(IDesktop.WINDOWNO_ATTRIBUTE, m_WindowNo); init(); @@ -123,11 +139,11 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl previewType.setMold("select"); attachment = null; // Added by Martin Augustine - Ntier software Services 09/10/2013 - if (isCanExport) { + if (isCanExport && !isList) { previewType.appendItem("PDF", "PDF"); previewType.appendItem("HTML", "HTML"); previewType.appendItem("Excel", "XLS"); - previewType.appendItem("CSV", "CSV"); + previewType.appendItem("CSV", "CSV"); previewType.appendItem("SSV", "SSV"); if ("PDF".equals(defaultType)) { previewType.setSelectedIndex(0); @@ -177,7 +193,7 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl layout.appendChild(north); north.appendChild(toolbar); ZKUpdateUtil.setVflex(north, "min"); - + Center center = new Center(); layout.appendChild(center); iframe = new Iframe(); @@ -192,12 +208,12 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl } catch (Exception e) { log.log(Level.SEVERE, e.getLocalizedMessage(), e); throw new AdempiereException("Failed to render report.", e); - } + } center.appendChild(iframe); this.setBorder("normal"); } - + private String makePrefix(String name) { StringBuilder prefix = new StringBuilder(); char[] nameArray = name.toCharArray(); @@ -206,7 +222,7 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl prefix.append(ch); } else { prefix.append("_"); - } + } } return prefix.toString(); } @@ -216,7 +232,7 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl */ public void actionPerformed (Event e) { - + if (e.getTarget() == previewType) cmd_render(); else if (e.getTarget() == bSendMail) // Added by Martin Augustine - Ntier software services 09/10/2013 @@ -225,7 +241,7 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl private void cmd_render() { try { - renderReport(); + renderReport(); } catch (Exception e) { throw new AdempiereException("Failed to render report", e); } @@ -253,7 +269,7 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl } // cmd_sendMail - public void onEvent(Event event) throws Exception { + public void onEvent(Event event) throws Exception { if (event.getName().equals(Events.ON_CLICK) || event.getName().equals(Events.ON_SELECT)) { actionPerformed(event); } else if (event.getName().equals(Events.ON_CTRL_KEY)) { @@ -291,15 +307,15 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl private void renderReport() throws Exception { String reportType; ClassLoader cl = Thread.currentThread().getContextClassLoader(); - try { + try { Thread.currentThread().setContextClassLoader(JasperReport.class.getClassLoader()); Listitem selected = previewType.getSelectedItem(); reportType=selected.getValue(); - if ( "PDF".equals( reportType ) ) + if ( "PDF".equals( reportType ) ) { attachment = getPDF(); media = new AMedia(m_title + ".pdf", "pdf", "application/pdf", attachment, true); - + } else if ("HTML".equals(reportType)) { String path = System.getProperty("java.io.tmpdir"); String prefix = makePrefix(jasperPrint.getName()); @@ -308,16 +324,19 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl log.log(Level.FINE, "Path="+path + " Prefix="+prefix); } File file = File.createTempFile(prefix, ".html", new File(path)); - - JRHtmlExporter exporter = new JRHtmlExporter(); - exporter.setParameter(JRExporterParameter.JASPER_PRINT,jasperPrint); - exporter.setParameter(JRExporterParameter.OUTPUT_FILE, file); - // Make images available for the HTML output - exporter.setParameter(JRHtmlExporterParameter.IS_OUTPUT_IMAGES_TO_DIR, Boolean.TRUE); - exporter.setParameter(JRHtmlExporterParameter.IMAGES_DIR_NAME, Executions.getCurrent().getDesktop().getSession().getWebApp().getRealPath("/images/report/")); - HttpServletRequest request = (HttpServletRequest)Executions.getCurrent().getNativeRequest(); - exporter.setParameter(JRHtmlExporterParameter.IMAGES_URI, request.getContextPath()+"/images/report/"); - exporter.exportReport(); + + HtmlExporter exporter = new HtmlExporter(); + SimpleHtmlReportConfiguration htmlConfig = new SimpleHtmlReportConfiguration(); + htmlConfig.setEmbedImage(true); + htmlConfig.setAccessibleHtml(true); + if (!isList){ + jasperPrintList = new ArrayList<>(); + jasperPrintList.add(jasperPrint); + } + exporter.setExporterInput(SimpleExporterInput.getInstance(jasperPrintList)); + exporter.setExporterOutput(new SimpleHtmlExporterOutput(file)); + exporter.setConfiguration(htmlConfig); + exporter.exportReport(); media = new AMedia(m_title, "html", "text/html", file, false); } else if ("XLS".equals(reportType)) { String path = System.getProperty("java.io.tmpdir"); @@ -326,17 +345,24 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl { log.log(Level.FINE, "Path="+path + " Prefix="+prefix); } - File file = File.createTempFile(prefix, ".xls", new File(path)); + File file = File.createTempFile(prefix, ".xls", new File(path)); FileOutputStream fos = new FileOutputStream(file); - + // coding For Excel: JRXlsExporter exporterXLS = new JRXlsExporter(); - exporterXLS.setParameter(JRXlsExporterParameter.JASPER_PRINT, jasperPrint); - exporterXLS.setParameter(JRXlsExporterParameter.OUTPUT_STREAM, fos); - exporterXLS.setParameter(JRXlsExporterParameter.IS_ONE_PAGE_PER_SHEET, Boolean.FALSE); - exporterXLS.exportReport(); - media = new AMedia(m_title + ".xls", "xls", "application/vnd.ms-excel", file, true); - + SimpleXlsReportConfiguration xlsConfig = new SimpleXlsReportConfiguration(); + xlsConfig.setOnePagePerSheet(false); + + if (!isList){ + jasperPrintList = new ArrayList<>(); + jasperPrintList.add(jasperPrint); + } + exporterXLS.setExporterInput(SimpleExporterInput.getInstance(jasperPrintList)); + exporterXLS.setExporterOutput(new SimpleOutputStreamExporterOutput(fos)); + exporterXLS.setConfiguration(xlsConfig); + exporterXLS.exportReport(); + media = new AMedia(m_title + ".xls", "xls", "application/vnd.ms-excel", file, true); + }else if ("CSV".equals(reportType)) { String path = System.getProperty("java.io.tmpdir"); String prefix = makePrefix(jasperPrint.getName()); @@ -347,11 +373,15 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl File file = File.createTempFile(prefix, ".csv", new File(path)); FileOutputStream fos = new FileOutputStream(file); JRCsvExporter exporter= new JRCsvExporter(); - exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint); - exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, fos); + if (!isList){ + jasperPrintList = new ArrayList<>(); + jasperPrintList.add(jasperPrint); + } + exporter.setExporterInput(SimpleExporterInput.getInstance(jasperPrintList)); + exporter.setExporterOutput(new SimpleWriterExporterOutput(fos)); exporter.exportReport(); - - media = new AMedia(m_title + ".csv", "csv", "application/csv", file, true); + + media = new AMedia(m_title + ".csv", "csv", "application/csv", file, true); }else if ("SSV".equals(reportType)) { String path = System.getProperty("java.io.tmpdir"); @@ -363,24 +393,36 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl File file = File.createTempFile(prefix, ".ssv", new File(path)); FileOutputStream fos = new FileOutputStream(file); JRCsvExporter exporter= new JRCsvExporter(); - exporter.setParameter(JRCsvExporterParameter.FIELD_DELIMITER, ";"); - exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint); - exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, fos); + SimpleCsvExporterConfiguration csvConfig = new SimpleCsvExporterConfiguration(); + csvConfig.setFieldDelimiter(";"); + if (!isList){ + jasperPrintList = new ArrayList<>(); + jasperPrintList.add(jasperPrint); + } + exporter.setExporterInput(SimpleExporterInput.getInstance(jasperPrintList)); + exporter.setExporterOutput(new SimpleWriterExporterOutput(fos)); + exporter.setConfiguration(csvConfig); exporter.exportReport(); - - media = new AMedia(m_title, "ssv", "application/ssv", file, true); + + media = new AMedia(m_title, "ssv", "application/ssv", file, true); } } finally { Thread.currentThread().setContextClassLoader(cl); } iframe.setSrc(null); - Events.echoEvent("onRenderReport", this, null); + Events.echoEvent("onRenderReport", this, null); } - + private File getPDF() throws IOException, JRException { String path = System.getProperty("java.io.tmpdir"); - String prefix = makePrefix(jasperPrint.getName()); + + String prefix = null; + if (isList) + prefix = makePrefix(jasperPrintList.get(0).getName())+"_List"; + else + prefix = makePrefix(jasperPrint.getName()); + if (log.isLoggable(Level.FINE)) { log.log(Level.FINE, "Path="+path + " Prefix="+prefix); @@ -389,8 +431,12 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl LocalJasperReportsContext context = new LocalJasperReportsContext(DefaultJasperReportsContext.getInstance()); context.setClassLoader(JRPdfExporter.class.getClassLoader()); JRPdfExporter exporter = new JRPdfExporter(context); - exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint); - exporter.setParameter(JRExporterParameter.OUTPUT_FILE_NAME, file.getAbsolutePath()); + if (!isList){ + jasperPrintList = new ArrayList<>(); + jasperPrintList.add(jasperPrint); + } + exporter.setExporterInput(SimpleExporterInput.getInstance(jasperPrintList)); + exporter.setExporterOutput(new SimpleOutputStreamExporterOutput(file)); exporter.exportReport(); return file; } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkJRViewerProvider.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkJRViewerProvider.java index 42ffaaa0f0..cbc685323e 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkJRViewerProvider.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkJRViewerProvider.java @@ -3,6 +3,8 @@ package org.adempiere.webui.window; import net.sf.jasperreports.engine.JRException; import net.sf.jasperreports.engine.JasperPrint; +import java.util.List; + import org.adempiere.report.jasper.JRViewerProvider; import org.adempiere.webui.apps.AEnv; import org.adempiere.webui.component.Window; @@ -14,11 +16,28 @@ public class ZkJRViewerProvider implements JRViewerProvider { public void openViewer(final JasperPrint jasperPrint, final String title) throws JRException { Runnable runnable = new Runnable() { - + @Override public void run() { Window viewer = new ZkJRViewer(jasperPrint, title); - + + viewer.setAttribute(Window.MODE_KEY, Window.MODE_EMBEDDED); + viewer.setAttribute(Window.INSERT_POSITION_KEY, Window.INSERT_NEXT); + viewer.setAttribute(WindowContainer.DEFER_SET_SELECTED_TAB, Boolean.TRUE); + SessionManager.getAppDesktop().showWindow(viewer); + } + }; + AEnv.executeAsyncDesktopTask(runnable); + } + + public void openViewer(final List jasperPrintList, final String title) + throws JRException { + Runnable runnable = new Runnable() { + + @Override + public void run() { + Window viewer = new ZkJRViewer(jasperPrintList, title); + viewer.setAttribute(Window.MODE_KEY, Window.MODE_EMBEDDED); viewer.setAttribute(Window.INSERT_POSITION_KEY, Window.INSERT_NEXT); viewer.setAttribute(WindowContainer.DEFER_SET_SELECTED_TAB, Boolean.TRUE); From 4e1f52c9cad901be067ab1a3ddcc40b1be562b5e Mon Sep 17 00:00:00 2001 From: Carlos Ruiz Date: Fri, 13 Oct 2017 20:50:46 +0200 Subject: [PATCH 2/7] IDEMPIERE-3520 Ability to merge several jasper reports in one run --- .../report/jasper/JRViewerProviderList.java | 11 +++ .../report/jasper/ReportStarter.java | 97 +++++++++++-------- .../OSGI-INF/jrviewerprovider.xml | 1 + .../adempiere/webui/window/ZkJRViewer.java | 26 ++++- .../webui/window/ZkJRViewerProvider.java | 9 +- 5 files changed, 93 insertions(+), 51 deletions(-) create mode 100644 org.adempiere.report.jasper/src/org/adempiere/report/jasper/JRViewerProviderList.java diff --git a/org.adempiere.report.jasper/src/org/adempiere/report/jasper/JRViewerProviderList.java b/org.adempiere.report.jasper/src/org/adempiere/report/jasper/JRViewerProviderList.java new file mode 100644 index 0000000000..5718a81331 --- /dev/null +++ b/org.adempiere.report.jasper/src/org/adempiere/report/jasper/JRViewerProviderList.java @@ -0,0 +1,11 @@ +package org.adempiere.report.jasper; + +import java.util.List; + +import net.sf.jasperreports.engine.JRException; +import net.sf.jasperreports.engine.JasperPrint; + +public interface JRViewerProviderList { + + public void openViewer(List jasperPrintList, String title) throws JRException; +} diff --git a/org.adempiere.report.jasper/src/org/adempiere/report/jasper/ReportStarter.java b/org.adempiere.report.jasper/src/org/adempiere/report/jasper/ReportStarter.java index 670166f218..4c4de4e595 100644 --- a/org.adempiere.report.jasper/src/org/adempiere/report/jasper/ReportStarter.java +++ b/org.adempiere.report.jasper/src/org/adempiere/report/jasper/ReportStarter.java @@ -35,6 +35,7 @@ import java.sql.SQLException; import java.sql.Timestamp; import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Properties; @@ -46,6 +47,34 @@ import javax.print.attribute.PrintRequestAttributeSet; import javax.print.attribute.standard.Copies; import javax.print.attribute.standard.JobName; +import org.adempiere.base.Service; +import org.adempiere.exceptions.AdempiereException; +import org.adempiere.exceptions.DBException; +import org.adempiere.util.IProcessUI; +import org.compiere.model.MAttachment; +import org.compiere.model.MAttachmentEntry; +import org.compiere.model.MProcess; +import org.compiere.model.MQuery; +import org.compiere.model.MSysConfig; +import org.compiere.model.MTable; +import org.compiere.model.PrintInfo; +import org.compiere.model.X_AD_PInstance_Para; +import org.compiere.print.MPrintFormat; +import org.compiere.print.PrintUtil; +import org.compiere.print.ServerReportCtl; +import org.compiere.process.ClientProcess; +import org.compiere.process.ProcessCall; +import org.compiere.process.ProcessInfo; +import org.compiere.process.ProcessInfoParameter; +import org.compiere.util.CLogger; +import org.compiere.util.DB; +import org.compiere.util.Env; +import org.compiere.util.Ini; +import org.compiere.util.Language; +import org.compiere.util.Trx; +import org.compiere.util.Util; +import org.compiere.utils.DigestOfFile; + import net.sf.jasperreports.engine.DefaultJasperReportsContext; import net.sf.jasperreports.engine.JRException; import net.sf.jasperreports.engine.JRParameter; @@ -87,34 +116,6 @@ import net.sf.jasperreports.export.SimpleWriterExporterOutput; import net.sf.jasperreports.export.SimpleXlsExporterConfiguration; import net.sf.jasperreports.export.SimpleXmlExporterOutput; -import org.adempiere.base.Service; -import org.adempiere.exceptions.AdempiereException; -import org.adempiere.exceptions.DBException; -import org.adempiere.util.IProcessUI; -import org.compiere.model.MAttachment; -import org.compiere.model.MAttachmentEntry; -import org.compiere.model.MProcess; -import org.compiere.model.MQuery; -import org.compiere.model.MSysConfig; -import org.compiere.model.MTable; -import org.compiere.model.PrintInfo; -import org.compiere.model.X_AD_PInstance_Para; -import org.compiere.print.MPrintFormat; -import org.compiere.print.PrintUtil; -import org.compiere.print.ServerReportCtl; -import org.compiere.process.ClientProcess; -import org.compiere.process.ProcessCall; -import org.compiere.process.ProcessInfo; -import org.compiere.process.ProcessInfoParameter; -import org.compiere.util.CLogger; -import org.compiere.util.DB; -import org.compiere.util.Env; -import org.compiere.util.Ini; -import org.compiere.util.Language; -import org.compiere.util.Trx; -import org.compiere.util.Util; -import org.compiere.utils.DigestOfFile; - /** * @author rlemeill * Originally coming from an application note from compiere.co.uk @@ -185,8 +186,7 @@ public class ReportStarter implements ProcessCall, ClientProcess log.warning("404 not found: Report cannot be found on server "+ e.getMessage()); return null; } catch (IOException e) { - log.severe("I/O error when trying to download (sub)report from server "+ e.getMessage()); - return null; + throw new AdempiereException("I/O error when trying to download (sub)report from server "+ e.getLocalizedMessage()); } } @@ -285,8 +285,7 @@ public class ReportStarter implements ProcessCall, ClientProcess } catch (Exception e) { - log.severe("Unknown exception: "+ e.getMessage()); - return null; + throw new AdempiereException("Unknown exception: "+ e.getLocalizedMessage()); } return reportFile; } @@ -311,8 +310,7 @@ public class ReportStarter implements ProcessCall, ClientProcess String hash = new String(baos.toByteArray()); return hash; } catch (IOException e) { - log.severe("I/O error when trying to download (sub)report from server "+ e.getMessage()); - return null; + throw new AdempiereException("I/O error when trying to download (sub)report from server "+ e.getLocalizedMessage()); } } @@ -379,7 +377,12 @@ public class ReportStarter implements ProcessCall, ClientProcess return false; } - String reportPath = reportData.getReportFilePath(); + List jasperPrintList = new ArrayList(); + String reportFilePath = reportData.getReportFilePath(); + String[] reportPathList = reportFilePath.split(";"); + for (int idx = 0; idx < reportPathList.length; idx++) { + + String reportPath = reportPathList[idx]; if (Util.isEmpty(reportPath, true)) { reportResult(AD_PInstance_ID, "Can not find report", trxName); @@ -702,9 +705,20 @@ public class ReportStarter implements ProcessCall, ClientProcess } } } else { - if (log.isLoggable(Level.INFO)) log.info( "ReportStarter.startProcess run report -"+jasperPrint.getName()); - JRViewerProvider viewerLauncher = Service.locator().locate(JRViewerProvider.class).getService(); - viewerLauncher.openViewer(jasperPrint, pi.getTitle()); + if (reportPathList.length == 1) { + if (log.isLoggable(Level.INFO)) log.info( "ReportStarter.startProcess run report -"+jasperPrint.getName()); + JRViewerProvider viewerLauncher = Service.locator().locate(JRViewerProvider.class).getService(); + viewerLauncher.openViewer(jasperPrint, pi.getTitle()); + } else { + jasperPrintList.add(jasperPrint); + if (idx+1 == reportPathList.length) { + JRViewerProviderList viewerLauncher = Service.locator().locate(JRViewerProviderList.class).getService(); + if (viewerLauncher == null) { + throw new AdempiereException("Can not find a viewer provider for multiple jaspers"); + } + viewerLauncher.openViewer(jasperPrintList, pi.getTitle()); + } + } } } else @@ -786,7 +800,7 @@ public class ReportStarter implements ProcessCall, ClientProcess } } } catch (JRException e) { - log.severe("ReportStarter.startProcess: Can not run report - "+ e.getMessage()); + throw new AdempiereException(e.getLocalizedMessage() + (e.getCause() != null ? " -> " + e.getCause().getLocalizedMessage() : "")); } finally { if (conn != null) { try { @@ -797,6 +811,8 @@ public class ReportStarter implements ProcessCall, ClientProcess } } + } // for reportPathList + if (onrows != null && onrows instanceof Integer) { nrows = (Integer) onrows; processInfo.setRowCount(nrows); @@ -1275,7 +1291,6 @@ public class ReportStarter implements ProcessCall, ClientProcess } catch (SQLException e) { -// log.severe("Execption; sql = "+sql+"; e.getMessage() = " +e.getMessage()); throw new DBException(e, sql); } finally @@ -1373,8 +1388,6 @@ public class ReportStarter implements ProcessCall, ClientProcess catch (SQLException e) { throw new DBException(e, sql); -// log.severe("sql = "+sql+"; e.getMessage() = "+ e.getMessage()); -// return null; } finally { diff --git a/org.adempiere.ui.zk/OSGI-INF/jrviewerprovider.xml b/org.adempiere.ui.zk/OSGI-INF/jrviewerprovider.xml index 802836a337..267f7c129a 100644 --- a/org.adempiere.ui.zk/OSGI-INF/jrviewerprovider.xml +++ b/org.adempiere.ui.zk/OSGI-INF/jrviewerprovider.xml @@ -3,5 +3,6 @@ + diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkJRViewer.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkJRViewer.java index 5793692408..e7f6876717 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkJRViewer.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkJRViewer.java @@ -139,7 +139,7 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl previewType.setMold("select"); attachment = null; // Added by Martin Augustine - Ntier software Services 09/10/2013 - if (isCanExport && !isList) { + if (isCanExport) { previewType.appendItem("PDF", "PDF"); previewType.appendItem("HTML", "HTML"); previewType.appendItem("Excel", "XLS"); @@ -318,7 +318,11 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl } else if ("HTML".equals(reportType)) { String path = System.getProperty("java.io.tmpdir"); - String prefix = makePrefix(jasperPrint.getName()); + String prefix = null; + if (isList) + prefix = makePrefix(jasperPrintList.get(0).getName())+"_List"; + else + prefix = makePrefix(jasperPrint.getName()); if (log.isLoggable(Level.FINE)) { log.log(Level.FINE, "Path="+path + " Prefix="+prefix); @@ -340,7 +344,11 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl media = new AMedia(m_title, "html", "text/html", file, false); } else if ("XLS".equals(reportType)) { String path = System.getProperty("java.io.tmpdir"); - String prefix = makePrefix(jasperPrint.getName()); + String prefix = null; + if (isList) + prefix = makePrefix(jasperPrintList.get(0).getName())+"_List"; + else + prefix = makePrefix(jasperPrint.getName()); if (log.isLoggable(Level.FINE)) { log.log(Level.FINE, "Path="+path + " Prefix="+prefix); @@ -365,7 +373,11 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl }else if ("CSV".equals(reportType)) { String path = System.getProperty("java.io.tmpdir"); - String prefix = makePrefix(jasperPrint.getName()); + String prefix = null; + if (isList) + prefix = makePrefix(jasperPrintList.get(0).getName())+"_List"; + else + prefix = makePrefix(jasperPrint.getName()); if (log.isLoggable(Level.FINE)) { log.log(Level.FINE, "Path="+path + " Prefix="+prefix); @@ -385,7 +397,11 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl }else if ("SSV".equals(reportType)) { String path = System.getProperty("java.io.tmpdir"); - String prefix = makePrefix(jasperPrint.getName()); + String prefix = null; + if (isList) + prefix = makePrefix(jasperPrintList.get(0).getName())+"_List"; + else + prefix = makePrefix(jasperPrint.getName()); if (log.isLoggable(Level.FINE)) { log.log(Level.FINE, "Path="+path + " Prefix="+prefix); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkJRViewerProvider.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkJRViewerProvider.java index cbc685323e..61d66795e2 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkJRViewerProvider.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkJRViewerProvider.java @@ -1,17 +1,18 @@ package org.adempiere.webui.window; -import net.sf.jasperreports.engine.JRException; -import net.sf.jasperreports.engine.JasperPrint; - import java.util.List; import org.adempiere.report.jasper.JRViewerProvider; +import org.adempiere.report.jasper.JRViewerProviderList; import org.adempiere.webui.apps.AEnv; import org.adempiere.webui.component.Window; import org.adempiere.webui.part.WindowContainer; import org.adempiere.webui.session.SessionManager; -public class ZkJRViewerProvider implements JRViewerProvider { +import net.sf.jasperreports.engine.JRException; +import net.sf.jasperreports.engine.JasperPrint; + +public class ZkJRViewerProvider implements JRViewerProvider, JRViewerProviderList { public void openViewer(final JasperPrint jasperPrint, final String title) throws JRException { From 1616e7a95b3fee93240842f5e9b5bc8a8194a021 Mon Sep 17 00:00:00 2001 From: Carlos Ruiz Date: Tue, 17 Oct 2017 18:29:34 +0200 Subject: [PATCH 3/7] IDEMPIERE-1546 There is no OSGi interface for a PaymentExport / thanks to Markus Bozem --- .../src/org/adempiere/base/Core.java | 35 ++++ .../base/DefaultPaymentExporterFactory.java | 58 +++++++ .../base/IPaymentExporterFactory.java | 29 ++++ .../compiere/model/MPaySelectionCheck.java | 152 +++++++++++++----- .../compiere/util/GenericPaymentExport.java | 41 ++++- .../src/org/compiere/util/PaymentExport.java | 73 ++++++++- .../src/org/compiere/apps/form/VPayPrint.java | 92 ++++++++--- .../adempiere/webui/apps/form/WPayPrint.java | 100 +++++++++--- .../src/org/compiere/apps/form/PayPrint.java | 73 ++++++++- 9 files changed, 555 insertions(+), 98 deletions(-) create mode 100644 org.adempiere.base/src/org/adempiere/base/DefaultPaymentExporterFactory.java create mode 100644 org.adempiere.base/src/org/adempiere/base/IPaymentExporterFactory.java diff --git a/org.adempiere.base/src/org/adempiere/base/Core.java b/org.adempiere.base/src/org/adempiere/base/Core.java index c84d24890d..59c5a90c8e 100644 --- a/org.adempiere.base/src/org/adempiere/base/Core.java +++ b/org.adempiere.base/src/org/adempiere/base/Core.java @@ -45,6 +45,7 @@ import org.compiere.model.PaymentProcessor; import org.compiere.model.StandardTaxProvider; import org.compiere.process.ProcessCall; import org.compiere.util.CLogger; +import org.compiere.util.PaymentExport; import org.compiere.util.ReplenishInterface; import org.osgi.framework.FrameworkUtil; @@ -415,4 +416,38 @@ public class Core { return engine; } + + /** + * get PaymentExporter instance + * + * @param className + * @return instance of the PaymentExporterInterface or null + */ + public static PaymentExport getPaymentExporter (String className){ + if (className == null || className.length() == 0) { + s_log.log(Level.SEVERE, "No PaymentExporter class name"); + return null; + } + + PaymentExport myPaymentExporter = null; + + List factoryList = + Service.locator().list(IPaymentExporterFactory.class).getServices(); + if (factoryList != null) { + for(IPaymentExporterFactory factory : factoryList) { + PaymentExport exporter = factory.newPaymentExporterInstance(className); + if (exporter != null) { + myPaymentExporter = exporter; + break; + } + } + } + + if (myPaymentExporter == null) { + s_log.log(Level.CONFIG, className + " not found in service/extension registry and classpath"); + return null; + } + + return myPaymentExporter; + } } diff --git a/org.adempiere.base/src/org/adempiere/base/DefaultPaymentExporterFactory.java b/org.adempiere.base/src/org/adempiere/base/DefaultPaymentExporterFactory.java new file mode 100644 index 0000000000..797a98a602 --- /dev/null +++ b/org.adempiere.base/src/org/adempiere/base/DefaultPaymentExporterFactory.java @@ -0,0 +1,58 @@ +/****************************************************************************** + * Product: iDempiere Business Suite ERP/CRM/SCM * + * Copyright (C) 2017 Markus Bozem * + * This program is free software; you can redistribute it and/or modify it * + * under the terms version 2 of the GNU General Public License as published * + * by the Free Software Foundation. This program is distributed in the hope * + * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied * + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * See the GNU General Public License for more details. * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * * + *****************************************************************************/ +package org.adempiere.base; + +import java.util.logging.Level; + +import org.adempiere.base.equinox.EquinoxExtensionLocator; +import org.compiere.util.CLogger; +import org.compiere.util.PaymentExport; + +/** + * @author mbozem + * + */ +public class DefaultPaymentExporterFactory implements IPaymentExporterFactory { + + private final static CLogger s_log = CLogger.getCLogger(DefaultPaymentExporterFactory.class); + + /** + * default constructor + */ + public DefaultPaymentExporterFactory() { + } + + @Override + public PaymentExport newPaymentExporterInstance(String className) { + PaymentExport myExporter = null; + myExporter = EquinoxExtensionLocator.instance().locate(PaymentExport.class, className, null).getExtension(); + if (myExporter == null) { + //fall back to dynamic java class loadup + try { + Class peClass = Class.forName(className); + if (peClass != null) + myExporter = (PaymentExport)peClass.newInstance(); + } catch (Error e1) { // NoClassDefFound + s_log.log(Level.SEVERE, className + " - Error=" + e1.getMessage()); + return null; + } catch (Exception e2) { + s_log.log(Level.SEVERE, className, e2); + return null; + } + } + + return myExporter; + } + +} diff --git a/org.adempiere.base/src/org/adempiere/base/IPaymentExporterFactory.java b/org.adempiere.base/src/org/adempiere/base/IPaymentExporterFactory.java new file mode 100644 index 0000000000..3397bf572a --- /dev/null +++ b/org.adempiere.base/src/org/adempiere/base/IPaymentExporterFactory.java @@ -0,0 +1,29 @@ +/****************************************************************************** + * Product: iDempiere Business Suite ERP/CRM/SCM * + * Copyright (C) 2017 Markus Bozem * + * This program is free software; you can redistribute it and/or modify it * + * under the terms version 2 of the GNU General Public License as published * + * by the Free Software Foundation. This program is distributed in the hope * + * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied * + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * See the GNU General Public License for more details. * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * * + *****************************************************************************/ +package org.adempiere.base; + +import org.compiere.util.PaymentExport; + +/** + * PaymentExporter factory interface. + * @author mbozem + */ +public interface IPaymentExporterFactory { + + /** + * @param className + * @return payment exporter instance + */ + public PaymentExport newPaymentExporterInstance(String className); +} diff --git a/org.adempiere.base/src/org/compiere/model/MPaySelectionCheck.java b/org.adempiere.base/src/org/compiere/model/MPaySelectionCheck.java index 7e4f67739b..5f4970e443 100644 --- a/org.adempiere.base/src/org/compiere/model/MPaySelectionCheck.java +++ b/org.adempiere.base/src/org/compiere/model/MPaySelectionCheck.java @@ -20,11 +20,14 @@ import java.math.BigDecimal; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import java.sql.Timestamp; import java.util.ArrayList; +import java.util.Date; import java.util.Properties; import java.util.logging.Level; import org.adempiere.exceptions.AdempiereException; +import org.compiere.acct.Doc; import org.compiere.process.DocAction; import org.compiere.util.CLogger; import org.compiere.util.DB; @@ -43,7 +46,7 @@ public class MPaySelectionCheck extends X_C_PaySelectionCheck /** * */ - private static final long serialVersionUID = -5752888482207479355L; + private static final long serialVersionUID = 2130445794890189020L; /** * Get Check for Payment @@ -385,60 +388,127 @@ public class MPaySelectionCheck extends X_C_PaySelectionCheck * Create Payments the first time * @param checks checks * @param batch batch + * @param createDeposit create deposit batch * @return last Document number or 0 if nothing printed */ - public static int confirmPrint (MPaySelectionCheck[] checks, MPaymentBatch batch) + public static int confirmPrint (MPaySelectionCheck[] checks, MPaymentBatch batch, boolean createDepositBatch) { boolean localTrx = false; String trxName = null; - if (checks.length > 0) - trxName = checks[0].get_TrxName(); - Trx trx = null; - if (trxName == null) { - localTrx = true; - trxName = Trx.createTrxName("ConfirmPrintMulti"); - trx = Trx.get(trxName, true); - trx.setDisplayName(MPaySelectionCheck.class.getName()+"_confirmPrints"); - } int lastDocumentNo = 0; - try { - for (int i = 0; i < checks.length; i++) + + if (checks.length > 0) + { + trxName = checks[0].get_TrxName(); + Properties ctx = checks[0].getCtx(); + int c_BankAccount_ID = checks[0].getC_PaySelection().getC_BankAccount_ID() ; + String paymentRule = checks[0].getPaymentRule() ; + Boolean isDebit ; + if (MInvoice.PAYMENTRULE_DirectDeposit.compareTo(paymentRule) == 0 + || MInvoice.PAYMENTRULE_Check.compareTo(paymentRule) == 0 + || MInvoice.PAYMENTRULE_OnCredit.compareTo(paymentRule) == 0) { - MPaySelectionCheck check = checks[i]; - if (localTrx) - check.set_TrxName(trxName); - confirmPrint(check, batch); - - // Get Check Document No - try - { - int no = Integer.parseInt(check.getDocumentNo()); - if (lastDocumentNo < no) - lastDocumentNo = no; - } - catch (NumberFormatException ex) - { - s_log.log(Level.SEVERE, "DocumentNo=" + check.getDocumentNo(), ex); - } - } // all checks - } catch (Exception e) { - if (localTrx && trx != null) { - trx.rollback(); - trx.close(); - trx = null; + isDebit = false ; } - throw new AdempiereException(e); - } finally { - if (localTrx && trx != null) { - trx.commit(); - trx.close(); + else if (MInvoice.PAYMENTRULE_DirectDebit.compareTo(paymentRule) == 0) + { + isDebit = true ; + } + else + { + isDebit = false ; + createDepositBatch = false ; + } + Trx trx = null; + if (trxName == null) { + localTrx = true; + trxName = Trx.createTrxName("ConfirmPrintMulti"); + trx = Trx.get(trxName, true); + } + + try { + MDepositBatch depositBatch = null; + if (createDepositBatch) + { + depositBatch = new MDepositBatch(ctx, 0, trxName) ; + depositBatch.setC_BankAccount_ID(c_BankAccount_ID); + if (isDebit) + { + depositBatch.setC_DocType_ID(MDocType.getDocType(Doc.DOCTYPE_ARReceipt)); + } + else + { + depositBatch.setC_DocType_ID(MDocType.getDocType(Doc.DOCTYPE_APPayment)); + } + depositBatch.setDateDeposit(new Timestamp((new Date()).getTime())); + depositBatch.setDateDoc(new Timestamp((new Date()).getTime())); + depositBatch.saveEx(); + } + + for (int i = 0; i < checks.length; i++) + { + MPaySelectionCheck check = checks[i]; + if (localTrx) + check.set_TrxName(trxName); + confirmPrint(check, batch); + if (createDepositBatch) + { + MDepositBatchLine depositBatchLine = new MDepositBatchLine(depositBatch) ; + depositBatchLine.setC_Payment_ID(check.getC_Payment_ID()); + depositBatchLine.setProcessed(true); + depositBatchLine.saveEx(); + } + // Get Check Document No + try + { + int no = Integer.parseInt(check.getDocumentNo()); + if (lastDocumentNo < no) + lastDocumentNo = no; + } + catch (NumberFormatException ex) + { + s_log.log(Level.SEVERE, "DocumentNo=" + check.getDocumentNo(), ex); + } + } // all checks + + if (createDepositBatch) + { + + depositBatch.setProcessed(true); + depositBatch.saveEx(); + } + + } catch (Exception e) { + if (localTrx && trx != null) { + trx.rollback(); + trx.close(); + trx = null; + } + throw new AdempiereException(e); + } finally { + if (localTrx && trx != null) { + trx.commit(); + trx.close(); + } } } - if (s_log.isLoggable(Level.FINE)) s_log.fine("Last Document No = " + lastDocumentNo); return lastDocumentNo; } // confirmPrint + /************************************************************************** + * Confirm Print. + * Create Payments the first time + * @param checks checks + * @param batch batch + * @return last Document number or 0 if nothing printed + */ + + public static int confirmPrint (MPaySelectionCheck[] checks, MPaymentBatch batch) + { + return confirmPrint (checks,batch,false) ; + } // confirmPrint + /** Logger */ static private CLogger s_log = CLogger.getCLogger (MPaySelectionCheck.class); diff --git a/org.adempiere.base/src/org/compiere/util/GenericPaymentExport.java b/org.adempiere.base/src/org/compiere/util/GenericPaymentExport.java index ca0cdef7b6..dc986342c9 100644 --- a/org.adempiere.base/src/org/compiere/util/GenericPaymentExport.java +++ b/org.adempiere.base/src/org/compiere/util/GenericPaymentExport.java @@ -21,6 +21,7 @@ import java.io.FileWriter; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import java.text.SimpleDateFormat; import java.util.logging.Level; import org.compiere.model.MCurrency; @@ -67,11 +68,13 @@ public class GenericPaymentExport implements PaymentExport /************************************************************************** * Export to File * @param checks array of checks + * @param depositBatch book the payments as single position + * @param paymentRule selected payment rule * @param file file to export checks * @return number of lines */ - public int exportToFile (MPaySelectionCheck[] checks, File file, StringBuffer err) - { + public int exportToFile(MPaySelectionCheck[] checks, boolean depositBatch, String paymentRule, File file, + StringBuffer err) { if (checks == null || checks.length == 0) return 0; // Must be a file @@ -115,6 +118,7 @@ public class GenericPaymentExport implements PaymentExport .append(x).append("PayDate").append(x).append(",") .append(x).append("Currency").append(x).append(",") .append(x).append("PayAmount").append(x).append(",") + .append(x).append("DepositBatch").append(x).append(",") .append(x).append("Comment").append(x) .append(Env.NL); fw.write(line.toString()); @@ -154,6 +158,7 @@ public class GenericPaymentExport implements PaymentExport .append(mpp.getParent().getPayDate()).append(",") // PayDate .append(x).append(MCurrency.getISO_Code(Env.getCtx(), mpp.getParent().getC_Currency_ID())).append(x).append(",") // Currency .append(mpp.getPayAmt()).append(",") // PayAmount + .append(x).append(depositBatch).append(x).append(",") .append(x).append(comment.toString()).append(x) // Comment .append(Env.NL); fw.write(line.toString()); @@ -249,5 +254,35 @@ public class GenericPaymentExport implements PaymentExport return bp; } // getBPartnerInfo + @Override + public String getFilenamePrefix() { + String creationDate = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(System.currentTimeMillis()) ; + return "payments-" + creationDate ; + } + + @Override + public String getFilenameSuffix() { + return ".csv"; + } + + @Override + public String getContentType() { + return "text/csv"; + } + + @Override + public boolean supportsDepositBatch() { + return true; + } + + @Override + public boolean supportsSeparateBooking() { + return true; + } + + @Override + public boolean getDefaultDepositBatch() { + return false; + } -} // PaymentExport +} // PaymentExporterInterface diff --git a/org.adempiere.base/src/org/compiere/util/PaymentExport.java b/org.adempiere.base/src/org/compiere/util/PaymentExport.java index 85500b465a..0b516ccde2 100644 --- a/org.adempiere.base/src/org/compiere/util/PaymentExport.java +++ b/org.adempiere.base/src/org/compiere/util/PaymentExport.java @@ -24,6 +24,10 @@ import org.compiere.model.MPaySelectionCheck; * Custom Payment Export Interface * * @author Carlos Ruiz - GlobalQSS + * + * Contributors: + * Markus Bozem - IDEMPIERE-1546 / IDEMPIERE-3286 + * * @version PaymentExport.java */ public interface PaymentExport @@ -34,7 +38,74 @@ public interface PaymentExport * @param checks array of checks * @param file file to export checks * @return number of lines + * + * This method is preserved for backward compatibility (old non-OSGi way via fragment), + * new interfaces can leave this method unimplemented and must implement the other methods */ - public int exportToFile (MPaySelectionCheck[] checks, File file, StringBuffer err); + public default int exportToFile (MPaySelectionCheck[] checks, File file, StringBuffer err) { + return exportToFile (checks, false, (String)null, file, err); + } + + /************************************************************************** + * Export to file + * @param checks array of checks + * @param depositBatch create deposit batch + * @param file file to export checks + * @return number of lines + */ + public default int exportToFile (MPaySelectionCheck[] checks, boolean depositBatch, String paymentRule, File file, StringBuffer err) { + return exportToFile (checks, file, err); + } + + /** + * Get the filename prefix from plugin + * e.g. "SEPA-Credit-Transfer-" + * @return prefix for filename + */ + public default String getFilenamePrefix() { + return "paymentExport"; + } + + /** + * Get the filename suffix from plugin + * e.g. ".xml" + * @return suffix for filename + */ + public default String getFilenameSuffix() { + return ".txt"; + } + + /** + * Get the content type from plugin + * e.g. "text/xml" or "text/csv" + * @return content type delivered to browser + */ + public default String getContentType() { + return "text/plain"; + } + + /** + * Plugin supports deposit batch + * @return true if supported + */ + public default boolean supportsDepositBatch() { + return false; + } + + /** + * Plugin supports booking payments separate on bank statement (no deposit batch) + * @return true if supported + */ + public default boolean supportsSeparateBooking() { + return false; + } + + /** + * Default if supportsDepositBatch is true and supportsSeparateBooking is true + * @return true if deposit batch should be selected on default, false if deposit batch should not be selected + */ + public default boolean getDefaultDepositBatch() { + return false; + } } // PaymentExport diff --git a/org.adempiere.ui.swing/src/org/compiere/apps/form/VPayPrint.java b/org.adempiere.ui.swing/src/org/compiere/apps/form/VPayPrint.java index 07fd91d750..1b506efcd2 100644 --- a/org.adempiere.ui.swing/src/org/compiere/apps/form/VPayPrint.java +++ b/org.adempiere.ui.swing/src/org/compiere/apps/form/VPayPrint.java @@ -46,6 +46,7 @@ import static org.compiere.model.SystemIDs.*; import org.compiere.plaf.CompiereColor; import org.compiere.print.ReportCtl; import org.compiere.print.ReportEngine; +import org.compiere.swing.CCheckBox; import org.compiere.swing.CComboBox; import org.compiere.swing.CLabel; import org.compiere.swing.CPanel; @@ -54,7 +55,6 @@ import org.compiere.util.DisplayType; import org.compiere.util.Env; import org.compiere.util.Ini; import org.compiere.util.Msg; -import org.compiere.util.PaymentExport; import org.compiere.util.ValueNamePair; /** @@ -65,6 +65,7 @@ import org.compiere.util.ValueNamePair; * * Contributors: * Carlos Ruiz - GlobalQSS - FR 3132033 - Make payment export class configurable per bank + * Markus Bozem: IDEMPIERE-1546 / IDEMPIERE-3286 */ public class VPayPrint extends PayPrint implements FormPanel, ActionListener, VetoableChangeListener { @@ -120,7 +121,10 @@ public class VPayPrint extends PayPrint implements FormPanel, ActionListener, Ve private VNumber fBalance = new VNumber(); private CLabel lCurrency = new CLabel(); private CLabel fCurrency = new CLabel(); - + private CLabel lDepositBatch = new CLabel(); + private CCheckBox fDepositBatch = new CCheckBox(); + private CLabel lSumPayments = new CLabel(); + private VNumber fSumPayments = new VNumber(); /** * Static Init * @throws Exception @@ -133,6 +137,8 @@ public class VPayPrint extends PayPrint implements FormPanel, ActionListener, Ve southLayout.setAlignment(FlowLayout.RIGHT); centerPanel.setLayout(centerLayout); // + bPrint.setEnabled(false); + bExport.setEnabled(false); bPrint.addActionListener(this); bExport.addActionListener(this); bCancel.addActionListener(this); @@ -156,6 +162,10 @@ public class VPayPrint extends PayPrint implements FormPanel, ActionListener, Ve fBalance.setReadWrite(false); fBalance.setDisplayType(DisplayType.Amount); lCurrency.setText(Msg.translate(Env.getCtx(), "C_Currency_ID")); + lDepositBatch.setText(Msg.translate(Env.getCtx(), "C_DepositBatch_ID")); + lSumPayments.setText(Msg.getMsg(Env.getCtx(), "Sum")); + fSumPayments.setReadWrite(false); + fSumPayments.setDisplayType(DisplayType.Amount); // southPanel.add(bCancel, null); southPanel.add(bExport, null); @@ -190,6 +200,15 @@ public class VPayPrint extends PayPrint implements FormPanel, ActionListener, Ve ,GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(0, 12, 12, 5), 0, 0)); centerPanel.add(fCurrency, new GridBagConstraints(3, 2, 1, 1, 0.0, 0.0 ,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 12, 12), 0, 0)); + + centerPanel.add(lDepositBatch, new GridBagConstraints(0, 4, 1, 1, 0.0, 0.0 + ,GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(0, 12, 5, 5), 0, 0)); + centerPanel.add(fDepositBatch, new GridBagConstraints(1, 4, 1, 1, 0.0, 0.0 + ,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 5, 12), 0, 0)); + centerPanel.add(lSumPayments, new GridBagConstraints(2, 4, 1, 1, 0.0, 0.0 + ,GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(0, 12, 5, 5), 0, 0)); + centerPanel.add(fSumPayments, new GridBagConstraints(3, 4, 1, 1, 0.0, 0.0 + ,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 5, 12), 0, 0)); } // VPayPrint /** @@ -311,6 +330,9 @@ public class VPayPrint extends PayPrint implements FormPanel, ActionListener, Ve if(noPayments != null) fNoPayments.setText(noPayments); + if(sumPayments != null) + fSumPayments.setValue(sumPayments); + bProcess.setEnabled(PaymentRule.equals("T")); if(documentNo != null) @@ -318,9 +340,44 @@ public class VPayPrint extends PayPrint implements FormPanel, ActionListener, Ve if(msg != null && msg.length() > 0) ADialog.error(m_WindowNo, panel, msg); + + getPluginFeatures(); } // loadPaymentRuleInfo - + protected void getPluginFeatures() + { + if (m_C_PaySelection_ID!=0) + { + if (loadPaymentExportClass (null)>=0) + { + bExport.setEnabled(true); + + fDepositBatch.setValue(m_PaymentExport.getDefaultDepositBatch()); + if (m_PaymentExport.supportsDepositBatch() && m_PaymentExport.supportsSeparateBooking()) + { + fDepositBatch.setReadWrite(true); + } + else + { + fDepositBatch.setReadWrite(false); + } + } + else + { + bExport.setEnabled(false); + } + if (printFormatId!=null && printFormatId!=0) + { + bPrint.setEnabled(true); + } + else + { + bPrint.setEnabled(false); + } + } + + } // getPluginFeatures + /************************************************************************** * Export payments to file */ @@ -339,7 +396,8 @@ public class VPayPrint extends PayPrint implements FormPanel, ActionListener, Ve fc.setDialogTitle(Msg.getMsg(Env.getCtx(), "Export")); fc.setFileSelectionMode(JFileChooser.FILES_ONLY); fc.setMultiSelectionEnabled(false); - fc.setSelectedFile(new java.io.File("paymentExport.txt")); + String filename = m_PaymentExport.getFilenamePrefix() + m_PaymentExport.getFilenameSuffix(); + fc.setSelectedFile(new java.io.File(filename)); if (fc.showSaveDialog(panel) != JFileChooser.APPROVE_OPTION) return; @@ -349,26 +407,14 @@ public class VPayPrint extends PayPrint implements FormPanel, ActionListener, Ve if (m_PaymentExportClass == null || m_PaymentExportClass.trim().length() == 0) { m_PaymentExportClass = "org.compiere.util.GenericPaymentExport"; } - // Get Payment Export Class - PaymentExport custom = null; - try + + no = loadPaymentExportClass(err) ; + + if (no >= 0) { - Class clazz = Class.forName(m_PaymentExportClass); - custom = (PaymentExport)clazz.newInstance(); - no = custom.exportToFile(m_checks, fc.getSelectedFile(), err); - } - catch (ClassNotFoundException e) - { - no = -1; - err.append("No custom PaymentExport class " + m_PaymentExportClass + " - " + e.toString()); - log.log(Level.SEVERE, err.toString(), e); - } - catch (Exception e) - { - no = -1; - err.append("Error in " + m_PaymentExportClass + " check log, " + e.toString()); - log.log(Level.SEVERE, err.toString(), e); + no = m_PaymentExport.exportToFile(m_checks,(Boolean) fDepositBatch.getValue(),PaymentRule, fc.getSelectedFile(), err); } + if (no >= 0) { ADialog.info(m_WindowNo, panel, "Saved", fc.getSelectedFile().getAbsolutePath() + "\n" @@ -377,7 +423,7 @@ public class VPayPrint extends PayPrint implements FormPanel, ActionListener, Ve if (ADialog.ask(m_WindowNo, panel, "VPayPrintSuccess?")) { // int lastDocumentNo = - MPaySelectionCheck.confirmPrint (m_checks, m_batch); + MPaySelectionCheck.confirmPrint (m_checks, m_batch, (Boolean) fDepositBatch.getValue()); // document No not updated } } else { diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPayPrint.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPayPrint.java index 8ebc830ea7..692eda2558 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPayPrint.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPayPrint.java @@ -39,6 +39,7 @@ import org.adempiere.webui.component.Rows; import org.adempiere.webui.component.Window; import org.adempiere.webui.editor.WNumberEditor; import org.adempiere.webui.editor.WSearchEditor; +import org.adempiere.webui.editor.WYesNoEditor; import org.adempiere.webui.event.ValueChangeEvent; import org.adempiere.webui.event.ValueChangeListener; import org.adempiere.webui.panel.ADForm; @@ -61,7 +62,6 @@ import org.compiere.util.DB; import org.compiere.util.DisplayType; import org.compiere.util.Env; import org.compiere.util.Msg; -import org.compiere.util.PaymentExport; import org.compiere.util.ValueNamePair; import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.EventListener; @@ -80,6 +80,7 @@ import com.itextpdf.text.pdf.PdfReader; * * Contributors: * Carlos Ruiz - GlobalQSS - FR 3132033 - Make payment export class configurable per bank + * Markus Bozem: IDEMPIERE-1546 / IDEMPIERE-3286 */ public class WPayPrint extends PayPrint implements IFormController, EventListener, ValueChangeListener { @@ -136,7 +137,12 @@ public class WPayPrint extends PayPrint implements IFormController, EventListene protected WNumberEditor fBalance = new WNumberEditor(); protected Label lCurrency = new Label(); protected Label fCurrency = new Label(); + protected Label lDepositBatch = new Label(); + protected WYesNoEditor fDepositBatch = new WYesNoEditor("", "", "Book as one post", false, false, true) ; + protected Label lSumPayments = new Label(); + protected WNumberEditor fSumPayments = new WNumberEditor(); + /** * Static Init * @throws Exception @@ -168,6 +174,10 @@ public class WPayPrint extends PayPrint implements IFormController, EventListene fBalance.setReadWrite(false); fBalance.getComponent().setIntegral(false); lCurrency.setText(Msg.translate(Env.getCtx(), "C_Currency_ID")); + lDepositBatch.setText(Msg.translate(Env.getCtx(), "C_DepositBatch_ID")); + lSumPayments.setText(Msg.getMsg(Env.getCtx(), "Sum")); + fSumPayments.setReadWrite(false); + fSumPayments.getComponent().setIntegral(false); // southPanel.addButton(bExport); southPanel.addButton(bPrint); @@ -195,8 +205,18 @@ public class WPayPrint extends PayPrint implements IFormController, EventListene row.appendChild(fDocumentNo.getComponent()); row.appendChild(lNoPayments.rightAlign()); row.appendChild(fNoPayments); + + row = rows.newRow(); + row.appendChild(lDepositBatch.rightAlign()) ; + row.appendChild(fDepositBatch.getComponent()) ; + row.appendChild(lSumPayments.rightAlign()) ; + row.appendChild(fSumPayments.getComponent()) ; southPanel.getButton(ConfirmPanel.A_OK).setVisible(false); + bExport.setDisabled(true); + bPrint.setDisabled(true); + fDepositBatch.setReadWrite(false); + fDocumentNo.setReadWrite(false); } // VPayPrint /** @@ -318,6 +338,9 @@ public class WPayPrint extends PayPrint implements IFormController, EventListene if(noPayments != null) fNoPayments.setText(noPayments); + + if(sumPayments != null) + fSumPayments.setValue(sumPayments); bProcess.setEnabled(PaymentRule.equals("T")); @@ -326,9 +349,45 @@ public class WPayPrint extends PayPrint implements IFormController, EventListene if(msg != null && msg.length() > 0) FDialog.error(m_WindowNo, form, msg); + + getPluginFeatures(); } // loadPaymentRuleInfo + protected void getPluginFeatures() + { + if (m_C_PaySelection_ID!=0) + { + if (loadPaymentExportClass (null)>=0) + { + bExport.setDisabled(false); + + fDepositBatch.setValue(m_PaymentExport.getDefaultDepositBatch()); + if (m_PaymentExport.supportsDepositBatch() && m_PaymentExport.supportsSeparateBooking()) + { + fDepositBatch.setReadWrite(true); + } + else + { + fDepositBatch.setReadWrite(false); + } + } + else + { + bExport.setDisabled(true); + } + if (printFormatId!=null && printFormatId!=0) + { + bPrint.setEnabled(true); + } + else + { + bPrint.setEnabled(false); + } + } + } // getPluginFeatures + + /************************************************************************** * Export payments to file */ @@ -343,37 +402,28 @@ public class WPayPrint extends PayPrint implements IFormController, EventListene try { - // Get File Info - File tempFile = File.createTempFile("paymentExport", ".txt"); - - // Create File int no = 0; StringBuffer err = new StringBuffer(""); if (m_PaymentExportClass == null || m_PaymentExportClass.trim().length() == 0) { m_PaymentExportClass = "org.compiere.util.GenericPaymentExport"; } - // Get Payment Export Class - PaymentExport custom = null; - try + + File tempFile = null; + String filenameForDownload = ""; + + no = loadPaymentExportClass(err) ; + + if (no >= 0) { - Class clazz = Class.forName(m_PaymentExportClass); - custom = (PaymentExport)clazz.newInstance(); - no = custom.exportToFile(m_checks, tempFile, err); - } - catch (ClassNotFoundException e) - { - no = -1; - err.append("No custom PaymentExport class " + m_PaymentExportClass + " - " + e.toString()); - log.log(Level.SEVERE, err.toString(), e); - } - catch (Exception e) - { - no = -1; - err.append("Error in " + m_PaymentExportClass + " check log, " + e.toString()); - log.log(Level.SEVERE, err.toString(), e); + // Get File Info + tempFile = File.createTempFile(m_PaymentExport.getFilenamePrefix(), m_PaymentExport.getFilenameSuffix()); + filenameForDownload = m_PaymentExport.getFilenamePrefix() + m_PaymentExport.getFilenameSuffix(); + + no = m_PaymentExport.exportToFile(m_checks,(Boolean) fDepositBatch.getValue(),PaymentRule, tempFile, err); } + if (no >= 0) { - Filedownload.save(new FileInputStream(tempFile), "plain/text", "paymentExport.txt"); + Filedownload.save(new FileInputStream(tempFile), m_PaymentExport.getContentType(), filenameForDownload); FDialog.info(m_WindowNo, form, "Saved", Msg.getMsg(Env.getCtx(), "NoOfLines") + "=" + no); @@ -384,7 +434,7 @@ public class WPayPrint extends PayPrint implements IFormController, EventListene { if (result) { - MPaySelectionCheck.confirmPrint (m_checks, m_batch); + MPaySelectionCheck.confirmPrint (m_checks, m_batch, (Boolean) fDepositBatch.getValue()); // document No not updated } diff --git a/org.adempiere.ui/src/org/compiere/apps/form/PayPrint.java b/org.adempiere.ui/src/org/compiere/apps/form/PayPrint.java index 37817a3bb0..7dd2c792eb 100644 --- a/org.adempiere.ui/src/org/compiere/apps/form/PayPrint.java +++ b/org.adempiere.ui/src/org/compiere/apps/form/PayPrint.java @@ -13,7 +13,8 @@ * * * Contributors: * * Carlos Ruiz - GlobalQSS: * - * FR 3132033 - Make payment export class configurable per bank * + * FR 3132033 - Make payment export class configurable per bank + * Markus Bozem: IDEMPIERE-1546 / IDEMPIERE-3286 * *****************************************************************************/ package org.compiere.apps.form; @@ -24,8 +25,11 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; +import java.util.List; import java.util.logging.Level; +import org.adempiere.base.IPaymentExporterFactory; +import org.adempiere.base.Service; import org.compiere.model.MLookupFactory; import org.compiere.model.MLookupInfo; import org.compiere.model.MPaySelectionCheck; @@ -34,6 +38,7 @@ import org.compiere.util.CLogger; import org.compiere.util.DB; import org.compiere.util.Env; import org.compiere.util.Language; +import org.compiere.util.PaymentExport; import org.compiere.util.ValueNamePair; public class PayPrint { @@ -57,6 +62,7 @@ public class PayPrint { public String bank; public String currency; public BigDecimal balance; + protected PaymentExport m_PaymentExport; /** * PaySelect changed - load Bank @@ -157,7 +163,8 @@ public class PayPrint { public String noPayments; public Integer documentNo; - + public Double sumPayments; + public Integer printFormatId; /** * PaymentRule changed - load DocumentNo, NoPayments, @@ -167,19 +174,23 @@ public class PayPrint { { String msg = null; - String sql = "SELECT COUNT(*) " + String sql = "SELECT COUNT(*),SUM(payamt) " + "FROM C_PaySelectionCheck " - + "WHERE C_PaySelection_ID=?"; + + "WHERE C_PaySelection_ID=? AND PaymentRule=?"; PreparedStatement pstmt = null; ResultSet rs = null; try { pstmt = DB.prepareStatement(sql, null); pstmt.setInt(1, C_PaySelection_ID); + pstmt.setString(2, PaymentRule); rs = pstmt.executeQuery(); // if (rs.next()) + { noPayments = String.valueOf(rs.getInt(1)); + sumPayments = rs.getDouble(2); + } } catch (SQLException e) { @@ -192,8 +203,11 @@ public class PayPrint { pstmt = null; } + printFormatId = null; + documentNo = null; + // DocumentNo - sql = "SELECT CurrentNext " + sql = "SELECT CurrentNext, Check_PrintFormat_ID " + "FROM C_BankAccountDoc " + "WHERE C_BankAccount_ID=? AND PaymentRule=? AND IsActive='Y'"; try @@ -204,7 +218,10 @@ public class PayPrint { rs = pstmt.executeQuery(); // if (rs.next()) + { documentNo = new Integer(rs.getInt(1)); + printFormatId = new Integer(rs.getInt(2)); + } else { log.log(Level.SEVERE, "VPayPrint.loadPaymentRuleInfo - No active BankAccountDoc for C_BankAccount_ID=" @@ -225,4 +242,50 @@ public class PayPrint { return msg; } // loadPaymentRuleInfo + + protected int loadPaymentExportClass (StringBuffer err) + { + m_PaymentExport = null ; + + if (m_PaymentExportClass == null || m_PaymentExportClass.trim().length() == 0) { + m_PaymentExportClass = "org.compiere.util.GenericPaymentExport"; + } + try + { + List factories = Service.locator().list(IPaymentExporterFactory.class).getServices(); + if (factories != null && !factories.isEmpty()) { + for(IPaymentExporterFactory factory : factories) { + m_PaymentExport = factory.newPaymentExporterInstance(m_PaymentExportClass); + if (m_PaymentExport != null) + break; + } + } + + if (m_PaymentExport == null) + { + Class clazz = Class.forName (m_PaymentExportClass); + m_PaymentExport = (PaymentExport)clazz.newInstance(); + } + + } + catch (ClassNotFoundException e) + { + if (err!=null) + { + err.append("No custom PaymentExport class " + m_PaymentExportClass + " - " + e.toString()); + log.log(Level.SEVERE, err.toString(), e); + } + return -1; + } + catch (Exception e) + { + if (err!=null) + { + err.append("Error in " + m_PaymentExportClass + " check log, " + e.toString()); + log.log(Level.SEVERE, err.toString(), e); + } + return -1; + } + return 0 ; + } // loadPaymentExportClass } From 0a930345baa60e7620f964e849f183b7ff7f6ac5 Mon Sep 17 00:00:00 2001 From: Orlando Curieles Date: Tue, 17 Oct 2017 19:06:59 +0200 Subject: [PATCH 4/7] IDEMPIERE-3521 InfoWindow problem on other SQL when make a register count --- .../WEB-INF/src/org/adempiere/webui/info/InfoWindow.java | 4 ++++ .../WEB-INF/src/org/adempiere/webui/panel/InfoPanel.java | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoWindow.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoWindow.java index 9d919319a7..21d14192a8 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoWindow.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoWindow.java @@ -1705,6 +1705,10 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL } countSql = MRole.getDefault().addAccessSQL (countSql, getTableName(), MRole.SQL_FULLYQUALIFIED, MRole.SQL_RO); + // Fix GroupBy On InfoWindow + String otherClause = infoWindow.getOtherClause(); + if (otherClause !=null) + countSql = countSql+" "+otherClause; countSql = "SELECT COUNT(*) FROM ( " + countSql + " ) a"; diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/InfoPanel.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/InfoPanel.java index 6ceedc67f7..376011e0d4 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/InfoPanel.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/InfoPanel.java @@ -1065,6 +1065,10 @@ public abstract class InfoPanel extends Window implements EventListener, countSql = countSql.trim(); countSql = countSql.substring(0, countSql.length() - 5); } + String otherClause = infoWindow.getOtherClause(); // Fix otherClause on count + if (otherClause != null) + countSql = countSql+" "+otherClause; + countSql = MRole.getDefault().addAccessSQL (countSql, getTableName(), MRole.SQL_FULLYQUALIFIED, MRole.SQL_RO); if (log.isLoggable(Level.FINER)) From 4fa72355389c8768eae441baea6e900c8412b89e Mon Sep 17 00:00:00 2001 From: Heng Sin Low Date: Wed, 18 Oct 2017 21:05:12 +0800 Subject: [PATCH 5/7] IDEMPIERE-3518 Improvement For Mobile Compatibility --- .../src/org/compiere/model/MSysConfig.java | 3 + .../src/org/compiere/util/DisplayType.java | 3 +- org.adempiere.sdk-feature/adempiere.rmap | 69 +- .../materialize.properties | 2 +- org.adempiere.ui.zk/META-INF/MANIFEST.MF | 5 +- .../org/adempiere/webui/AdempiereWebUI.java | 26 +- .../src/org/adempiere/webui/ClientInfo.java | 82 + .../src/org/adempiere/webui/LayoutUtils.java | 165 +- .../org/adempiere/webui/ValuePreference.java | 8 +- .../src/org/adempiere/webui/WLogin.java | 13 +- .../org/adempiere/webui/acct/WAcctViewer.java | 3 + .../adempiere/webui/adwindow/ADTabpanel.java | 299 +- .../webui/adwindow/ADWindowToolbar.java | 125 + .../adwindow/AbstractADWindowContent.java | 10 +- .../adempiere/webui/adwindow/GridView.java | 27 +- .../src/org/adempiere/webui/apps/AEnv.java | 6 +- .../webui/apps/AbstractProcessDialog.java | 10 +- .../webui/apps/FeedbackRequestWindow.java | 29 +- .../adempiere/webui/apps/GlobalSearch.java | 15 +- .../webui/apps/form/WAllocation.java | 316 +- .../webui/apps/form/WArchiveViewer.java | 148 +- .../adempiere/webui/apps/form/WCharge.java | 12 +- .../webui/apps/form/WCreateFromForm.java | 32 +- .../webui/apps/form/WCreateFromInvoiceUI.java | 116 +- .../webui/apps/form/WCreateFromRMAUI.java | 22 +- .../apps/form/WCreateFromShipmentUI.java | 78 +- .../apps/form/WCreateFromStatementUI.java | 98 +- .../webui/apps/form/WCreateFromWindow.java | 25 +- .../webui/apps/form/WFactReconcile.java | 39 +- .../adempiere/webui/apps/form/WGenForm.java | 26 +- .../adempiere/webui/apps/form/WInOutGen.java | 81 +- .../webui/apps/form/WInvoiceGen.java | 79 +- .../org/adempiere/webui/apps/form/WMatch.java | 203 +- .../adempiere/webui/apps/form/WPayPrint.java | 18 + .../adempiere/webui/apps/form/WPaySelect.java | 67 +- .../webui/apps/form/WPaymentFormWindow.java | 6 +- .../webui/apps/form/WReportCustomization.java | 4 +- .../apps/form/WStatementCreateFromBatch.java | 95 +- .../adempiere/webui/apps/form/WTreeBOM.java | 68 +- .../webui/apps/form/WTreeMaintenance.java | 78 +- .../webui/apps/form/WTrxMaterial.java | 117 +- .../adempiere/webui/apps/graph/WGraph.java | 13 +- .../webui/component/ConfirmPanel.java | 18 + .../webui/component/FolderBrowser.java | 4 +- .../adempiere/webui/component/Messagebox.java | 13 +- .../adempiere/webui/component/NumberBox.java | 10 +- .../webui/component/SimpleTreeModel.java | 17 +- .../org/adempiere/webui/component/Tabbox.java | 15 +- .../webui/component/WListItemRenderer.java | 7 +- .../org/adempiere/webui/component/Window.java | 10 + .../webui/dashboard/RequestWindow.java | 32 +- .../webui/desktop/DashboardController.java | 179 +- .../webui/desktop/DefaultDesktop.java | 231 +- .../org/adempiere/webui/editor/WEditor.java | 52 +- .../webui/editor/WLocationEditor.java | 23 +- .../webui/editor/WLocatorEditor.java | 21 + .../adempiere/webui/editor/WNumberEditor.java | 4 + .../adempiere/webui/editor/WSearchEditor.java | 3 +- .../adempiere/webui/editor/WStringEditor.java | 2 + .../adempiere/webui/editor/WUrlEditor.java | 2 + .../webui/factory/DefaultEditorFactory.java | 5 +- .../org/adempiere/webui/grid/WQuickEntry.java | 38 +- .../webui/info/InfoProductWindow.java | 9 +- .../org/adempiere/webui/info/InfoWindow.java | 84 +- .../src/org/adempiere/webui/panel/ADForm.java | 4 +- .../org/adempiere/webui/panel/CustomForm.java | 2 +- .../webui/panel/CustomizeGridViewPanel.java | 11 +- .../adempiere/webui/panel/HeaderPanel.java | 39 +- .../adempiere/webui/panel/HelpController.java | 6 +- .../webui/panel/InfoGeneralPanel.java | 129 +- .../panel/InfoPAttributeInstancePanel.java | 7 +- .../org/adempiere/webui/panel/InfoPanel.java | 28 +- .../adempiere/webui/panel/InvoiceHistory.java | 23 +- .../org/adempiere/webui/panel/UserPanel.java | 106 +- .../adempiere/webui/panel/WAttachment.java | 44 +- .../webui/panel/WDocActionPanel.java | 6 +- .../webui/panel/WProcessParameterForm.java | 17 +- .../org/adempiere/webui/panel/WSchedule.java | 6 +- .../webui/panel/action/CSVImportAction.java | 2 +- .../webui/panel/action/ExportAction.java | 2 +- .../webui/panel/action/FileImportAction.java | 2 +- .../webui/panel/action/ReportAction.java | 2 +- .../adempiere/webui/part/WindowContainer.java | 122 +- .../src/org/adempiere/webui/theme/ITheme.java | 2 + .../adempiere/webui/theme/ThemeManager.java | 4 + .../adempiere/webui/util/ZKUpdateUtil.java | 44 + .../adempiere/webui/window/AboutWindow.java | 20 +- .../webui/window/CustomizeGridViewDialog.java | 19 +- .../adempiere/webui/window/FindWindow.java | 26 +- .../adempiere/webui/window/InfoSchedule.java | 4 +- .../webui/window/SimplePDFViewer.java | 58 +- .../webui/window/WAccountDialog.java | 362 +- .../webui/window/WAssignmentDialog.java | 6 +- .../src/org/adempiere/webui/window/WChat.java | 48 +- .../adempiere/webui/window/WEMailDialog.java | 21 +- .../webui/window/WFieldRecordInfo.java | 16 +- .../webui/window/WFieldSuggestion.java | 6 +- .../adempiere/webui/window/WImageDialog.java | 30 +- .../webui/window/WLocationDialog.java | 28 +- .../webui/window/WLocatorDialog.java | 26 +- .../adempiere/webui/window/WMediaDialog.java | 26 +- .../webui/window/WPAttributeDialog.java | 6 +- .../webui/window/WPAttributeInstance.java | 18 +- .../org/adempiere/webui/window/WPostIt.java | 32 +- .../adempiere/webui/window/WPreference.java | 13 +- .../adempiere/webui/window/WRecordInfo.java | 18 +- .../webui/window/WTextEditorDialog.java | 19 +- .../adempiere/webui/window/ZkJRViewer.java | 37 +- .../webui/window/ZkReportViewer.java | 183 +- org.adempiere.ui.zk/WEB-INF/zk.xml | 4 + org.adempiere.ui.zk/build.properties | 3 +- org.adempiere.ui.zk/images/iD192.png | Bin 0 -> 27641 bytes org.adempiere.ui.zk/index.zul | 3 + org.adempiere.ui.zk/js/ckeditor/config-min.js | 2 + org.adempiere.ui.zk/js/ckeditor/config.js | 1 + org.adempiere.ui.zk/manifest.json | 13 + .../pdf.js/web/cmaps/78-EUC-H.bcmap | Bin 0 -> 2404 bytes .../pdf.js/web/cmaps/78-EUC-V.bcmap | Bin 0 -> 173 bytes .../pdf.js/web/cmaps/78-H.bcmap | Bin 0 -> 2379 bytes .../pdf.js/web/cmaps/78-RKSJ-H.bcmap | Bin 0 -> 2398 bytes .../pdf.js/web/cmaps/78-RKSJ-V.bcmap | Bin 0 -> 173 bytes .../pdf.js/web/cmaps/78-V.bcmap | Bin 0 -> 169 bytes .../pdf.js/web/cmaps/78ms-RKSJ-H.bcmap | Bin 0 -> 2651 bytes .../pdf.js/web/cmaps/78ms-RKSJ-V.bcmap | Bin 0 -> 290 bytes .../pdf.js/web/cmaps/83pv-RKSJ-H.bcmap | Bin 0 -> 905 bytes .../pdf.js/web/cmaps/90ms-RKSJ-H.bcmap | Bin 0 -> 721 bytes .../pdf.js/web/cmaps/90ms-RKSJ-V.bcmap | Bin 0 -> 290 bytes .../pdf.js/web/cmaps/90msp-RKSJ-H.bcmap | Bin 0 -> 715 bytes .../pdf.js/web/cmaps/90msp-RKSJ-V.bcmap | Bin 0 -> 291 bytes .../pdf.js/web/cmaps/90pv-RKSJ-H.bcmap | Bin 0 -> 982 bytes .../pdf.js/web/cmaps/90pv-RKSJ-V.bcmap | Bin 0 -> 260 bytes .../pdf.js/web/cmaps/Add-H.bcmap | Bin 0 -> 2419 bytes .../pdf.js/web/cmaps/Add-RKSJ-H.bcmap | Bin 0 -> 2413 bytes .../pdf.js/web/cmaps/Add-RKSJ-V.bcmap | Bin 0 -> 287 bytes .../pdf.js/web/cmaps/Add-V.bcmap | Bin 0 -> 282 bytes .../pdf.js/web/cmaps/Adobe-CNS1-0.bcmap | Bin 0 -> 317 bytes .../pdf.js/web/cmaps/Adobe-CNS1-1.bcmap | Bin 0 -> 371 bytes .../pdf.js/web/cmaps/Adobe-CNS1-2.bcmap | Bin 0 -> 376 bytes .../pdf.js/web/cmaps/Adobe-CNS1-3.bcmap | Bin 0 -> 401 bytes .../pdf.js/web/cmaps/Adobe-CNS1-4.bcmap | Bin 0 -> 405 bytes .../pdf.js/web/cmaps/Adobe-CNS1-5.bcmap | Bin 0 -> 406 bytes .../pdf.js/web/cmaps/Adobe-CNS1-6.bcmap | Bin 0 -> 406 bytes .../pdf.js/web/cmaps/Adobe-CNS1-UCS2.bcmap | Bin 0 -> 41193 bytes .../pdf.js/web/cmaps/Adobe-GB1-0.bcmap | Bin 0 -> 217 bytes .../pdf.js/web/cmaps/Adobe-GB1-1.bcmap | Bin 0 -> 250 bytes .../pdf.js/web/cmaps/Adobe-GB1-2.bcmap | Bin 0 -> 465 bytes .../pdf.js/web/cmaps/Adobe-GB1-3.bcmap | Bin 0 -> 470 bytes .../pdf.js/web/cmaps/Adobe-GB1-4.bcmap | Bin 0 -> 601 bytes .../pdf.js/web/cmaps/Adobe-GB1-5.bcmap | Bin 0 -> 625 bytes .../pdf.js/web/cmaps/Adobe-GB1-UCS2.bcmap | Bin 0 -> 33974 bytes .../pdf.js/web/cmaps/Adobe-Japan1-0.bcmap | Bin 0 -> 225 bytes .../pdf.js/web/cmaps/Adobe-Japan1-1.bcmap | Bin 0 -> 226 bytes .../pdf.js/web/cmaps/Adobe-Japan1-2.bcmap | Bin 0 -> 233 bytes .../pdf.js/web/cmaps/Adobe-Japan1-3.bcmap | Bin 0 -> 242 bytes .../pdf.js/web/cmaps/Adobe-Japan1-4.bcmap | Bin 0 -> 337 bytes .../pdf.js/web/cmaps/Adobe-Japan1-5.bcmap | Bin 0 -> 430 bytes .../pdf.js/web/cmaps/Adobe-Japan1-6.bcmap | Bin 0 -> 485 bytes .../pdf.js/web/cmaps/Adobe-Japan1-UCS2.bcmap | Bin 0 -> 40951 bytes .../pdf.js/web/cmaps/Adobe-Korea1-0.bcmap | Bin 0 -> 241 bytes .../pdf.js/web/cmaps/Adobe-Korea1-1.bcmap | Bin 0 -> 386 bytes .../pdf.js/web/cmaps/Adobe-Korea1-2.bcmap | Bin 0 -> 391 bytes .../pdf.js/web/cmaps/Adobe-Korea1-UCS2.bcmap | Bin 0 -> 23293 bytes .../pdf.js/web/cmaps/B5-H.bcmap | Bin 0 -> 1086 bytes .../pdf.js/web/cmaps/B5-V.bcmap | Bin 0 -> 142 bytes .../pdf.js/web/cmaps/B5pc-H.bcmap | Bin 0 -> 1099 bytes .../pdf.js/web/cmaps/B5pc-V.bcmap | Bin 0 -> 144 bytes .../pdf.js/web/cmaps/CNS-EUC-H.bcmap | Bin 0 -> 1780 bytes .../pdf.js/web/cmaps/CNS-EUC-V.bcmap | Bin 0 -> 1920 bytes .../pdf.js/web/cmaps/CNS1-H.bcmap | Bin 0 -> 706 bytes .../pdf.js/web/cmaps/CNS1-V.bcmap | Bin 0 -> 143 bytes .../pdf.js/web/cmaps/CNS2-H.bcmap | Bin 0 -> 504 bytes .../pdf.js/web/cmaps/CNS2-V.bcmap | 3 + .../pdf.js/web/cmaps/ETHK-B5-H.bcmap | Bin 0 -> 4426 bytes .../pdf.js/web/cmaps/ETHK-B5-V.bcmap | Bin 0 -> 158 bytes .../pdf.js/web/cmaps/ETen-B5-H.bcmap | Bin 0 -> 1125 bytes .../pdf.js/web/cmaps/ETen-B5-V.bcmap | Bin 0 -> 158 bytes .../pdf.js/web/cmaps/ETenms-B5-H.bcmap | 3 + .../pdf.js/web/cmaps/ETenms-B5-V.bcmap | Bin 0 -> 172 bytes .../pdf.js/web/cmaps/EUC-H.bcmap | Bin 0 -> 578 bytes .../pdf.js/web/cmaps/EUC-V.bcmap | Bin 0 -> 170 bytes .../pdf.js/web/cmaps/Ext-H.bcmap | Bin 0 -> 2536 bytes .../pdf.js/web/cmaps/Ext-RKSJ-H.bcmap | Bin 0 -> 2542 bytes .../pdf.js/web/cmaps/Ext-RKSJ-V.bcmap | Bin 0 -> 218 bytes .../pdf.js/web/cmaps/Ext-V.bcmap | Bin 0 -> 215 bytes .../pdf.js/web/cmaps/GB-EUC-H.bcmap | Bin 0 -> 549 bytes .../pdf.js/web/cmaps/GB-EUC-V.bcmap | Bin 0 -> 179 bytes .../pdf.js/web/cmaps/GB-H.bcmap | 4 + .../pdf.js/web/cmaps/GB-V.bcmap | Bin 0 -> 175 bytes .../pdf.js/web/cmaps/GBK-EUC-H.bcmap | Bin 0 -> 14692 bytes .../pdf.js/web/cmaps/GBK-EUC-V.bcmap | Bin 0 -> 180 bytes .../pdf.js/web/cmaps/GBK2K-H.bcmap | Bin 0 -> 19662 bytes .../pdf.js/web/cmaps/GBK2K-V.bcmap | Bin 0 -> 219 bytes .../pdf.js/web/cmaps/GBKp-EUC-H.bcmap | Bin 0 -> 14686 bytes .../pdf.js/web/cmaps/GBKp-EUC-V.bcmap | Bin 0 -> 181 bytes .../pdf.js/web/cmaps/GBT-EUC-H.bcmap | Bin 0 -> 7290 bytes .../pdf.js/web/cmaps/GBT-EUC-V.bcmap | Bin 0 -> 180 bytes .../pdf.js/web/cmaps/GBT-H.bcmap | Bin 0 -> 7269 bytes .../pdf.js/web/cmaps/GBT-V.bcmap | Bin 0 -> 176 bytes .../pdf.js/web/cmaps/GBTpc-EUC-H.bcmap | Bin 0 -> 7298 bytes .../pdf.js/web/cmaps/GBTpc-EUC-V.bcmap | Bin 0 -> 182 bytes .../pdf.js/web/cmaps/GBpc-EUC-H.bcmap | Bin 0 -> 557 bytes .../pdf.js/web/cmaps/GBpc-EUC-V.bcmap | Bin 0 -> 181 bytes org.adempiere.ui.zk/pdf.js/web/cmaps/H.bcmap | Bin 0 -> 553 bytes .../pdf.js/web/cmaps/HKdla-B5-H.bcmap | Bin 0 -> 2654 bytes .../pdf.js/web/cmaps/HKdla-B5-V.bcmap | Bin 0 -> 148 bytes .../pdf.js/web/cmaps/HKdlb-B5-H.bcmap | Bin 0 -> 2414 bytes .../pdf.js/web/cmaps/HKdlb-B5-V.bcmap | Bin 0 -> 148 bytes .../pdf.js/web/cmaps/HKgccs-B5-H.bcmap | Bin 0 -> 2292 bytes .../pdf.js/web/cmaps/HKgccs-B5-V.bcmap | Bin 0 -> 149 bytes .../pdf.js/web/cmaps/HKm314-B5-H.bcmap | Bin 0 -> 1772 bytes .../pdf.js/web/cmaps/HKm314-B5-V.bcmap | Bin 0 -> 149 bytes .../pdf.js/web/cmaps/HKm471-B5-H.bcmap | Bin 0 -> 2171 bytes .../pdf.js/web/cmaps/HKm471-B5-V.bcmap | Bin 0 -> 149 bytes .../pdf.js/web/cmaps/HKscs-B5-H.bcmap | Bin 0 -> 4437 bytes .../pdf.js/web/cmaps/HKscs-B5-V.bcmap | Bin 0 -> 159 bytes .../pdf.js/web/cmaps/Hankaku.bcmap | Bin 0 -> 132 bytes .../pdf.js/web/cmaps/Hiragana.bcmap | Bin 0 -> 124 bytes .../pdf.js/web/cmaps/KSC-EUC-H.bcmap | Bin 0 -> 1848 bytes .../pdf.js/web/cmaps/KSC-EUC-V.bcmap | Bin 0 -> 164 bytes .../pdf.js/web/cmaps/KSC-H.bcmap | Bin 0 -> 1831 bytes .../pdf.js/web/cmaps/KSC-Johab-H.bcmap | Bin 0 -> 16791 bytes .../pdf.js/web/cmaps/KSC-Johab-V.bcmap | Bin 0 -> 166 bytes .../pdf.js/web/cmaps/KSC-V.bcmap | Bin 0 -> 160 bytes .../pdf.js/web/cmaps/KSCms-UHC-H.bcmap | Bin 0 -> 2787 bytes .../pdf.js/web/cmaps/KSCms-UHC-HW-H.bcmap | Bin 0 -> 2789 bytes .../pdf.js/web/cmaps/KSCms-UHC-HW-V.bcmap | Bin 0 -> 169 bytes .../pdf.js/web/cmaps/KSCms-UHC-V.bcmap | Bin 0 -> 166 bytes .../pdf.js/web/cmaps/KSCpc-EUC-H.bcmap | Bin 0 -> 2024 bytes .../pdf.js/web/cmaps/KSCpc-EUC-V.bcmap | Bin 0 -> 166 bytes .../pdf.js/web/cmaps/Katakana.bcmap | Bin 0 -> 100 bytes org.adempiere.ui.zk/pdf.js/web/cmaps/LICENSE | 36 + .../pdf.js/web/cmaps/NWP-H.bcmap | Bin 0 -> 2765 bytes .../pdf.js/web/cmaps/NWP-V.bcmap | Bin 0 -> 252 bytes .../pdf.js/web/cmaps/RKSJ-H.bcmap | Bin 0 -> 534 bytes .../pdf.js/web/cmaps/RKSJ-V.bcmap | Bin 0 -> 170 bytes .../pdf.js/web/cmaps/Roman.bcmap | Bin 0 -> 96 bytes .../pdf.js/web/cmaps/UniCNS-UCS2-H.bcmap | Bin 0 -> 48280 bytes .../pdf.js/web/cmaps/UniCNS-UCS2-V.bcmap | Bin 0 -> 156 bytes .../pdf.js/web/cmaps/UniCNS-UTF16-H.bcmap | Bin 0 -> 50419 bytes .../pdf.js/web/cmaps/UniCNS-UTF16-V.bcmap | Bin 0 -> 156 bytes .../pdf.js/web/cmaps/UniCNS-UTF32-H.bcmap | Bin 0 -> 52679 bytes .../pdf.js/web/cmaps/UniCNS-UTF32-V.bcmap | Bin 0 -> 160 bytes .../pdf.js/web/cmaps/UniCNS-UTF8-H.bcmap | Bin 0 -> 53629 bytes .../pdf.js/web/cmaps/UniCNS-UTF8-V.bcmap | Bin 0 -> 157 bytes .../pdf.js/web/cmaps/UniGB-UCS2-H.bcmap | Bin 0 -> 43366 bytes .../pdf.js/web/cmaps/UniGB-UCS2-V.bcmap | Bin 0 -> 193 bytes .../pdf.js/web/cmaps/UniGB-UTF16-H.bcmap | Bin 0 -> 44086 bytes .../pdf.js/web/cmaps/UniGB-UTF16-V.bcmap | Bin 0 -> 178 bytes .../pdf.js/web/cmaps/UniGB-UTF32-H.bcmap | Bin 0 -> 45738 bytes .../pdf.js/web/cmaps/UniGB-UTF32-V.bcmap | Bin 0 -> 182 bytes .../pdf.js/web/cmaps/UniGB-UTF8-H.bcmap | Bin 0 -> 46837 bytes .../pdf.js/web/cmaps/UniGB-UTF8-V.bcmap | Bin 0 -> 181 bytes .../pdf.js/web/cmaps/UniJIS-UCS2-H.bcmap | Bin 0 -> 25439 bytes .../pdf.js/web/cmaps/UniJIS-UCS2-HW-H.bcmap | Bin 0 -> 119 bytes .../pdf.js/web/cmaps/UniJIS-UCS2-HW-V.bcmap | Bin 0 -> 680 bytes .../pdf.js/web/cmaps/UniJIS-UCS2-V.bcmap | Bin 0 -> 664 bytes .../pdf.js/web/cmaps/UniJIS-UTF16-H.bcmap | Bin 0 -> 39443 bytes .../pdf.js/web/cmaps/UniJIS-UTF16-V.bcmap | Bin 0 -> 643 bytes .../pdf.js/web/cmaps/UniJIS-UTF32-H.bcmap | Bin 0 -> 40539 bytes .../pdf.js/web/cmaps/UniJIS-UTF32-V.bcmap | Bin 0 -> 677 bytes .../pdf.js/web/cmaps/UniJIS-UTF8-H.bcmap | Bin 0 -> 41695 bytes .../pdf.js/web/cmaps/UniJIS-UTF8-V.bcmap | Bin 0 -> 678 bytes .../pdf.js/web/cmaps/UniJIS2004-UTF16-H.bcmap | Bin 0 -> 39534 bytes .../pdf.js/web/cmaps/UniJIS2004-UTF16-V.bcmap | Bin 0 -> 647 bytes .../pdf.js/web/cmaps/UniJIS2004-UTF32-H.bcmap | Bin 0 -> 40630 bytes .../pdf.js/web/cmaps/UniJIS2004-UTF32-V.bcmap | Bin 0 -> 681 bytes .../pdf.js/web/cmaps/UniJIS2004-UTF8-H.bcmap | Bin 0 -> 41779 bytes .../pdf.js/web/cmaps/UniJIS2004-UTF8-V.bcmap | Bin 0 -> 682 bytes .../web/cmaps/UniJISPro-UCS2-HW-V.bcmap | Bin 0 -> 705 bytes .../pdf.js/web/cmaps/UniJISPro-UCS2-V.bcmap | Bin 0 -> 689 bytes .../pdf.js/web/cmaps/UniJISPro-UTF8-V.bcmap | Bin 0 -> 726 bytes .../web/cmaps/UniJISX0213-UTF32-H.bcmap | Bin 0 -> 40517 bytes .../web/cmaps/UniJISX0213-UTF32-V.bcmap | Bin 0 -> 684 bytes .../web/cmaps/UniJISX02132004-UTF32-H.bcmap | Bin 0 -> 40608 bytes .../web/cmaps/UniJISX02132004-UTF32-V.bcmap | Bin 0 -> 688 bytes .../pdf.js/web/cmaps/UniKS-UCS2-H.bcmap | Bin 0 -> 25783 bytes .../pdf.js/web/cmaps/UniKS-UCS2-V.bcmap | Bin 0 -> 178 bytes .../pdf.js/web/cmaps/UniKS-UTF16-H.bcmap | Bin 0 -> 26327 bytes .../pdf.js/web/cmaps/UniKS-UTF16-V.bcmap | Bin 0 -> 164 bytes .../pdf.js/web/cmaps/UniKS-UTF32-H.bcmap | Bin 0 -> 26451 bytes .../pdf.js/web/cmaps/UniKS-UTF32-V.bcmap | Bin 0 -> 168 bytes .../pdf.js/web/cmaps/UniKS-UTF8-H.bcmap | Bin 0 -> 27790 bytes .../pdf.js/web/cmaps/UniKS-UTF8-V.bcmap | Bin 0 -> 169 bytes org.adempiere.ui.zk/pdf.js/web/cmaps/V.bcmap | Bin 0 -> 166 bytes .../pdf.js/web/cmaps/WP-Symbol.bcmap | Bin 0 -> 179 bytes org.adempiere.ui.zk/pdf.js/web/debugger.js | 620 + .../pdf.js/web/images/annotation-check.svg | 11 + .../pdf.js/web/images/annotation-comment.svg | 16 + .../pdf.js/web/images/annotation-help.svg | 26 + .../pdf.js/web/images/annotation-insert.svg | 10 + .../pdf.js/web/images/annotation-key.svg | 11 + .../web/images/annotation-newparagraph.svg | 11 + .../pdf.js/web/images/annotation-noicon.svg | 7 + .../pdf.js/web/images/annotation-note.svg | 42 + .../web/images/annotation-paragraph.svg | 16 + .../web/images/findbarButton-next-rtl.png | Bin 0 -> 199 bytes .../web/images/findbarButton-next-rtl@2x.png | Bin 0 -> 304 bytes .../pdf.js/web/images/findbarButton-next.png | Bin 0 -> 193 bytes .../web/images/findbarButton-next@2x.png | Bin 0 -> 296 bytes .../web/images/findbarButton-previous-rtl.png | Bin 0 -> 193 bytes .../images/findbarButton-previous-rtl@2x.png | Bin 0 -> 296 bytes .../web/images/findbarButton-previous.png | Bin 0 -> 199 bytes .../web/images/findbarButton-previous@2x.png | Bin 0 -> 304 bytes .../pdf.js/web/images/grab.cur | Bin 0 -> 326 bytes .../pdf.js/web/images/grabbing.cur | Bin 0 -> 326 bytes .../pdf.js/web/images/loading-icon.gif | Bin 0 -> 2545 bytes .../pdf.js/web/images/loading-small.png | Bin 0 -> 7402 bytes .../pdf.js/web/images/loading-small@2x.png | Bin 0 -> 16131 bytes ...ondaryToolbarButton-documentProperties.png | Bin 0 -> 403 bytes ...aryToolbarButton-documentProperties@2x.png | Bin 0 -> 933 bytes .../secondaryToolbarButton-firstPage.png | Bin 0 -> 179 bytes .../secondaryToolbarButton-firstPage@2x.png | Bin 0 -> 266 bytes .../secondaryToolbarButton-handTool.png | Bin 0 -> 301 bytes .../secondaryToolbarButton-handTool@2x.png | Bin 0 -> 583 bytes .../secondaryToolbarButton-lastPage.png | Bin 0 -> 175 bytes .../secondaryToolbarButton-lastPage@2x.png | Bin 0 -> 276 bytes .../secondaryToolbarButton-rotateCcw.png | Bin 0 -> 360 bytes .../secondaryToolbarButton-rotateCcw@2x.png | Bin 0 -> 731 bytes .../secondaryToolbarButton-rotateCw.png | Bin 0 -> 359 bytes .../secondaryToolbarButton-rotateCw@2x.png | Bin 0 -> 714 bytes .../secondaryToolbarButton-selectTool.png | Bin 0 -> 461 bytes .../secondaryToolbarButton-selectTool@2x.png | Bin 0 -> 1067 bytes .../pdf.js/web/images/shadow.png | Bin 0 -> 290 bytes .../pdf.js/web/images/texture.png | Bin 0 -> 2417 bytes .../web/images/toolbarButton-bookmark.png | Bin 0 -> 174 bytes .../web/images/toolbarButton-bookmark@2x.png | Bin 0 -> 260 bytes .../web/images/toolbarButton-download.png | Bin 0 -> 259 bytes .../web/images/toolbarButton-download@2x.png | Bin 0 -> 425 bytes .../web/images/toolbarButton-menuArrows.png | Bin 0 -> 107 bytes .../images/toolbarButton-menuArrows@2x.png | Bin 0 -> 152 bytes .../web/images/toolbarButton-openFile.png | Bin 0 -> 295 bytes .../web/images/toolbarButton-openFile@2x.png | Bin 0 -> 550 bytes .../web/images/toolbarButton-pageDown-rtl.png | Bin 0 -> 242 bytes .../images/toolbarButton-pageDown-rtl@2x.png | Bin 0 -> 398 bytes .../web/images/toolbarButton-pageDown.png | Bin 0 -> 238 bytes .../web/images/toolbarButton-pageDown@2x.png | Bin 0 -> 396 bytes .../web/images/toolbarButton-pageUp-rtl.png | Bin 0 -> 245 bytes .../images/toolbarButton-pageUp-rtl@2x.png | Bin 0 -> 405 bytes .../web/images/toolbarButton-pageUp.png | Bin 0 -> 246 bytes .../web/images/toolbarButton-pageUp@2x.png | Bin 0 -> 403 bytes .../images/toolbarButton-presentationMode.png | Bin 0 -> 321 bytes .../toolbarButton-presentationMode@2x.png | Bin 0 -> 586 bytes .../pdf.js/web/images/toolbarButton-print.png | Bin 0 -> 257 bytes .../web/images/toolbarButton-print@2x.png | Bin 0 -> 464 bytes .../web/images/toolbarButton-search.png | Bin 0 -> 309 bytes .../web/images/toolbarButton-search@2x.png | Bin 0 -> 653 bytes ...olbarButton-secondaryToolbarToggle-rtl.png | Bin 0 -> 246 bytes ...arButton-secondaryToolbarToggle-rtl@2x.png | Bin 0 -> 456 bytes .../toolbarButton-secondaryToolbarToggle.png | Bin 0 -> 243 bytes ...oolbarButton-secondaryToolbarToggle@2x.png | Bin 0 -> 458 bytes .../toolbarButton-sidebarToggle-rtl.png | Bin 0 -> 225 bytes .../toolbarButton-sidebarToggle-rtl@2x.png | Bin 0 -> 344 bytes .../images/toolbarButton-sidebarToggle.png | Bin 0 -> 225 bytes .../images/toolbarButton-sidebarToggle@2x.png | Bin 0 -> 331 bytes .../images/toolbarButton-viewAttachments.png | Bin 0 -> 384 bytes .../toolbarButton-viewAttachments@2x.png | Bin 0 -> 859 bytes .../images/toolbarButton-viewOutline-rtl.png | Bin 0 -> 177 bytes .../toolbarButton-viewOutline-rtl@2x.png | Bin 0 -> 394 bytes .../web/images/toolbarButton-viewOutline.png | Bin 0 -> 178 bytes .../images/toolbarButton-viewOutline@2x.png | Bin 0 -> 331 bytes .../images/toolbarButton-viewThumbnail.png | Bin 0 -> 185 bytes .../images/toolbarButton-viewThumbnail@2x.png | Bin 0 -> 219 bytes .../web/images/toolbarButton-zoomIn.png | Bin 0 -> 136 bytes .../web/images/toolbarButton-zoomIn@2x.png | Bin 0 -> 160 bytes .../web/images/toolbarButton-zoomOut.png | Bin 0 -> 88 bytes .../web/images/toolbarButton-zoomOut@2x.png | Bin 0 -> 109 bytes .../web/images/treeitem-collapsed-rtl.png | Bin 0 -> 143 bytes .../web/images/treeitem-collapsed-rtl@2x.png | Bin 0 -> 167 bytes .../pdf.js/web/images/treeitem-collapsed.png | Bin 0 -> 128 bytes .../web/images/treeitem-collapsed@2x.png | Bin 0 -> 149 bytes .../pdf.js/web/images/treeitem-expanded.png | Bin 0 -> 125 bytes .../web/images/treeitem-expanded@2x.png | Bin 0 -> 172 bytes .../pdf.js/web/locale/ach/viewer.properties | 179 + .../pdf.js/web/locale/af/viewer.properties | 184 + .../pdf.js/web/locale/ak/viewer.properties | 130 + .../pdf.js/web/locale/an/viewer.properties | 180 + .../pdf.js/web/locale/ar/viewer.properties | 184 + .../pdf.js/web/locale/as/viewer.properties | 167 + .../pdf.js/web/locale/ast/viewer.properties | 177 + .../pdf.js/web/locale/az/viewer.properties | 184 + .../pdf.js/web/locale/be/viewer.properties | 184 + .../pdf.js/web/locale/bg/viewer.properties | 184 + .../pdf.js/web/locale/bn-BD/viewer.properties | 181 + .../pdf.js/web/locale/bn-IN/viewer.properties | 177 + .../pdf.js/web/locale/br/viewer.properties | 180 + .../pdf.js/web/locale/bs/viewer.properties | 184 + .../pdf.js/web/locale/ca/viewer.properties | 184 + .../pdf.js/web/locale/cs/viewer.properties | 184 + .../pdf.js/web/locale/csb/viewer.properties | 134 + .../pdf.js/web/locale/cy/viewer.properties | 184 + .../pdf.js/web/locale/da/viewer.properties | 184 + .../pdf.js/web/locale/de/viewer.properties | 184 + .../pdf.js/web/locale/el/viewer.properties | 184 + .../pdf.js/web/locale/en-GB/viewer.properties | 184 + .../pdf.js/web/locale/en-US/viewer.properties | 184 + .../pdf.js/web/locale/en-ZA/viewer.properties | 170 + .../pdf.js/web/locale/eo/viewer.properties | 184 + .../pdf.js/web/locale/es-AR/viewer.properties | 184 + .../pdf.js/web/locale/es-CL/viewer.properties | 184 + .../pdf.js/web/locale/es-ES/viewer.properties | 117 + .../pdf.js/web/locale/es-MX/viewer.properties | 184 + .../pdf.js/web/locale/et/viewer.properties | 184 + .../pdf.js/web/locale/eu/viewer.properties | 184 + .../pdf.js/web/locale/fa/viewer.properties | 184 + .../pdf.js/web/locale/ff/viewer.properties | 184 + .../pdf.js/web/locale/fi/viewer.properties | 184 + .../pdf.js/web/locale/fr/viewer.properties | 184 + .../pdf.js/web/locale/fy-NL/viewer.properties | 184 + .../pdf.js/web/locale/ga-IE/viewer.properties | 184 + .../pdf.js/web/locale/gd/viewer.properties | 184 + .../pdf.js/web/locale/gl/viewer.properties | 168 + .../pdf.js/web/locale/gu-IN/viewer.properties | 184 + .../pdf.js/web/locale/he/viewer.properties | 184 + .../pdf.js/web/locale/hi-IN/viewer.properties | 183 + .../pdf.js/web/locale/hr/viewer.properties | 184 + .../pdf.js/web/locale/hu/viewer.properties | 184 + .../pdf.js/web/locale/hy-AM/viewer.properties | 184 + .../pdf.js/web/locale/id/viewer.properties | 184 + .../pdf.js/web/locale/is/viewer.properties | 184 + .../pdf.js/web/locale/it/viewer.properties | 117 + .../pdf.js/web/locale/ja/viewer.properties | 184 + .../pdf.js/web/locale/ka/viewer.properties | 184 + .../pdf.js/web/locale/kk/viewer.properties | 184 + .../pdf.js/web/locale/km/viewer.properties | 184 + .../pdf.js/web/locale/kn/viewer.properties | 169 + .../pdf.js/web/locale/ko/viewer.properties | 184 + .../pdf.js/web/locale/ku/viewer.properties | 146 + .../pdf.js/web/locale/lg/viewer.properties | 112 + .../pdf.js/web/locale/lij/viewer.properties | 180 + .../pdf.js/web/locale/locale.properties | 312 + .../pdf.js/web/locale/lt/viewer.properties | 184 + .../pdf.js/web/locale/lv/viewer.properties | 184 + .../pdf.js/web/locale/mai/viewer.properties | 168 + .../pdf.js/web/locale/mk/viewer.properties | 133 + .../pdf.js/web/locale/ml/viewer.properties | 168 + .../pdf.js/web/locale/mn/viewer.properties | 82 + .../pdf.js/web/locale/mr/viewer.properties | 184 + .../pdf.js/web/locale/ms/viewer.properties | 184 + .../pdf.js/web/locale/my/viewer.properties | 180 + .../pdf.js/web/locale/nb-NO/viewer.properties | 184 + .../pdf.js/web/locale/nl/viewer.properties | 184 + .../pdf.js/web/locale/nn-NO/viewer.properties | 184 + .../pdf.js/web/locale/nso/viewer.properties | 130 + .../pdf.js/web/locale/oc/viewer.properties | 184 + .../pdf.js/web/locale/or/viewer.properties | 167 + .../pdf.js/web/locale/pa-IN/viewer.properties | 184 + .../pdf.js/web/locale/pl/viewer.properties | 131 + .../pdf.js/web/locale/pt-BR/viewer.properties | 184 + .../pdf.js/web/locale/pt-PT/viewer.properties | 184 + .../pdf.js/web/locale/rm/viewer.properties | 184 + .../pdf.js/web/locale/ro/viewer.properties | 177 + .../pdf.js/web/locale/ru/viewer.properties | 184 + .../pdf.js/web/locale/rw/viewer.properties | 81 + .../pdf.js/web/locale/sah/viewer.properties | 166 + .../pdf.js/web/locale/si/viewer.properties | 171 + .../pdf.js/web/locale/sk/viewer.properties | 184 + .../pdf.js/web/locale/sl/viewer.properties | 184 + .../pdf.js/web/locale/son/viewer.properties | 180 + .../pdf.js/web/locale/sq/viewer.properties | 184 + .../pdf.js/web/locale/sr/viewer.properties | 184 + .../pdf.js/web/locale/sv-SE/viewer.properties | 184 + .../pdf.js/web/locale/sw/viewer.properties | 128 + .../pdf.js/web/locale/ta-LK/viewer.properties | 77 + .../pdf.js/web/locale/ta/viewer.properties | 184 + .../pdf.js/web/locale/te/viewer.properties | 183 + .../pdf.js/web/locale/th/viewer.properties | 184 + .../pdf.js/web/locale/tl/viewer.properties | 101 + .../pdf.js/web/locale/tn/viewer.properties | 83 + .../pdf.js/web/locale/tr/viewer.properties | 184 + .../pdf.js/web/locale/uk/viewer.properties | 184 + .../pdf.js/web/locale/ur/viewer.properties | 176 + .../pdf.js/web/locale/vi/viewer.properties | 184 + .../pdf.js/web/locale/wo/viewer.properties | 124 + .../pdf.js/web/locale/xh/viewer.properties | 184 + .../pdf.js/web/locale/zh-CN/viewer.properties | 184 + .../pdf.js/web/locale/zh-TW/viewer.properties | 184 + .../pdf.js/web/locale/zu/viewer.properties | 131 + org.adempiere.ui.zk/pdf.js/web/viewer.css | 2277 ++++ org.adempiere.ui.zk/pdf.js/web/viewer.html | 364 + org.adempiere.ui.zk/pdf.js/web/viewer.js | 10446 ++++++++++++++++ org.adempiere.ui.zk/pdf.js/web/viewer.js.map | 1 + .../default/css/fragment/adwindow.css.dsp | 9 +- .../css/fragment/application-menu.css.dsp | 34 +- .../default/css/fragment/borderlayout.css.dsp | 29 +- .../theme/default/css/fragment/button.css.dsp | 3 + .../default/css/fragment/desktop.css.dsp | 45 +- .../default/css/fragment/field-editor.css.dsp | 3 + .../theme/default/css/fragment/gadget.css.dsp | 2 +- .../default/css/fragment/info-window.css.dsp | 3 + .../theme/default/css/fragment/login.css.dsp | 31 + .../css/fragment/parameter-process.css.dsp | 16 +- .../default/css/fragment/window-size.css.dsp | 375 + .../theme/default/css/theme.css.dsp | 2 + .../theme/default/preference.zul | 2 + .../theme/default/zul/desktop/header.zul | 14 +- org.idempiere.zk.extra/META-INF/MANIFEST.MF | 14 +- org.idempiere.zk.extra/copyjars.xml | 2 +- 497 files changed, 36569 insertions(+), 1071 deletions(-) create mode 100644 org.adempiere.ui.zk/images/iD192.png create mode 100644 org.adempiere.ui.zk/manifest.json create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/78-EUC-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/78-EUC-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/78-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/78-RKSJ-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/78-RKSJ-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/78-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/78ms-RKSJ-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/78ms-RKSJ-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/83pv-RKSJ-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/90ms-RKSJ-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/90ms-RKSJ-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/90msp-RKSJ-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/90msp-RKSJ-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/90pv-RKSJ-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/90pv-RKSJ-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/Add-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/Add-RKSJ-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/Add-RKSJ-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/Add-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/Adobe-CNS1-0.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/Adobe-CNS1-1.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/Adobe-CNS1-2.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/Adobe-CNS1-3.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/Adobe-CNS1-4.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/Adobe-CNS1-5.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/Adobe-CNS1-6.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/Adobe-CNS1-UCS2.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/Adobe-GB1-0.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/Adobe-GB1-1.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/Adobe-GB1-2.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/Adobe-GB1-3.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/Adobe-GB1-4.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/Adobe-GB1-5.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/Adobe-GB1-UCS2.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/Adobe-Japan1-0.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/Adobe-Japan1-1.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/Adobe-Japan1-2.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/Adobe-Japan1-3.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/Adobe-Japan1-4.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/Adobe-Japan1-5.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/Adobe-Japan1-6.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/Adobe-Japan1-UCS2.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/Adobe-Korea1-0.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/Adobe-Korea1-1.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/Adobe-Korea1-2.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/Adobe-Korea1-UCS2.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/B5-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/B5-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/B5pc-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/B5pc-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/CNS-EUC-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/CNS-EUC-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/CNS1-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/CNS1-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/CNS2-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/CNS2-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/ETHK-B5-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/ETHK-B5-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/ETen-B5-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/ETen-B5-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/ETenms-B5-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/ETenms-B5-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/EUC-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/EUC-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/Ext-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/Ext-RKSJ-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/Ext-RKSJ-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/Ext-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/GB-EUC-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/GB-EUC-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/GB-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/GB-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/GBK-EUC-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/GBK-EUC-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/GBK2K-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/GBK2K-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/GBKp-EUC-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/GBKp-EUC-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/GBT-EUC-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/GBT-EUC-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/GBT-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/GBT-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/GBTpc-EUC-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/GBTpc-EUC-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/GBpc-EUC-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/GBpc-EUC-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/HKdla-B5-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/HKdla-B5-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/HKdlb-B5-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/HKdlb-B5-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/HKgccs-B5-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/HKgccs-B5-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/HKm314-B5-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/HKm314-B5-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/HKm471-B5-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/HKm471-B5-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/HKscs-B5-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/HKscs-B5-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/Hankaku.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/Hiragana.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/KSC-EUC-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/KSC-EUC-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/KSC-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/KSC-Johab-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/KSC-Johab-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/KSC-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/KSCms-UHC-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/KSCms-UHC-HW-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/KSCms-UHC-HW-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/KSCms-UHC-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/KSCpc-EUC-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/KSCpc-EUC-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/Katakana.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/LICENSE create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/NWP-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/NWP-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/RKSJ-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/RKSJ-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/Roman.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/UniCNS-UCS2-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/UniCNS-UCS2-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/UniCNS-UTF16-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/UniCNS-UTF16-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/UniCNS-UTF32-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/UniCNS-UTF32-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/UniCNS-UTF8-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/UniCNS-UTF8-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/UniGB-UCS2-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/UniGB-UCS2-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/UniGB-UTF16-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/UniGB-UTF16-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/UniGB-UTF32-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/UniGB-UTF32-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/UniGB-UTF8-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/UniGB-UTF8-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/UniJIS-UCS2-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/UniJIS-UCS2-HW-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/UniJIS-UCS2-HW-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/UniJIS-UCS2-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/UniJIS-UTF16-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/UniJIS-UTF16-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/UniJIS-UTF32-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/UniJIS-UTF32-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/UniJIS-UTF8-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/UniJIS-UTF8-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/UniJIS2004-UTF16-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/UniJIS2004-UTF16-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/UniJIS2004-UTF32-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/UniJIS2004-UTF32-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/UniJIS2004-UTF8-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/UniJIS2004-UTF8-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/UniJISPro-UCS2-HW-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/UniJISPro-UCS2-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/UniJISPro-UTF8-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/UniJISX0213-UTF32-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/UniJISX0213-UTF32-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/UniJISX02132004-UTF32-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/UniJISX02132004-UTF32-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/UniKS-UCS2-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/UniKS-UCS2-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/UniKS-UTF16-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/UniKS-UTF16-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/UniKS-UTF32-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/UniKS-UTF32-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/UniKS-UTF8-H.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/UniKS-UTF8-V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/V.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/cmaps/WP-Symbol.bcmap create mode 100644 org.adempiere.ui.zk/pdf.js/web/debugger.js create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/annotation-check.svg create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/annotation-comment.svg create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/annotation-help.svg create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/annotation-insert.svg create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/annotation-key.svg create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/annotation-newparagraph.svg create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/annotation-noicon.svg create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/annotation-note.svg create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/annotation-paragraph.svg create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/findbarButton-next-rtl.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/findbarButton-next-rtl@2x.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/findbarButton-next.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/findbarButton-next@2x.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/findbarButton-previous-rtl.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/findbarButton-previous-rtl@2x.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/findbarButton-previous.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/findbarButton-previous@2x.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/grab.cur create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/grabbing.cur create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/loading-icon.gif create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/loading-small.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/loading-small@2x.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/secondaryToolbarButton-documentProperties.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/secondaryToolbarButton-documentProperties@2x.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/secondaryToolbarButton-firstPage.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/secondaryToolbarButton-firstPage@2x.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/secondaryToolbarButton-handTool.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/secondaryToolbarButton-handTool@2x.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/secondaryToolbarButton-lastPage.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/secondaryToolbarButton-lastPage@2x.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/secondaryToolbarButton-rotateCcw.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/secondaryToolbarButton-rotateCcw@2x.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/secondaryToolbarButton-rotateCw.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/secondaryToolbarButton-rotateCw@2x.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/secondaryToolbarButton-selectTool.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/secondaryToolbarButton-selectTool@2x.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/shadow.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/texture.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/toolbarButton-bookmark.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/toolbarButton-bookmark@2x.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/toolbarButton-download.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/toolbarButton-download@2x.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/toolbarButton-menuArrows.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/toolbarButton-menuArrows@2x.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/toolbarButton-openFile.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/toolbarButton-openFile@2x.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/toolbarButton-pageDown-rtl.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/toolbarButton-pageDown-rtl@2x.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/toolbarButton-pageDown.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/toolbarButton-pageDown@2x.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/toolbarButton-pageUp-rtl.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/toolbarButton-pageUp-rtl@2x.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/toolbarButton-pageUp.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/toolbarButton-pageUp@2x.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/toolbarButton-presentationMode.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/toolbarButton-presentationMode@2x.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/toolbarButton-print.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/toolbarButton-print@2x.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/toolbarButton-search.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/toolbarButton-search@2x.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/toolbarButton-secondaryToolbarToggle-rtl.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/toolbarButton-secondaryToolbarToggle-rtl@2x.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/toolbarButton-secondaryToolbarToggle.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/toolbarButton-secondaryToolbarToggle@2x.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/toolbarButton-sidebarToggle-rtl.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/toolbarButton-sidebarToggle-rtl@2x.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/toolbarButton-sidebarToggle.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/toolbarButton-sidebarToggle@2x.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/toolbarButton-viewAttachments.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/toolbarButton-viewAttachments@2x.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/toolbarButton-viewOutline-rtl.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/toolbarButton-viewOutline-rtl@2x.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/toolbarButton-viewOutline.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/toolbarButton-viewOutline@2x.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/toolbarButton-viewThumbnail.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/toolbarButton-viewThumbnail@2x.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/toolbarButton-zoomIn.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/toolbarButton-zoomIn@2x.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/toolbarButton-zoomOut.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/toolbarButton-zoomOut@2x.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/treeitem-collapsed-rtl.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/treeitem-collapsed-rtl@2x.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/treeitem-collapsed.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/treeitem-collapsed@2x.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/treeitem-expanded.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/images/treeitem-expanded@2x.png create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/ach/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/af/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/ak/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/an/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/ar/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/as/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/ast/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/az/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/be/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/bg/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/bn-BD/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/bn-IN/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/br/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/bs/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/ca/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/cs/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/csb/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/cy/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/da/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/de/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/el/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/en-GB/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/en-US/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/en-ZA/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/eo/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/es-AR/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/es-CL/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/es-ES/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/es-MX/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/et/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/eu/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/fa/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/ff/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/fi/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/fr/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/fy-NL/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/ga-IE/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/gd/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/gl/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/gu-IN/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/he/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/hi-IN/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/hr/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/hu/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/hy-AM/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/id/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/is/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/it/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/ja/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/ka/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/kk/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/km/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/kn/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/ko/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/ku/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/lg/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/lij/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/locale.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/lt/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/lv/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/mai/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/mk/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/ml/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/mn/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/mr/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/ms/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/my/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/nb-NO/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/nl/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/nn-NO/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/nso/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/oc/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/or/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/pa-IN/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/pl/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/pt-BR/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/pt-PT/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/rm/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/ro/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/ru/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/rw/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/sah/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/si/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/sk/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/sl/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/son/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/sq/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/sr/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/sv-SE/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/sw/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/ta-LK/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/ta/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/te/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/th/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/tl/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/tn/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/tr/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/uk/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/ur/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/vi/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/wo/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/xh/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/zh-CN/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/zh-TW/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/locale/zu/viewer.properties create mode 100644 org.adempiere.ui.zk/pdf.js/web/viewer.css create mode 100644 org.adempiere.ui.zk/pdf.js/web/viewer.html create mode 100644 org.adempiere.ui.zk/pdf.js/web/viewer.js create mode 100644 org.adempiere.ui.zk/pdf.js/web/viewer.js.map create mode 100644 org.adempiere.ui.zk/theme/default/css/fragment/window-size.css.dsp diff --git a/org.adempiere.base/src/org/compiere/model/MSysConfig.java b/org.adempiere.base/src/org/compiere/model/MSysConfig.java index 8b9ebda7cc..e3f8181cdf 100644 --- a/org.adempiere.base/src/org/compiere/model/MSysConfig.java +++ b/org.adempiere.base/src/org/compiere/model/MSysConfig.java @@ -159,12 +159,15 @@ public class MSysConfig extends X_AD_SysConfig public static final String ZK_FOOTER_SERVER_DATETIME_FORMAT = "ZK_FOOTER_SERVER_DATETIME_FORMAT"; public static final String ZK_FOOTER_SERVER_MSG = "ZK_FOOTER_SERVER_MSG"; public static final String ZK_GRID_EDIT_MODELESS = "ZK_GRID_EDIT_MODELESS"; + public static final String ZK_GRID_MOBILE_EDIT_MODELESS = "ZK_GRID_MOBILE_EDIT_MODELESS"; + public static final String ZK_GRID_MOBILE_MAX_COLUMNS = "ZK_GRID_MOBILE_MAX_COLUMNS"; public static final String ZK_INFO_NUM_PAGE_PRELOAD = "ZK_INFO_NUM_PAGE_PRELOAD"; public static final String ZK_LOGIN_ALLOW_CHROME_SAVE_PASSWORD = "ZK_LOGIN_ALLOW_CHROME_SAVE_PASSWORD"; public static final String ZK_LOGIN_ALLOW_REMEMBER_ME = "ZK_LOGIN_ALLOW_REMEMBER_ME"; public static final String ZK_LOGO_LARGE = "ZK_LOGO_LARGE"; public static final String ZK_LOGO_SMALL = "ZK_LOGO_SMALL"; public static final String ZK_MAX_UPLOAD_SIZE = "ZK_MAX_UPLOAD_SIZE"; + public static final String ZK_MOBILE_PAGING_SIZE = "ZK_MOBILE_PAGING_SIZE"; public static final String ZK_PAGING_SIZE = "ZK_PAGING_SIZE"; public static final String ZK_REPORT_FORM_OUTPUT_TYPE = "ZK_REPORT_FORM_OUTPUT_TYPE"; public static final String ZK_REPORT_JASPER_OUTPUT_TYPE = "ZK_REPORT_JASPER_OUTPUT_TYPE"; diff --git a/org.adempiere.base/src/org/compiere/util/DisplayType.java b/org.adempiere.base/src/org/compiere/util/DisplayType.java index 9137c8c8e1..fb7ac27013 100644 --- a/org.adempiere.base/src/org/compiere/util/DisplayType.java +++ b/org.adempiere.base/src/org/compiere/util/DisplayType.java @@ -65,7 +65,6 @@ import java.util.logging.Level; import org.adempiere.base.IDisplayTypeFactory; import org.adempiere.base.Service; -import org.compiere.model.MCurrency; /** * System Display Types. @@ -271,7 +270,7 @@ public final class DisplayType || displayType == TextLong || displayType == Memo || displayType == FilePath || displayType == FileName || displayType == URL || displayType == PrinterName - || displayType == SingleSelectionGrid + || displayType == SingleSelectionGrid || displayType == Color || displayType == MultipleSelectionGrid) return true; diff --git a/org.adempiere.sdk-feature/adempiere.rmap b/org.adempiere.sdk-feature/adempiere.rmap index 5612b1d021..c3662f4ca2 100644 --- a/org.adempiere.sdk-feature/adempiere.rmap +++ b/org.adempiere.sdk-feature/adempiere.rmap @@ -22,16 +22,16 @@ - - - - - - - - - - + + + + + + + + + + @@ -63,7 +63,6 @@ - @@ -155,26 +154,26 @@ - - - - - - - + + + + + + + - - - - + + + + - - + + @@ -189,63 +188,63 @@ - + - + - + - + - + - + - + - + - + - + - + diff --git a/org.adempiere.sdk-feature/materialize.properties b/org.adempiere.sdk-feature/materialize.properties index 2cc27b38d4..a42936c203 100644 --- a/org.adempiere.sdk-feature/materialize.properties +++ b/org.adempiere.sdk-feature/materialize.properties @@ -14,7 +14,7 @@ url.maven2.lib=http://central.maven.org url.maven.zkoss=http://mavensync.zkoss.org url.maven.zkoss.lib=http://mavensync.zkoss.org -url.zkoss.osgi=http://downloads.sourceforge.net/project/idempiere/binary.file/jarfile/zk-p2/zk-8.0.1.1/ +url.zkoss.osgi=http://downloads.sourceforge.net/project/idempiere/binary.file/jarfile/zk-p2/zk-8.0.2.2/ url.maven.restlet=http://maven.restlet.org diff --git a/org.adempiere.ui.zk/META-INF/MANIFEST.MF b/org.adempiere.ui.zk/META-INF/MANIFEST.MF index 683b4af05d..6d3abecb90 100644 --- a/org.adempiere.ui.zk/META-INF/MANIFEST.MF +++ b/org.adempiere.ui.zk/META-INF/MANIFEST.MF @@ -4,7 +4,8 @@ Bundle-Name: iDempiere Web Client Bundle-SymbolicName: org.adempiere.ui.zk;singleton:=true Bundle-Version: 4.1.0.qualifier Bundle-RequiredExecutionEnvironment: JavaSE-1.8 -Import-Package: javax.activation, +Import-Package: groovy.transform.stc;version="2.4.7", + javax.activation, javax.annotation;version="1.2.0", javax.annotation.processing, javax.annotation.security;version="1.2.0", @@ -90,3 +91,5 @@ Bundle-Activator: org.adempiere.webui.WebUIActivator Eclipse-ExtensibleAPI: true Web-ContextPath: webui Service-Component: OSGI-INF/reportviewerprovider.xml, OSGI-INF/defaultinfofactory.xml, OSGI-INF/defaulteditorfactory.xml, OSGI-INF/jrviewerprovider.xml, OSGI-INF/resourcefinder.xml, OSGI-INF/defaultpaymentformfactory.xml, OSGI-INF/processfactory.xml, OSGI-INF/defaultprintshippinglabel.xml, OSGI-INF/defaultcreatefromfactory.xml, OSGI-INF/defaultformfactory.xml, OSGI-INF/feedbackservice.xml, OSGI-INF/zulgadgetfactory.xml, OSGI-INF/jfgchartrenderer.xml +Bundle-ActivationPolicy: lazy +Eclipse-RegisterBuddy: org.idempiere.zk.extra diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/AdempiereWebUI.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/AdempiereWebUI.java index 32d38f75af..8790a1672a 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/AdempiereWebUI.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/AdempiereWebUI.java @@ -118,7 +118,6 @@ public class AdempiereWebUI extends Window implements EventListener, IWeb public AdempiereWebUI() { - this.addEventListener(Events.ON_CLIENT_INFO, this); this.setVisible(false); userPreference = new UserPreference(); @@ -146,6 +145,7 @@ public class AdempiereWebUI extends Window implements EventListener, IWeb { loginDesktop = new WLogin(this); loginDesktop.createPart(this.getPage()); + loginDesktop.getComponent().getRoot().addEventListener(Events.ON_CLIENT_INFO, this); } else { @@ -176,6 +176,7 @@ public class AdempiereWebUI extends Window implements EventListener, IWeb { if (loginDesktop != null) { + loginDesktop.getComponent().getRoot().removeEventListener(Events.ON_CLIENT_INFO, this); loginDesktop.detach(); loginDesktop = null; } @@ -255,6 +256,7 @@ public class AdempiereWebUI extends Window implements EventListener, IWeb appDesktop.setClientInfo(clientInfo); appDesktop.createPart(this.getPage()); this.getPage().getDesktop().setAttribute(APPLICATION_DESKTOP_KEY, new WeakReference(appDesktop)); + appDesktop.getComponent().getRoot().addEventListener(Events.ON_CLIENT_INFO, this); //track browser tab per session SessionContextListener.addDesktopId(mSession.getAD_Session_ID(), getPage().getDesktop().getId()); @@ -278,8 +280,8 @@ public class AdempiereWebUI extends Window implements EventListener, IWeb } Env.setContext(ctx, "#LocalHttpAddr", localHttpAddr.toString()); Clients.response(new AuScript("zAu.cmd0.clearBusy()")); - - processParameters(); + + processParameters(); } private void processParameters() { @@ -441,14 +443,16 @@ public class AdempiereWebUI extends Window implements EventListener, IWeb clientInfo.desktopXOffset = c.getDesktopXOffset(); clientInfo.desktopYOffset = c.getDesktopYOffset(); clientInfo.orientation = c.getOrientation(); - clientInfo.timeZone = c.getTimeZone(); - IDesktop appDesktop = getAppDeskop(); - if (appDesktop != null) - appDesktop.setClientInfo(clientInfo); + clientInfo.timeZone = c.getTimeZone(); String ua = Servlets.getUserAgent((ServletRequest) Executions.getCurrent().getNativeRequest()); clientInfo.userAgent = ua; ua = ua.toLowerCase(); - clientInfo.tablet = Executions.getCurrent().getBrowser("mobile") !=null; + clientInfo.tablet = false; + if (Executions.getCurrent().getBrowser("mobile") !=null) { + clientInfo.tablet = true; + } else if (ua.contains("ipad") || ua.contains("iphone") || ua.contains("android")) { + clientInfo.tablet = true; + } if (getDesktop() != null && getDesktop().getSession() != null) { getDesktop().getSession().setAttribute(CLIENT_INFO, clientInfo); } @@ -457,6 +461,11 @@ public class AdempiereWebUI extends Window implements EventListener, IWeb Env.setContext(Env.getCtx(), "#clientInfo_desktopHeight", clientInfo.desktopHeight); Env.setContext(Env.getCtx(), "#clientInfo_orientation", clientInfo.orientation); Env.setContext(Env.getCtx(), "#clientInfo_mobile", clientInfo.tablet); + + IDesktop appDesktop = getAppDeskop(); + if (appDesktop != null) + appDesktop.setClientInfo(clientInfo); + } } @@ -469,6 +478,7 @@ public class AdempiereWebUI extends Window implements EventListener, IWeb loginDesktop = new WLogin(this); loginDesktop.createPart(this.getPage()); loginDesktop.changeRole(locale, properties); + loginDesktop.getComponent().getRoot().addEventListener(Events.ON_CLIENT_INFO, this); } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/ClientInfo.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/ClientInfo.java index 1f7a61858d..0dcd074d24 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/ClientInfo.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/ClientInfo.java @@ -19,6 +19,14 @@ package org.adempiere.webui; import java.io.Serializable; import java.util.TimeZone; +import org.adempiere.webui.session.SessionManager; +import org.compiere.util.Env; +import org.zkoss.zk.ui.Component; +import org.zkoss.zk.ui.event.Event; +import org.zkoss.zk.ui.event.EventListener; +import org.zkoss.zk.ui.event.Events; +import org.zkoss.zk.ui.sys.ComponentCtrl; + /** * * @author Low Heng Sin @@ -43,6 +51,16 @@ public class ClientInfo implements Serializable { public boolean tablet; public double devicePixelRatio; + public static final int LARGE_WIDTH = 1200; + public static final int MEDIUM_WIDTH = 1000; + public static final int SMALL_WIDTH = 700; + public static final int EXTRA_SMALL_WIDTH = 500; + + public static final int LARGE_HEIGHT = 1000; + public static final int MEDIUM_HEIGHT = 700; + public static final int SMALL_HEIGHT = 500; + public static final int EXTRA_SMALL_HEIGHT = 360; + @Override public String toString() { StringBuilder builder = new StringBuilder(); @@ -73,6 +91,70 @@ public class ClientInfo implements Serializable { return builder.toString(); } + + /** + * @return true if mobile browser + */ + public static boolean isMobile() { + return "Y".equals(Env.getContext(Env.getCtx(), "#clientInfo_mobile")); + } + + /** + * @return the current clientinfo instance + */ + public static ClientInfo get() { + return SessionManager.getAppDesktop().getClientInfo(); + } + /** + * + * @param minWidth + * @return true if desktopWidth >= minWidth + */ + public static boolean minWidth(int minWidth) { + return ClientInfo.get().desktopWidth > 0 && ClientInfo.get().desktopWidth >= minWidth; + } + /** + * + * @param maxWidth + * @return true if desktopWidth <= maxWidth + */ + public static boolean maxWidth(int maxWidth) { + return ClientInfo.get().desktopWidth > 0 && ClientInfo.get().desktopWidth <= maxWidth; + } + + /** + * + * @param minHeight + * @return true if desktopHeight >= minHeight + */ + public static boolean minHeight(int minHeight) { + return ClientInfo.get().desktopHeight > 0 && ClientInfo.get().desktopHeight >= minHeight; + } + + /** + * + * @param maxHeight + * @return true if desktopHeight <= maxHeight + */ + public static boolean maxHeight(int maxHeight) { + return ClientInfo.get().desktopHeight > 0 && ClientInfo.get().desktopHeight <= maxHeight; + } + + private static String AFTER_PAGE_DETACHED = "afterPageDetached"; + + /** + * Call runnable on client info update + * @param component + * @param runnable + */ + public static void onClientInfo(Component component, Runnable runnable) { + ComponentCtrl ctrl = (ComponentCtrl) component; + EventListener eventListener = evt -> runnable.run(); + + Component root = SessionManager.getAppDesktop().getComponent().getRoot(); + root.addEventListener(Events.ON_CLIENT_INFO, eventListener); + ctrl.addCallback(AFTER_PAGE_DETACHED, t -> root.removeEventListener(Events.ON_CLIENT_INFO, eventListener)); + } } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/LayoutUtils.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/LayoutUtils.java index ba8ef0c34f..9ca7216c9b 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/LayoutUtils.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/LayoutUtils.java @@ -14,6 +14,8 @@ package org.adempiere.webui; import java.io.IOException; import java.io.StringWriter; +import java.util.ArrayList; +import java.util.List; import org.adempiere.webui.component.Label; import org.adempiere.webui.component.Mask; @@ -26,9 +28,18 @@ import org.zkoss.zk.au.out.AuScript; import org.zkoss.zk.ui.AbstractComponent; import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.HtmlBasedComponent; +import org.zkoss.zk.ui.event.EventListener; +import org.zkoss.zk.ui.event.Events; +import org.zkoss.zk.ui.event.OpenEvent; import org.zkoss.zk.ui.util.Clients; import org.zkoss.zul.Borderlayout; +import org.zkoss.zul.Cell; import org.zkoss.zul.Div; +import org.zkoss.zul.Grid; +import org.zkoss.zul.LayoutRegion; +import org.zkoss.zul.Row; +import org.zkoss.zul.Rows; +import org.zkoss.zul.Space; import org.zkoss.zul.Window; import org.zkoss.zul.Window.Mode; @@ -92,13 +103,21 @@ public final class LayoutUtils { return div; } + public static void openPopupWindow(Component ref, Window window) { + openPopupWindow(ref, window, 0); + } + /** * open popup window overlapping the ref component * @param ref * @param window */ - public static void openPopupWindow(Component ref, Window window) { - openPopupWindow(ref, window, "overlap"); + public static void openPopupWindow(Component ref, Window window, int delayMs) { + openPopupWindow(ref, window, "overlap", delayMs); + } + + public static void openPopupWindow(Component ref, Window window, String position) { + openPopupWindow(ref, window, position, 0); } /** @@ -107,17 +126,24 @@ public final class LayoutUtils { * @param window * @param position */ - public static void openPopupWindow(Component ref, Window window, String position) { + public static void openPopupWindow(Component ref, Window window, String position, int delayMs) { if (window.getPage() == null) window.setPage(ref.getPage()); StringBuilder script = new StringBuilder(); + if (delayMs > 0) { + script.append("setTimeout(function() { "); + } script.append("_idempiere_popup_window('#") .append(ref.getUuid()) .append("','#") .append(window.getUuid()) .append("','") .append(position) - .append("');"); + .append("'); "); + script.append("zk.Widget.$('#").append(window.getUuid()).append("').focus(); "); + if (delayMs > 0) { + script.append(" }, ").append(delayMs).append(");"); + } window.doPopup(); Clients.response("_openPopupWindow_", new AuScript(window, script.toString())); window.focus(); @@ -318,4 +344,135 @@ public final class LayoutUtils { } return trueParent; } + + /** + * Compact grid to limit (for e.g, to max of 2 column) + * Note: doesn't handle row span + * @param grid + * @param limit + */ + public static void compactTo(Grid grid, int limit) { + Rows rows = grid.getRows(); + if (rows == null) return; + Row currentRow = (Row)rows.getFirstChild(); + while (currentRow != null) { + int size = 0; + int extraStart = 0; + for (Component component : currentRow.getChildren()) { + if (component instanceof Cell) { + Cell cell = (Cell) component; + size += cell.getColspan(); + } else { + size++; + } + if (size > limit && extraStart == 0) + extraStart = currentRow.getChildren().indexOf(component); + } + Row nextRow = (Row) currentRow.getNextSibling(); + if (size > limit) { + List extras = new ArrayList<>(); + for(int i = extraStart; i < currentRow.getChildren().size(); i++) { + extras.add(currentRow.getChildren().get(i)); + } + org.adempiere.webui.component.Row newRow = new org.adempiere.webui.component.Row(); + int spanOffset = 0; + while (!extras.isEmpty()) { + Component component = extras.remove(0); + if (component instanceof Cell) { + spanOffset += (((Cell)component).getColspan()-1); + } + newRow.appendChild(component); + if (newRow.getChildren().size()+spanOffset >= limit) { + if (nextRow != null) + rows.insertBefore(newRow, nextRow); + else + rows.appendChild(newRow); + newRow = new org.adempiere.webui.component.Row(); + } + } + if (newRow.getChildren().size() > 0) { + if (nextRow != null) + rows.insertBefore(newRow, nextRow); + else + rows.appendChild(newRow); + } + } + currentRow = nextRow; + } + } + + public static void expandTo(Grid grid, int min) { + expandTo(grid, min, false); + } + + /** + * Expand grid to min (for e.g, to min of 2 column) + * Note: doesn't handle row span + * @param grid + * @param min + * @param fillWithSpace if true, fill up row with space instead of + * moving element from next row + */ + public static void expandTo(Grid grid, int min, boolean fillWithSpace) { + Rows rows = grid.getRows(); + if (rows == null) return; + Row currentRow = (Row)rows.getFirstChild(); + while (currentRow != null) { + int size = 0; + for (Component component : currentRow.getChildren()) { + if (component instanceof Cell) { + Cell cell = (Cell) component; + size += cell.getColspan(); + } else { + size++; + } + } + Row nextRow = (Row) currentRow.getNextSibling(); + if (size < min) { + if (fillWithSpace) { + Cell cell = new Cell(); + cell.setColspan(min-size); + cell.appendChild(new Space()); + currentRow.appendChild(cell); + } else { + while (size < min && nextRow != null) { + List toAdd = new ArrayList<>(); + for (Component c : nextRow.getChildren()) { + toAdd.add(c); + if (c instanceof Cell) + size += ((Cell)c).getColspan(); + else + size++; + if (size >= min) + break; + } + for(Component c : toAdd) { + currentRow.appendChild(c); + } + } + if (nextRow != null && nextRow.getChildren().isEmpty()) { + nextRow.detach(); + continue; + } + } + } + currentRow = nextRow; + } + } + + private static final EventListener addSlideEventListener = (OpenEvent evt) -> { + if (evt.isOpen()) + LayoutUtils.removeSclass("slide", (HtmlBasedComponent) evt.getTarget()); + else + LayoutUtils.addSclass("slide", (HtmlBasedComponent) evt.getTarget()); + evt.getTarget().invalidate(); + }; + + /** + * enable slide sclass ( when slide out ) for collapsible region + * @param region + */ + public static void addSlideSclass(LayoutRegion region) { + region.addEventListener(Events.ON_OPEN, addSlideEventListener); + } } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/ValuePreference.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/ValuePreference.java index 13f32af59f..1228acb1c2 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/ValuePreference.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/ValuePreference.java @@ -34,6 +34,7 @@ import org.adempiere.webui.component.Rows; import org.adempiere.webui.component.Textbox; import org.adempiere.webui.component.Window; import org.adempiere.webui.component.ZkCssHelper; +import org.adempiere.webui.theme.ThemeManager; import org.adempiere.webui.util.ZKUpdateUtil; import org.adempiere.webui.window.FDialog; import org.compiere.model.GridField; @@ -390,9 +391,12 @@ public class ValuePreference extends Window implements EventListener this.setBorder("normal"); setLayout.makeNoStrip(); setLayout.setOddRowSclass("even"); - - ZKUpdateUtil.setWidth(this, "500px"); + + if (!ThemeManager.isUseCSSForWindowSize()) { + ZKUpdateUtil.setWindowWidthX(this, 500); + } this.setSizable(true); + this.setSclass("value-preference-dialog"); } // jbInit /** diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/WLogin.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/WLogin.java index c123d9e34f..3cc2d19d16 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/WLogin.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/WLogin.java @@ -17,11 +17,14 @@ package org.adempiere.webui; import java.util.Locale; import java.util.Properties; +import javax.servlet.ServletRequest; + import org.adempiere.webui.apps.AEnv; import org.adempiere.webui.part.AbstractUIPart; import org.adempiere.webui.theme.ThemeManager; import org.adempiere.webui.util.ZKUpdateUtil; import org.adempiere.webui.window.LoginWindow; +import org.zkoss.web.servlet.Servlets; import org.zkoss.zhtml.Text; import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.Executions; @@ -79,7 +82,15 @@ public class WLogin extends AbstractUIPart browserWarningWindow.doOverlapped(); } - boolean mobile = Executions.getCurrent().getBrowser("mobile") !=null; + boolean mobile = false; + if (Executions.getCurrent().getBrowser("mobile") !=null) { + mobile = true; + } else { + String ua = Servlets.getUserAgent((ServletRequest) Executions.getCurrent().getNativeRequest()); + ua = ua.toLowerCase(); + if (ua.contains("ipad") || ua.contains("iphone") || ua.contains("android")) + mobile = true; + } West west = layout.getWest(); if (west.getFirstChild() != null && west.getFirstChild().getFirstChild() != null) { diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/acct/WAcctViewer.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/acct/WAcctViewer.java index 9bf3c87a7d..fee0f344d7 100755 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/acct/WAcctViewer.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/acct/WAcctViewer.java @@ -25,6 +25,7 @@ import java.util.List; import java.util.logging.Level; import org.adempiere.util.Callback; +import org.adempiere.webui.ClientInfo; import org.adempiere.webui.apps.AEnv; import org.adempiere.webui.component.Button; import org.adempiere.webui.component.Checkbox; @@ -537,6 +538,8 @@ public class WAcctViewer extends Window implements EventListener ZKUpdateUtil.setHflex(table, "1"); //ZKUpdateUtil.setVflex(table, "1"); table.addEventListener(Events.ON_DOUBLE_CLICK, this); + if (ClientInfo.isMobile()) + table.setSizedByContent(true); pagingPanel = new South(); resultPanel.appendChild(pagingPanel); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADTabpanel.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADTabpanel.java index 959cd01fe1..7f84f5f7da 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADTabpanel.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADTabpanel.java @@ -17,6 +17,8 @@ package org.adempiere.webui.adwindow; +import java.math.RoundingMode; +import java.text.DecimalFormat; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; @@ -176,13 +178,13 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer private GridView listPanel; - private Map> fieldGroupContents = new HashMap>(); + private Map> fieldGroupContents; - private Map> fieldGroupHeaders = new HashMap>(); + private Map> fieldGroupHeaders; private ArrayList rowList; - List allCollapsibleGroups = new ArrayList(); + List allCollapsibleGroups; private Borderlayout formContainer = null; @@ -203,6 +205,8 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer /** DefaultFocusField */ private WEditor defaultFocusField = null; + private int numberOfFormColumns; + public static final String ON_TOGGLE_EVENT = "onToggle"; private static enum SouthEvent { @@ -232,6 +236,8 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer }); addEventListener(ON_POST_INIT_EVENT, this); addEventListener(ON_SAVE_OPEN_PREFERENCE_EVENT, this); + if (ClientInfo.isMobile()) + ClientInfo.onClientInfo(this, this::onClientInfo); } private void initComponents() @@ -260,13 +266,10 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer South south = borderLayout.getSouth(); if (south == null) { south = new South(); + LayoutUtils.addSlideSclass(south); borderLayout.appendChild(south); - south.setWidgetOverride("doClick_", "function (evt){this.$supers('doClick_', arguments);" + - "var target = evt.domTarget;if (!target.id) target = target.parentNode;" + - "if(this.$n('colled') == target) {" + - "var se = new zk.Event(this, 'onSlide', null, {toServer: true}); zAu.send(se); } }"); south.addEventListener(Events.ON_OPEN, this); - south.addEventListener("onSlide", this); + south.addEventListener(Events.ON_SLIDE, this); south.addEventListener(Events.ON_SWIPE, new EventListener() { @@ -277,7 +280,8 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer South south = borderLayout.getSouth(); if (south.isOpen()) { south.setOpen(false); - onSouthEvent(SouthEvent.CLOSE); + OpenEvent openEvent = new OpenEvent(Events.ON_OPEN, south, false); + Events.postEvent(openEvent); } } } @@ -288,8 +292,10 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer south.setVisible(true); south.setCollapsible(true); south.setSplittable(true); - south.setOpen(isOpenDetailPane()); + south.setOpen(isOpenDetailPane()); south.setSclass("adwindow-gridview-detail"); + if (!south.isOpen()) + LayoutUtils.addSclass("slide", south); String height = heigthDetailPane(); if (! Util.isEmpty(height)) { try { @@ -367,6 +373,11 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer west.setSplittable(true); west.setAutoscroll(true); layout.appendChild(west); + LayoutUtils.addSlideSclass(west); + if (isMobile()) { + west.setOpen(false); + LayoutUtils.addSclass("slide", west); + } Center center = new Center(); Vlayout div = new Vlayout(); @@ -416,26 +427,70 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer @Override public void createUI() { - if (uiCreated) return; - - uiCreated = true; + createUI(false); + } + + protected void createUI(boolean update) + { + if (update) + { + if (!uiCreated) return; + } + else + { + if (uiCreated) return; + uiCreated = true; + } + + fieldGroupContents = new HashMap>(); + fieldGroupHeaders = new HashMap>(); + allCollapsibleGroups = new ArrayList(); int numCols=gridTab.getNumColumns(); if (numCols <= 0) { - numCols=4; + numCols=6; } + //adapt layout for phone and tablet + int diff = 0; + if (isMobile()) + { + if (ClientInfo.maxWidth(ClientInfo.EXTRA_SMALL_WIDTH-1)) { + if (numCols > 3) { + diff = numCols - 3; + numCols=3; + } + } else if (ClientInfo.maxWidth(ClientInfo.MEDIUM_WIDTH-1)) { + if (numCols > 6) { + diff = numCols - 6; + numCols=6; + } + } + } + + this.numberOfFormColumns = numCols; + + if (update) + form.getColumns().detach(); // set size in percentage per column leaving a MARGIN on right - Columns columns = new Columns(); + Columns columns = new Columns(); form.appendChild(columns); - int equalWidth = 98 / numCols; + double equalWidth = 95.00d / numCols; + DecimalFormat decimalFormat = new DecimalFormat("0.00"); + decimalFormat.setRoundingMode(RoundingMode.DOWN); + String columnWidth = decimalFormat.format(equalWidth); for (int h=0;h numCols && diff > 0) + { + xpos = xpos - diff; + if (xpos <= 0) + xpos = 1; + if (xpos == 1 && (field.getDisplayType() == DisplayType.YesNo || field.getDisplayType() == DisplayType.Button || field.isFieldOnly())) + xpos = 2; + } + //normal field - if (field.getXPosition() <= actualxpos) { + if (xpos <= actualxpos) { // Fill right part of the row with spacers until number of columns if (numCols - actualxpos + 1 > 0) row.appendCellChild(createSpacer(), numCols - actualxpos + 1); @@ -535,29 +606,32 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer actualxpos = 0; } // Fill left part of the field - if (field.getXPosition()-1 - actualxpos > 0) - row.appendCellChild(createSpacer(), field.getXPosition()-1 - actualxpos); + if (xpos-1 - actualxpos > 0) + row.appendCellChild(createSpacer(), xpos-1 - actualxpos); boolean paintLabel = ! (field.getDisplayType() == DisplayType.Button || field.getDisplayType() == DisplayType.YesNo || field.isFieldOnly()); if (field.isHeading()) - actualxpos = field.getXPosition(); + actualxpos = xpos; else - actualxpos = field.getXPosition() + field.getColumnSpan()-1 + (paintLabel ? 1 : 0); + actualxpos = xpos + field.getColumnSpan()-1 + (paintLabel ? 1 : 0); if (! field.isHeading()) { - WEditor editor = WebEditorFactory.getEditor(gridTab, field, false); + WEditor editor = update ? findEditor(field) : WebEditorFactory.getEditor(gridTab, field, false); if (editor != null) // Not heading { - editor.getComponent().setWidgetOverride("fieldHeader", HelpController.escapeJavascriptContent(field.getHeader())); - editor.getComponent().setWidgetOverride("fieldDescription", HelpController.escapeJavascriptContent(field.getDescription())); - editor.getComponent().setWidgetOverride("fieldHelp", HelpController.escapeJavascriptContent(field.getHelp())); - editor.getComponent().setWidgetListener("onFocus", "zWatch.fire('onFieldTooltip', this, null, this.fieldHeader(), this.fieldDescription(), this.fieldHelp());"); + if (!update) + { + editor.getComponent().setWidgetOverride("fieldHeader", HelpController.escapeJavascriptContent(field.getHeader())); + editor.getComponent().setWidgetOverride("fieldDescription", HelpController.escapeJavascriptContent(field.getDescription())); + editor.getComponent().setWidgetOverride("fieldHelp", HelpController.escapeJavascriptContent(field.getHelp())); + editor.getComponent().setWidgetListener("onFocus", "zWatch.fire('onFieldTooltip', this, null, this.fieldHeader(), this.fieldDescription(), this.fieldHelp());"); - editor.setGridTab(this.getGridTab()); - field.addPropertyChangeListener(editor); - editors.add(editor); - editorComps.add(editor.getComponent()); + editor.setGridTab(this.getGridTab()); + field.addPropertyChangeListener(editor); + editors.add(editor); + editorComps.add(editor.getComponent()); + } if (paintLabel) { Div div = new Div(); div.setSclass("form-label"); @@ -571,57 +645,71 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer //to support float/absolute editor row.getLastCell().setStyle("position: relative; overflow: visible;"); - if (editor instanceof WButtonEditor) + if (!update) { - if (windowPanel != null) - ((WButtonEditor)editor).addActionListener(windowPanel); - } - else - { - editor.addValueChangeListener(dataBinder); + if (editor instanceof WButtonEditor) + { + if (windowPanel != null) + ((WButtonEditor)editor).addActionListener(windowPanel); + } + else + { + editor.addValueChangeListener(dataBinder); + } } // Default Focus if (defaultFocusField == null && field.isDefaultFocus()) defaultFocusField = editor; - //stretch component to fill grid cell - editor.fillHorizontal(); - - Component fellow = editor.getComponent().getFellowIfAny(field.getColumnName()); - if (fellow == null) { - editor.getComponent().setId(field.getColumnName()); - } - - //setup editor context menu - WEditorPopupMenu popupMenu = editor.getPopupMenu(); - if (popupMenu == null) + if (!update) { - popupMenu = new WEditorPopupMenu(false, false, false, false, false, false, null); - popupMenu.addSuggestion(field); + //stretch component to fill grid cell + editor.fillHorizontal(); + + Component fellow = editor.getComponent().getFellowIfAny(field.getColumnName()); + if (fellow == null) { + editor.getComponent().setId(field.getColumnName()); + } + + //setup editor context menu + WEditorPopupMenu popupMenu = editor.getPopupMenu(); + if (popupMenu == null) + { + popupMenu = new WEditorPopupMenu(false, false, false, false, false, false, null); + popupMenu.addSuggestion(field); + } + if (popupMenu != null) + { + if (editor instanceof ContextMenuListener) + popupMenu.addMenuListener((ContextMenuListener)editor); + popupMenu.setId(field.getColumnName()+"-popup"); + this.appendChild(popupMenu); + if (!field.isFieldOnly()) + { + Label label = editor.getLabel(); + if (ClientInfo.isMobile()) + { + WEditorPopupMenu finalPopupMenu = popupMenu; + label.addEventListener(Events.ON_CLICK, evt-> finalPopupMenu.open(label, "after_start")); + } + else + { + if (popupMenu.isZoomEnabled() && editor instanceof IZoomableEditor) + { + label.addEventListener(Events.ON_CLICK, new ZoomListener((IZoomableEditor) editor)); + } + + popupMenu.addContextElement(label); + if (editor.getComponent() instanceof XulElement) + { + popupMenu.addContextElement((XulElement) editor.getComponent()); + } + } + } + popupMenu.addSuggestion(field); + } } - if (popupMenu != null) - { - if (editor instanceof ContextMenuListener) - popupMenu.addMenuListener((ContextMenuListener)editor); - popupMenu.setId(field.getColumnName()+"-popup"); - this.appendChild(popupMenu); - if (!field.isFieldOnly()) - { - Label label = editor.getLabel(); - if (popupMenu.isZoomEnabled() && editor instanceof IZoomableEditor) - { - label.addEventListener(Events.ON_CLICK, new ZoomListener((IZoomableEditor) editor)); - } - - popupMenu.addContextElement(label); - if (editor.getComponent() instanceof XulElement) - { - popupMenu.addContextElement((XulElement) editor.getComponent()); - } - } - popupMenu.addSuggestion(field); - } } } else // just heading @@ -643,10 +731,11 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer if (rowList != null) rowList.add(row); - loadToolbarButtons(); + if (!update) + loadToolbarButtons(); //create tree - if (gridTab.isTreeTab() && treePanel != null) { + if (!update && gridTab.isTreeTab() && treePanel != null) { int AD_Tree_ID = Env.getContextAsInt (Env.getCtx(), getWindowNo(), "AD_Tree_ID", true); int AD_Tree_ID_Default = MTree.getDefaultAD_Tree_ID (Env.getAD_Client_ID(Env.getCtx()), gridTab.getKeyColumnName()); @@ -659,10 +748,18 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer } } - if (!gridTab.isSingleRow() && !isGridView()) + if (!update && !gridTab.isSingleRow() && !isGridView()) switchRowPresentation(); } + private WEditor findEditor(GridField field) { + for(WEditor editor : editors) { + if (editor.getGridField() == field) + return editor; + } + return null; + } + private void loadToolbarButtons() { //get extra toolbar process buttons MToolBarButton[] mToolbarButtons = MToolBarButton.getProcessButtonOfTab(gridTab.getAD_Tab_ID(), null); @@ -1027,7 +1124,8 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer } else { if (activate) { formContainer.setVisible(activate); - focusToFirstEditor(); + if (!isMobile()) + focusToFirstEditor(); } } @@ -1163,6 +1261,8 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer } private boolean isOpenDetailPane() { + if (isMobile()) + return false; boolean open = true; int windowId = getGridTab().getAD_Window_ID(); int adTabId = getGridTab().getAD_Tab_ID(); @@ -1517,7 +1617,7 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer @Override public void focus() { - if (form.isVisible()) + if (form.isVisible() && !isMobile()) this.focusToFirstEditor(true); else listPanel.focus(); @@ -1786,7 +1886,32 @@ DataStatusListener, IADTabpanel, IdSpace, IFieldEditorContainer } super.onPageDetached(page); } + + protected void onClientInfo() { + if (!uiCreated || gridTab == null) return; + int numCols=gridTab.getNumColumns(); + if (numCols <= 0) { + numCols=6; + } + if (ClientInfo.maxWidth(ClientInfo.EXTRA_SMALL_WIDTH-1)) { + if (numCols > 3) { + numCols=3; + } + } else if (ClientInfo.maxWidth(ClientInfo.MEDIUM_WIDTH-1)) { + if (numCols > 6) { + numCols=6; + } + } + if (numCols > 0 && numCols != numberOfFormColumns) { + createUI(true); + dynamicDisplay(0); + } + }; + + protected boolean isMobile() { + return ClientInfo.isMobile(); + } @Override public void editorTraverse(Callback editorTaverseCallback) { editorTraverse(editorTaverseCallback, editors); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADWindowToolbar.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADWindowToolbar.java index b8a8c26a4b..0b920de0af 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADWindowToolbar.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/ADWindowToolbar.java @@ -26,6 +26,7 @@ import java.util.Map; import java.util.logging.Level; import org.adempiere.base.IServiceHolder; +import org.adempiere.webui.ClientInfo; import org.adempiere.webui.LayoutUtils; import org.adempiere.webui.action.Actions; import org.adempiere.webui.action.IAction; @@ -50,11 +51,15 @@ import org.zkoss.zk.au.out.AuScript; import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.Executions; import org.zkoss.zk.ui.Page; +import org.zkoss.zk.ui.event.AfterSizeEvent; import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.event.Events; import org.zkoss.zk.ui.event.KeyEvent; +import org.zkoss.zk.ui.event.OpenEvent; import org.zkoss.zk.ui.util.Clients; +import org.zkoss.zul.A; +import org.zkoss.zul.Popup; import org.zkoss.zul.Separator; import org.zkoss.zul.Space; import org.zkoss.zul.Toolbarbutton; @@ -132,6 +137,14 @@ public class ADWindowToolbar extends FToolbar implements EventListener private KeyEvent prevKeyEvent; + private A overflowButton; + + private ArrayList overflows; + + private Popup overflowPopup; + + private int prevWidth; + /** Last Modifier of Action Event */ // public int lastModifiers; // @@ -144,6 +157,9 @@ public class ADWindowToolbar extends FToolbar implements EventListener public ADWindowToolbar(int windowNo) { setWindowNo(windowNo); init(); + if (ClientInfo.isMobile()) { + mobileInit(); + } } private void init() @@ -673,6 +689,7 @@ public class ADWindowToolbar extends FToolbar implements EventListener } private boolean ToolBarMenuRestictionLoaded = false; + public void updateToolbarAccess(int xAD_Window_ID) { if (ToolBarMenuRestictionLoaded) return; @@ -783,4 +800,112 @@ public class ADWindowToolbar extends FToolbar implements EventListener SessionManager.getSessionApplication().getKeylistener().addEventListener(Events.ON_CTRL_KEY, this); } } + + private void mobileInit() { + LayoutUtils.addSclass("mobile", this); + addEventListener("onOverflowButton", evt -> onOverflowButton(evt)); + this.setWidgetOverride("toolbarScrollable", "function (wgt) {\n" + + " var total = jq(wgt.$n()).width();\n" + + " var w = wgt.firstChild;\n" + + "\n" + + " // make sure all images are loaded.\n" + + " if (zUtl.isImageLoading()) {\n" + + " var f = arguments.callee;\n" + + " setTimeout(function () {\n" + + " return f(wgt);\n" + + " }, 20);\n" + + " return;\n" + + " }\n" + + " for (; w; w = w.nextSibling) {\n" + + " total -= jq(w.$n()).outerWidth(true);\n" + + " if (total < 0 && w.className == 'zul.wgt.Toolbarbutton') {\n" + + " break;\n" + + " }\n" + + " }\n" + + " if (w) {\n" + + " var event = new zk.Event(wgt, 'onOverflowButton', w.uuid, {toServer: true}); \n" + + " zAu.send(event); \n" + + " }\n" + + "}"); + addEventListener(Events.ON_AFTER_SIZE, (AfterSizeEvent evt) -> onAfterSize(evt)); + + } + + private void onAfterSize(AfterSizeEvent evt) { + int width = evt.getWidth(); + if (width != prevWidth) { + prevWidth = width; + if (overflowButton != null) + overflowButton.detach(); + if (overflowPopup != null) + overflowPopup.detach(); + if (overflows != null) { + for (ToolBarButton btn : overflows) { + appendChild(btn); + } + overflows = null; + } + Events.postEvent("onPostAfterSize", this, null); + } + } + + private void onOverflowButton(Event evt) { + overflows = new ArrayList<>(); + String uuid = (String) evt.getData(); + boolean overflowStarted = false; + for(Component comp : getChildren()) { + if (comp instanceof ToolBarButton) { + if (overflowStarted) { + overflows.add((ToolBarButton) comp); + } else if (comp.getUuid().equals(uuid)) { + overflows.add((ToolBarButton) comp); + overflowStarted = true; + } + } + } + if (overflows.size() > 0) { + overflowButton = new A(); + overflowButton.setIconSclass("z-icon-angle-double-down"); + overflowButton.setStyle("position: absolute; right: 2px; bottom: 6px; font-size: 12px; font-weight: 500;"); + appendChild(overflowButton); + overflowPopup = new Popup(); + overflowPopup.addEventListener(Events.ON_OPEN, (OpenEvent oe) -> { + if (!oe.isOpen()) { + overflowPopup.setAttribute("popup.close", System.currentTimeMillis()); + } + }); + appendChild(overflowPopup); + for(ToolBarButton btn : overflows) { + overflowPopup.appendChild(btn); + } + overflowButton.addEventListener(Events.ON_CLICK, e -> { + Long ts = (Long) overflowPopup.removeAttribute("popup.close"); + if (ts != null) { + if (System.currentTimeMillis() - ts.longValue() < 500) { + return; + } + } + overflowPopup.open(overflowButton, "after_end"); + }); + + int cnt = 0; + for(Component c : getChildren()) { + if (c instanceof ToolBarButton) + cnt++; + } + if (overflows.size() >= cnt) { + String script = "var e = jq('#" + getUuid() + "');"; + script = script + "var b=zk.Widget.$('#" + overflowPopup.getUuid() + "'); "; + script = script + "b.setWidth(e.css('width'));"; + Clients.evalJavaScript(script); + } else { + overflowPopup.setWidth(null); + } + } + } + + public void onPostAfterSize() { + String script = "var w = zk.Widget.$('#" + getUuid() + "'); w.toolbarScrollable(w);"; + Clients.evalJavaScript(script); + } } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/AbstractADWindowContent.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/AbstractADWindowContent.java index 6d9702c160..d42c6e953e 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/AbstractADWindowContent.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/AbstractADWindowContent.java @@ -34,6 +34,7 @@ import java.util.logging.Level; import org.adempiere.util.Callback; import org.adempiere.webui.AdempiereIdGenerator; import org.adempiere.webui.AdempiereWebUI; +import org.adempiere.webui.ClientInfo; import org.adempiere.webui.LayoutUtils; import org.adempiere.webui.WArchive; import org.adempiere.webui.WRequest; @@ -758,7 +759,10 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements findWindow.setBorder("none"); findWindow.setStyle("position: absolute; border-bottom: 2px solid #484848; padding: 2px; background-color: #fff;"); ZKUpdateUtil.setWidth(findWindow, "100%"); - ZKUpdateUtil.setHeight(findWindow, "60%"); + if (ClientInfo.maxHeight(ClientInfo.MEDIUM_HEIGHT-1)) + ZKUpdateUtil.setHeight(findWindow, "100%"); + else + ZKUpdateUtil.setHeight(findWindow, "60%"); findWindow.setZindex(1000); findWindow.setSizable(false); findWindow.setContentStyle("background-color: #fff; width: 99%; margin: auto;"); @@ -3039,8 +3043,8 @@ public abstract class AbstractADWindowContent extends AbstractUIPart implements onRefresh(true, false); } }); - showBusyMask(form); - LayoutUtils.openOverlappedWindow(getComponent(), form, "middle_center"); + form.setPage(getComponent().getPage()); + form.doHighlighted(); form.focus(); } else { diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/GridView.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/GridView.java index 3827db8631..25b29ba933 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/GridView.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/adwindow/GridView.java @@ -26,7 +26,7 @@ import org.adempiere.base.Core; import org.adempiere.model.MTabCustomization; import org.adempiere.util.Callback; import org.adempiere.util.GridRowCtx; -import org.adempiere.webui.apps.AEnv; +import org.adempiere.webui.ClientInfo; import org.adempiere.webui.component.Checkbox; import org.adempiere.webui.component.Columns; import org.adempiere.webui.component.EditorBox; @@ -83,6 +83,8 @@ public class GridView extends Vbox implements EventListener, IdSpace, IFi private static final int DEFAULT_DETAIL_PAGE_SIZE = 10; + private static final int DEFAULT_MOBILE_PAGE_SIZE = 20; + private static final int DEFAULT_PAGE_SIZE = 20; private static final int MIN_COLUMN_WIDTH = 100; @@ -158,10 +160,14 @@ public class GridView extends Vbox implements EventListener, IdSpace, IFi ZKUpdateUtil.setVflex(gridFooter, "0"); //default paging size - if (AEnv.isTablet()) + if (ClientInfo.isMobile()) { - //anything more than 20 is very slow on a tablet - pageSize = 10; + //Shoud be <= 20 on mobile + pageSize = MSysConfig.getIntValue(MSysConfig.ZK_MOBILE_PAGING_SIZE, DEFAULT_MOBILE_PAGE_SIZE, Env.getAD_Client_ID(Env.getCtx())); + String limit = Library.getProperty(CustomGridDataLoader.GRID_DATA_LOADER_LIMIT); + if (limit == null || !(limit.equals(Integer.toString(pageSize)))) { + Library.setProperty(CustomGridDataLoader.GRID_DATA_LOADER_LIMIT, Integer.toString(pageSize)); + } } else { @@ -173,7 +179,10 @@ public class GridView extends Vbox implements EventListener, IdSpace, IFi } //default true for better UI experience - modeless = MSysConfig.getBooleanValue(MSysConfig.ZK_GRID_EDIT_MODELESS, true); + if (ClientInfo.isMobile()) + modeless = MSysConfig.getBooleanValue(MSysConfig.ZK_GRID_MOBILE_EDIT_MODELESS, false); + else + modeless = MSysConfig.getBooleanValue(MSysConfig.ZK_GRID_EDIT_MODELESS, true); appendChild(listbox); appendChild(gridFooter); @@ -294,10 +303,16 @@ public class GridView extends Vbox implements EventListener, IdSpace, IFi } else { ArrayList gridFieldList = new ArrayList(); + //limit number of columns on mobile for better performance + int max = 0; + if (ClientInfo.isMobile()) + max = MSysConfig.getIntValue(MSysConfig.ZK_GRID_MOBILE_MAX_COLUMNS, 10, Env.getAD_Client_ID(Env.getCtx())); for(GridField field:tmpFields){ if(field.isDisplayedGrid() && !field.isToolbarOnlyButton()) { gridFieldList.add(field); } + if (max > 0 && gridFieldList.size() >= max) + break; } Collections.sort(gridFieldList, new Comparator() { @@ -458,7 +473,7 @@ public class GridView extends Vbox implements EventListener, IdSpace, IFi Columns columns = new Columns(); //frozen not working well on tablet devices yet - if (!AEnv.isTablet()) + if (!ClientInfo.isMobile()) { Frozen frozen = new Frozen(); //freeze selection and indicator column diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/AEnv.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/AEnv.java index 552dfe0039..7293618ce9 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/AEnv.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/AEnv.java @@ -34,9 +34,9 @@ import java.util.logging.Level; import javax.servlet.ServletRequest; +import org.adempiere.webui.ClientInfo; import org.adempiere.webui.adwindow.ADWindow; import org.adempiere.webui.component.Window; -import org.adempiere.webui.desktop.IDesktop; import org.adempiere.webui.editor.WTableDirEditor; import org.adempiere.webui.info.InfoWindow; import org.adempiere.webui.session.SessionManager; @@ -762,11 +762,11 @@ public final class AEnv } /** + * @deprecated replace by ClientInfo.isMobile() * @return true if running on a tablet */ public static boolean isTablet() { - IDesktop appDesktop = SessionManager.getAppDesktop(); - return appDesktop != null ? appDesktop.getClientInfo().tablet : false; + return ClientInfo.isMobile(); } /** diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/AbstractProcessDialog.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/AbstractProcessDialog.java index 99dea34eb2..36ee50297e 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/AbstractProcessDialog.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/AbstractProcessDialog.java @@ -29,6 +29,7 @@ import org.adempiere.util.Callback; import org.adempiere.util.ContextRunnable; import org.adempiere.util.IProcessUI; import org.adempiere.util.ServerContext; +import org.adempiere.webui.LayoutUtils; import org.adempiere.webui.component.Button; import org.adempiere.webui.component.Checkbox; import org.adempiere.webui.component.Column; @@ -398,8 +399,9 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI return;//if not a report not need show this pannel // option control - HtmlBasedComponent reportOptionLayout = new Hlayout(); + Hlayout reportOptionLayout = new Hlayout(); reportOptionLayout.setSclass("report-option-container"); + reportOptionLayout.setValign("middle"); bottomParameterLayout.appendChild(reportOptionLayout); freportType = new Listbox(); @@ -438,7 +440,7 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI } protected void savePrameterLayout(HtmlBasedComponent bottomParameterLayout) { - HtmlBasedComponent savePrameterLayout = new Div(); + HtmlBasedComponent savePrameterLayout = new Hlayout(); savePrameterLayout.setSclass("save-parameter-container"); bottomParameterLayout.appendChild(savePrameterLayout); @@ -455,6 +457,9 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI bDelete.setEnabled(false); bDelete.addActionListener(this); savePrameterLayout.appendChild(bDelete); + + LayoutUtils.addSclass("btn-small", bSave); + LayoutUtils.addSclass("btn-small", bDelete); querySaved(); } @@ -483,6 +488,7 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI bOK.setId("Ok"); bOK.addEventListener(Events.ON_CLICK, this); confParaPanel.appendChild(bOK); + confParaPanel.appendChild(new Space()); bCancel = ButtonFactory.createNamedButton(ConfirmPanel.A_CANCEL, true, true); bCancel.setId("Cancel"); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/FeedbackRequestWindow.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/FeedbackRequestWindow.java index aade1840b9..0f915c1812 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/FeedbackRequestWindow.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/FeedbackRequestWindow.java @@ -59,8 +59,8 @@ import org.zkoss.zk.ui.event.Events; import org.zkoss.zk.ui.event.UploadEvent; import org.zkoss.zk.ui.util.Clients; import org.zkoss.zul.Borderlayout; +import org.zkoss.zul.Center; import org.zkoss.zul.Div; -import org.zkoss.zul.North; import org.zkoss.zul.South; /** @@ -90,11 +90,20 @@ public class FeedbackRequestWindow extends Window implements EventListener { + ZKUpdateUtil.setCSSHeight(this); + ZKUpdateUtil.setCSSWidth(this); + }); + } + this.setSclass("popup-dialog feedback-request-dialog"); this.setBorder("normal"); this.setShadow(true); this.setClosable(true); + this.setMaximizable(true); boolean readOnly = !MRole.getDefault().canUpdate( Env.getAD_Client_ID(Env.getCtx()), Env.getAD_Org_ID(Env.getCtx()), @@ -144,7 +153,7 @@ public class FeedbackRequestWindow extends Window implements EventListener { bandbox = new Bandbox(); bandbox.setSclass("global-search-box"); appendChild(bandbox); - ZKUpdateUtil.setWidth(bandbox, "100%"); +// ZKUpdateUtil.setWidth(bandbox, "100%"); bandbox.setAutodrop(true); bandbox.addEventListener(Events.ON_CHANGING, this); bandbox.addEventListener(Events.ON_CHANGE, this); @@ -84,7 +85,7 @@ public class GlobalSearch extends Div implements EventListener { bandbox.addEventListener(Events.ON_CTRL_KEY, this); Bandpopup popup = new Bandpopup(); - ZKUpdateUtil.setHeight(popup, "500px"); + ZKUpdateUtil.setWindowHeightX(popup, ClientInfo.get().desktopHeight-50); bandbox.appendChild(popup); tabbox = new Tabbox(); @@ -209,4 +210,14 @@ public class GlobalSearch extends Div implements EventListener { super.onPageAttached(newpage, oldpage); Events.echoEvent(ON_CREATE_ECHO, this, null); } + + public void closePopup() { + if (bandbox != null) { + bandbox.close(); + } + } + + public void onClientInfo() { + ZKUpdateUtil.setWindowHeightX(bandbox.getDropdown(), ClientInfo.get().desktopHeight-50); + } } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WAllocation.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WAllocation.java index e6f5b2bed1..4c4fe21f15 100755 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WAllocation.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WAllocation.java @@ -25,8 +25,12 @@ import java.util.Calendar; import java.util.Vector; import java.util.logging.Level; +import org.adempiere.webui.ClientInfo; +import org.adempiere.webui.LayoutUtils; import org.adempiere.webui.component.Button; import org.adempiere.webui.component.Checkbox; +import org.adempiere.webui.component.Column; +import org.adempiere.webui.component.Columns; import org.adempiere.webui.component.DocumentLink; import org.adempiere.webui.component.Grid; import org.adempiere.webui.component.GridFactory; @@ -64,12 +68,13 @@ import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zul.Borderlayout; import org.zkoss.zul.Center; +import org.zkoss.zul.Div; import org.zkoss.zul.Hbox; import org.zkoss.zul.Hlayout; import org.zkoss.zul.North; -import org.zkoss.zul.Separator; import org.zkoss.zul.South; -import org.zkoss.zul.Space; + +import static org.adempiere.webui.ClientInfo.*; /** * Allocation Form @@ -84,7 +89,7 @@ public class WAllocation extends Allocation { private CustomForm form = new CustomForm(); - + /** * Initialize Panel * @param WindowNo window @@ -98,20 +103,23 @@ public class WAllocation extends Allocation super.dynInit(); dynInit(); zkInit(); - calculate(); - southPanel.appendChild(new Separator()); - southPanel.appendChild(statusBar); + calculate(); } catch(Exception e) { log.log(Level.SEVERE, "", e); } + + if (ClientInfo.isMobile()) + { + ClientInfo.onClientInfo(form, this::onClientInfo); + } } // init // private Borderlayout mainLayout = new Borderlayout(); private Panel parameterPanel = new Panel(); - private Panel allocationPanel = new Panel(); + private Panel allocationPanel = new Panel(); //footer private Grid parameterLayout = GridFactory.newGridLayout(); private Label bpartnerLabel = new Label(); private WSearchEditor bpartnerSearch = null; @@ -145,9 +153,8 @@ public class WAllocation extends Allocation private Checkbox autoWriteOff = new Checkbox(); private Label organizationLabel = new Label(); private WTableDirEditor organizationPick; + private int noOfColumn; - private Panel southPanel = new Panel(); - /** * Static Init * @throws Exception @@ -155,9 +162,16 @@ public class WAllocation extends Allocation private void zkInit() throws Exception { // - form.appendChild(mainLayout); - ZKUpdateUtil.setWidth(mainLayout, "99%"); - ZKUpdateUtil.setHeight(mainLayout, "100%"); + Div div = new Div(); + div.setStyle("height: 100%; width: 100%; overflow: auto;"); + div.appendChild(mainLayout); + form.appendChild(div); + ZKUpdateUtil.setWidth(mainLayout, "100%"); + + ///// + mainLayout.setStyle("min-height: 600px"); + ///// + dateLabel.setText(Msg.getMsg(Env.getCtx(), "Date")); autoWriteOff.setSelected(false); autoWriteOff.setText(Msg.getMsg(Env.getCtx(), "AutoWriteOff", true)); @@ -190,108 +204,71 @@ public class WAllocation extends Allocation organizationLabel.setText(Msg.translate(Env.getCtx(), "AD_Org_ID")); + // parameters layout North north = new North(); - north.setStyle("border: none"); + north.setBorder("none"); + north.setSplittable(true); + north.setCollapsible(true); mainLayout.appendChild(north); north.appendChild(parameterPanel); - Rows rows = null; - Row row = null; - - ZKUpdateUtil.setWidth(parameterLayout, "80%"); - rows = parameterLayout.newRows(); - row = rows.newRow(); - row.appendCellChild(bpartnerLabel.rightAlign()); - ZKUpdateUtil.setHflex(bpartnerSearch.getComponent(), "true"); - row.appendCellChild(bpartnerSearch.getComponent(),2); - bpartnerSearch.showMenu(); - Hbox box = new Hbox(); - box.appendChild(dateLabel.rightAlign()); - box.appendChild(dateField.getComponent()); - row.appendCellChild(box); - row.appendCellChild(organizationLabel.rightAlign()); - ZKUpdateUtil.setHflex(organizationPick.getComponent(), "true"); - row.appendCellChild(organizationPick.getComponent(),1); - organizationPick.showMenu(); - - row = rows.newRow(); - row.appendCellChild(currencyLabel.rightAlign(),1); - ZKUpdateUtil.setHflex(currencyPick.getComponent(), "true"); - row.appendCellChild(currencyPick.getComponent(),1); - currencyPick.showMenu(); - row.appendCellChild(multiCurrency,1); - row.appendCellChild(autoWriteOff,2); - row.appendCellChild(new Space(),1); - - South south = new South(); - south.setStyle("border: none"); - mainLayout.appendChild(south); - south.appendChild(southPanel); - southPanel.appendChild(allocationPanel); - allocationPanel.appendChild(allocationLayout); - ZKUpdateUtil.setHflex(allocationLayout, "min"); - rows = allocationLayout.newRows(); - row = rows.newRow(); - row.appendCellChild(differenceLabel.rightAlign()); - row.appendCellChild(allocCurrencyLabel.rightAlign()); - ZKUpdateUtil.setHflex(differenceField, "true"); - row.appendCellChild(differenceField); - row.appendCellChild(chargeLabel.rightAlign()); - ZKUpdateUtil.setHflex(chargePick.getComponent(), "true"); - row.appendCellChild(chargePick.getComponent()); - row.appendCellChild(DocTypeLabel.rightAlign()); - chargePick.showMenu(); - ZKUpdateUtil.setHflex(DocTypePick.getComponent(), "true"); - row.appendCellChild(DocTypePick.getComponent()); - DocTypePick.showMenu(); - ZKUpdateUtil.setHflex(allocateButton, "true"); - row.appendCellChild(allocateButton); - row.appendCellChild(refreshButton); + layoutParameterAndSummary(); + // payment layout paymentPanel.appendChild(paymentLayout); ZKUpdateUtil.setWidth(paymentPanel, "100%"); - ZKUpdateUtil.setHeight(paymentPanel, "100%"); ZKUpdateUtil.setWidth(paymentLayout, "100%"); - ZKUpdateUtil.setHeight(paymentLayout, "100%"); - paymentLayout.setStyle("border: none"); + ZKUpdateUtil.setVflex(paymentPanel, "1"); + ZKUpdateUtil.setVflex(paymentLayout, "1"); + // invoice layout invoicePanel.appendChild(invoiceLayout); ZKUpdateUtil.setWidth(invoicePanel, "100%"); - ZKUpdateUtil.setHeight(invoicePanel, "100%"); ZKUpdateUtil.setWidth(invoiceLayout, "100%"); - ZKUpdateUtil.setHeight(invoiceLayout, "100%"); - invoiceLayout.setStyle("border: none"); + ZKUpdateUtil.setVflex(invoicePanel, "1"); + ZKUpdateUtil.setVflex(invoiceLayout, "1"); + // payment layout north - label north = new North(); - north.setStyle("border: none"); + north.setBorder("none"); paymentLayout.appendChild(north); north.appendChild(paymentLabel); - south = new South(); - south.setStyle("border: none"); + ZKUpdateUtil.setVflex(paymentLabel, "min"); + // payment layout south - sum + South south = new South(); + south.setBorder("none"); paymentLayout.appendChild(south); south.appendChild(paymentInfo.rightAlign()); + ZKUpdateUtil.setVflex(paymentInfo, "min"); + //payment layout center - payment list Center center = new Center(); paymentLayout.appendChild(center); center.appendChild(paymentTable); - ZKUpdateUtil.setWidth(paymentTable, "99%"); - //ZKUpdateUtil.setHeight(paymentTable, "99%"); - center.setStyle("border: none"); + ZKUpdateUtil.setWidth(paymentTable, "100%"); + ZKUpdateUtil.setVflex(paymentTable, "1"); + center.setBorder("none"); + // invoice layout north - label north = new North(); - north.setStyle("border: none"); + north.setBorder("none"); invoiceLayout.appendChild(north); north.appendChild(invoiceLabel); + ZKUpdateUtil.setVflex(invoiceLabel, "min"); + // invoice layout south - sum south = new South(); - south.setStyle("border: none"); + south.setBorder("none"); invoiceLayout.appendChild(south); south.appendChild(invoiceInfo.rightAlign()); + ZKUpdateUtil.setVflex(invoiceInfo, "min"); + // invoice layout center - invoice list center = new Center(); invoiceLayout.appendChild(center); center.appendChild(invoiceTable); - ZKUpdateUtil.setWidth(invoiceTable, "99%"); - //ZKUpdateUtil.setHeight(invoiceTable, "99%"); + ZKUpdateUtil.setWidth(invoiceTable, "100%"); + ZKUpdateUtil.setVflex(invoiceTable, "1"); center.setStyle("border: none"); - // + + // mainlayout center - payment + invoice center = new Center(); mainLayout.appendChild(center); center.appendChild(infoPanel); @@ -300,22 +277,155 @@ public class WAllocation extends Allocation infoPanel.setStyle("border: none"); ZKUpdateUtil.setWidth(infoPanel, "100%"); - ZKUpdateUtil.setHeight(infoPanel, "100%"); + // north of mainlayout center - payment north = new North(); - north.setStyle("border: none"); - ZKUpdateUtil.setHeight(north, "49%"); + north.setBorder("none"); infoPanel.appendChild(north); north.appendChild(paymentPanel); + north.setAutoscroll(true); north.setSplittable(true); + north.setSize("50%"); + north.setCollapsible(true); + + // center of mainlayout center - invoice center = new Center(); - center.setStyle("border: none"); + center.setBorder("none"); infoPanel.appendChild(center); center.appendChild(invoicePanel); - ZKUpdateUtil.setHflex(invoicePanel, "1"); - ZKUpdateUtil.setVflex(invoicePanel, "1"); + center.setAutoscroll(true); + infoPanel.setStyle("min-height: 300px;"); } // jbInit + protected void layoutParameterAndSummary() { + Rows rows = null; + Row row = null; + + setupParameterColumns(); + + rows = parameterLayout.newRows(); + row = rows.newRow(); + row.appendCellChild(bpartnerLabel.rightAlign()); + ZKUpdateUtil.setHflex(bpartnerSearch.getComponent(), "true"); + row.appendCellChild(bpartnerSearch.getComponent(),1); + bpartnerSearch.showMenu(); + row.appendChild(dateLabel.rightAlign()); + row.appendChild(dateField.getComponent()); + + row.appendCellChild(organizationLabel.rightAlign()); + ZKUpdateUtil.setHflex(organizationPick.getComponent(), "true"); + row.appendCellChild(organizationPick.getComponent(),1); + organizationPick.showMenu(); + + row = rows.newRow(); + row.appendCellChild(currencyLabel.rightAlign(),1); + ZKUpdateUtil.setHflex(currencyPick.getComponent(), "true"); + row.appendCellChild(currencyPick.getComponent(),1); + currencyPick.showMenu(); + + Hbox cbox = new Hbox(); + cbox.setWidth("100%"); + if (noOfColumn == 6) + cbox.setPack("center"); + else + cbox.setPack("end"); + cbox.appendChild(multiCurrency); + cbox.appendChild(autoWriteOff); + row.appendCellChild(cbox, 2); + if (noOfColumn < 6) + LayoutUtils.compactTo(parameterLayout, noOfColumn); + else + LayoutUtils.expandTo(parameterLayout, noOfColumn, true); + + // footer/allocations layout + South south = new South(); + south.setBorder("none"); + mainLayout.appendChild(south); + south.appendChild(allocationPanel); + allocationPanel.appendChild(allocationLayout); + allocationPanel.appendChild(statusBar); + ZKUpdateUtil.setWidth(allocationLayout, "100%"); + ZKUpdateUtil.setHflex(allocationPanel, "1"); + ZKUpdateUtil.setVflex(allocationPanel, "min"); + ZKUpdateUtil.setVflex(allocationLayout, "min"); + ZKUpdateUtil.setVflex(statusBar, "min"); + ZKUpdateUtil.setVflex(south, "min"); + rows = allocationLayout.newRows(); + row = rows.newRow(); + if (maxWidth(SMALL_WIDTH-1)) + { + Hbox box = new Hbox(); + box.setWidth("100%"); + box.setPack("end"); + box.appendChild(differenceLabel.rightAlign()); + box.appendChild(allocCurrencyLabel.rightAlign()); + row.appendCellChild(box); + } + else + { + Hlayout box = new Hlayout(); + box.setStyle("float: right"); + box.appendChild(differenceLabel.rightAlign()); + box.appendChild(allocCurrencyLabel.rightAlign()); + row.appendCellChild(box); + } + ZKUpdateUtil.setHflex(differenceField, "true"); + row.appendCellChild(differenceField); + if (maxWidth(SMALL_WIDTH-1)) + row = rows.newRow(); + row.appendCellChild(chargeLabel.rightAlign()); + ZKUpdateUtil.setHflex(chargePick.getComponent(), "true"); + row.appendCellChild(chargePick.getComponent()); + if (maxWidth(SMALL_WIDTH-1)) + row = rows.newRow(); + row.appendCellChild(DocTypeLabel.rightAlign()); + chargePick.showMenu(); + ZKUpdateUtil.setHflex(DocTypePick.getComponent(), "true"); + row.appendCellChild(DocTypePick.getComponent()); + DocTypePick.showMenu(); + if (maxWidth(SMALL_WIDTH-1)) + { + row = rows.newRow(); + Hbox box = new Hbox(); + box.setWidth("100%"); + box.setPack("end"); + box.appendChild(allocateButton); + box.appendChild(refreshButton); + row.appendCellChild(box, 2); + } + else + { + Hbox box = new Hbox(); + box.setPack("end"); + box.appendChild(allocateButton); + box.appendChild(refreshButton); + ZKUpdateUtil.setHflex(box, "1"); + row.appendCellChild(box, 2); + } + } + + protected void setupParameterColumns() { + noOfColumn = 6; + if (maxWidth(MEDIUM_WIDTH-1)) + { + if (maxWidth(SMALL_WIDTH-1)) + noOfColumn = 2; + else + noOfColumn = 4; + } + if (noOfColumn == 2) + { + Columns columns = new Columns(); + Column column = new Column(); + column.setWidth("35%"); + columns.appendChild(column); + column = new Column(); + column.setWidth("65%"); + columns.appendChild(column); + parameterLayout.appendChild(columns); + } + } + /** * Dynamic Init (prepare dynamic fields) * @throws Exception if Lookups cannot be initialized @@ -373,6 +483,36 @@ public class WAllocation extends Allocation } // dynInit + protected void onClientInfo() + { + if (ClientInfo.isMobile() && form.getPage() != null) + { + if (noOfColumn > 0 && parameterLayout.getRows() != null) + { + int t = 6; + if (maxWidth(MEDIUM_WIDTH-1)) + { + if (maxWidth(SMALL_WIDTH-1)) + t = 2; + else + t = 4; + } + if (t != noOfColumn) + { + parameterLayout.getRows().detach(); + if (parameterLayout.getColumns() != null) + parameterLayout.getColumns().detach(); + if (mainLayout.getSouth() != null) + mainLayout.getSouth().detach(); + if (allocationLayout.getRows() != null) + allocationLayout.getRows().detach(); + layoutParameterAndSummary(); + form.invalidate(); + } + } + } + } + /************************************************************************** * Action Listener. * - MultiCurrency diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WArchiveViewer.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WArchiveViewer.java index 67e88befad..ecd698b0ad 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WArchiveViewer.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WArchiveViewer.java @@ -27,6 +27,7 @@ import java.util.Date; import java.util.logging.Level; import org.adempiere.util.Callback; +import org.adempiere.webui.ClientInfo; import org.adempiere.webui.component.Button; import org.adempiere.webui.component.Checkbox; import org.adempiere.webui.component.Column; @@ -47,6 +48,7 @@ import org.adempiere.webui.component.Tabpanel; import org.adempiere.webui.component.Tabpanels; import org.adempiere.webui.component.Tabs; import org.adempiere.webui.component.Textbox; +import org.adempiere.webui.component.ToolBarButton; import org.adempiere.webui.editor.WSearchEditor; import org.adempiere.webui.panel.ADForm; import org.adempiere.webui.panel.CustomForm; @@ -65,14 +67,20 @@ import org.compiere.util.KeyNamePair; import org.compiere.util.Msg; import org.compiere.util.Util; import org.zkoss.util.media.AMedia; +import org.zkoss.util.media.Media; import org.zkoss.zk.ui.Page; import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.event.Events; +import org.zkoss.zk.ui.event.OpenEvent; +import org.zkoss.zk.ui.ext.render.DynamicMedia; import org.zkoss.zul.Cell; import org.zkoss.zul.Hbox; import org.zkoss.zul.Iframe; +import org.zkoss.zul.Popup; import org.zkoss.zul.Space; +import org.zkoss.zul.impl.Utils; +import org.zkoss.zul.impl.XulElement; /** * Archive Viewer @@ -83,7 +91,52 @@ import org.zkoss.zul.Space; public class WArchiveViewer extends Archive implements IFormController, EventListener { - private CustomForm form = new CustomForm(); + private static final String ONCLOSE_TIMESTAMP_ATTR = "onclose.timestamp"; + + private class WArchiveViewerForm extends CustomForm + { + /** + * generated serial id + */ + private static final long serialVersionUID = 4919349386488325L; + //-- ComponentCtrl --// + public Object getExtraCtrl() { + return new ExtraCtrl(); + } + /** A utility class to implement {@link #getExtraCtrl}. + * It is used only by component developers. + */ + protected class ExtraCtrl extends XulElement.ExtraCtrl + implements DynamicMedia { + //-- DynamicMedia --// + public Media getMedia(String pathInfo) { + return media; + } + } + + @Override + public void onPageAttached(Page newpage, Page oldpage) { + super.onPageAttached(newpage, oldpage); + if (newpage != null) { + try { + dynInit(); + jbInit(); + if (ClientInfo.isMobile()) { + if (media != null && iframe.getSrc() == null) { + String url = Utils.getDynamicMediaURI(form, mediaVersion, media.getName(), media.getFormat()); + String pdfJsUrl = "pdf.js/web/viewer.html?file="+url; + iframe.setSrc(pdfJsUrl); + } + } + } + catch(Exception e) + { + log.log(Level.SEVERE, "init", e); + } + } + } + }; + private CustomForm form; // private Vbox queryPanel = new Vbox(); private Checkbox reportField = new Checkbox(); @@ -131,29 +184,14 @@ public class WArchiveViewer extends Archive implements IFormController, EventLis private Button bRefresh = new Button(); private boolean showQuery = true; + private int mediaVersion = 0; + private AMedia media; + public WArchiveViewer() { log.info(""); - form = new CustomForm() { - private static final long serialVersionUID = 7226661630651936293L; - - @Override - public void onPageAttached(Page newpage, Page oldpage) { - super.onPageAttached(newpage, oldpage); - if (newpage != null) - try { - dynInit(); - jbInit(); - } - catch(Exception e) - { - log.log(Level.SEVERE, "init", e); - } - - } - - }; + form = new WArchiveViewerForm(); m_WindowNo = form.getWindowNo(); } @@ -185,10 +223,29 @@ public class WArchiveViewer extends Archive implements IFormController, EventLis Env.getCtx(), "C_BPartner_ID"), "", true, false, true); } // dynInit - private void reportViewer(byte[] data) - { - AMedia media = new AMedia("Archive Viewer", "pdf", "application/pdf", data); - iframe.setContent(media); + private void reportViewer(String name, byte[] data) + { + media = new AMedia(name + ".pdf", "pdf", "application/pdf", data); + if (ClientInfo.isMobile()) + { + mediaVersion ++; + if (form.getDesktop() == null) + { + iframe.setContent(null); + iframe.setSrc(null); + } + else + { + String url = Utils.getDynamicMediaURI(form, mediaVersion, media.getName(), media.getFormat()); + String pdfJsUrl = "pdf.js/web/viewer.html?file="+url; + iframe.setContent(null); + iframe.setSrc(pdfJsUrl); + } + } + else + { + iframe.setContent(media); + } iframe.invalidate(); } @@ -452,13 +509,44 @@ public class WArchiveViewer extends Archive implements IFormController, EventLis ZKUpdateUtil.setWidth(boxViewSeparator, "100%"); ZKUpdateUtil.setHeight(boxViewSeparator, "100%"); cell = new Cell(); - ZKUpdateUtil.setWidth(cell, "70%"); cell.appendChild(iframe); boxViewSeparator.appendChild(cell); - cell = new Cell(); - ZKUpdateUtil.setWidth(cell, "30%"); - cell.appendChild(gridView); - boxViewSeparator.appendChild(cell); + if (ClientInfo.maxWidth(ClientInfo.SMALL_WIDTH-1)) + { + ZKUpdateUtil.setHflex(cell, "1"); + cell = new Cell(); + ZKUpdateUtil.setHflex(cell, "min"); + ToolBarButton more = new ToolBarButton(); + more.setImage(ThemeManager.getThemeResource("images/expand-header.png")); + cell.appendChild(more); + boxViewSeparator.appendChild(cell); + Popup sidePopup = new Popup(); + sidePopup.setWidth("300px"); + sidePopup.setVflex("min"); + sidePopup.setStyle("max-height: 100%; overflow-y: auto;"); + sidePopup.addEventListener(Events.ON_OPEN, (OpenEvent evt) -> { + if (!evt.isOpen()) + sidePopup.setAttribute(ONCLOSE_TIMESTAMP_ATTR, System.currentTimeMillis()); + }); + tabViewPanel.appendChild(sidePopup); + sidePopup.appendChild(gridView); + more.addEventListener(Events.ON_CLICK, evt -> { + Long ts = (Long) sidePopup.removeAttribute(ONCLOSE_TIMESTAMP_ATTR); + if (ts != null) { + if ((System.currentTimeMillis()-ts.longValue()) < 500) + return; + } + sidePopup.open(more, "after_end"); + }); + } + else + { + ZKUpdateUtil.setWidth(cell, "70%"); + cell = new Cell(); + ZKUpdateUtil.setWidth(cell, "30%"); + cell.appendChild(gridView); + boxViewSeparator.appendChild(cell); + } tabViewPanel.appendChild(boxViewSeparator); tabs.appendChild(tabView); @@ -611,7 +699,7 @@ public class WArchiveViewer extends Archive implements IFormController, EventLis InputStream in = ar.getInputStream(); //pdfViewer.setScale(reportField.isSelected() ? 50 : 75); if (in != null) - reportViewer(ar.getBinaryData());//pdfViewer.loadPDF(in); + reportViewer(ar.getName(), ar.getBinaryData());//pdfViewer.loadPDF(in); else iframe.getChildren().clear();//pdfViewer.clearDocument(); } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WCharge.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WCharge.java index f58fb87066..30666baf5f 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WCharge.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WCharge.java @@ -228,6 +228,8 @@ public class WCharge extends Charge implements IFormController, EventListener, WTa { super(); this.form = createFrom; + + setSizable(true); + setMaximizable(true); + setBorder("normal"); + setSclass("create-from-form"); } protected void initForm() @@ -95,6 +102,10 @@ public class WCreateFromForm extends ADForm implements EventListener, WTa North north = new North(); contentPane.appendChild(north); north.appendChild(parameterPanel); + north.setAutoscroll(true); + north.setSplittable(true); + north.setCollapsible(true); + LayoutUtils.addSlideSclass(north); Center center = new Center(); contentPane.appendChild(center); @@ -115,12 +126,21 @@ public class WCreateFromForm extends ADForm implements EventListener, WTa southPanel.appendChild(new Separator()); southPanel.appendChild(statusBar); - ZKUpdateUtil.setWidth(this,"750px"); - ZKUpdateUtil.setHeight(this, "550px"); - setSizable(true); - setBorder("normal"); + if (!ThemeManager.isUseCSSForWindowSize()) + { + ZKUpdateUtil.setWindowWidthX(this, 750); + ZKUpdateUtil.setWindowHeightX(this, 550); + } + else + { + addCallback(AFTER_PAGE_ATTACHED, t -> { + ZKUpdateUtil.setCSSHeight(this); + ZKUpdateUtil.setCSSWidth(this); + }); + } + ZKUpdateUtil.setWidth(contentPane, "100%"); - ZKUpdateUtil.setHeight(contentPane, "100%"); + ZKUpdateUtil.setHeight(contentPane, "100%"); } public void onEvent(Event e) throws Exception @@ -270,5 +290,5 @@ public class WCreateFromForm extends ADForm implements EventListener, WTa if (visible && getProcessInfo() != null) form.initForm(); return ok; - } + } } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WCreateFromInvoiceUI.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WCreateFromInvoiceUI.java index 2ac307e58f..e0f7f91ada 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WCreateFromInvoiceUI.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WCreateFromInvoiceUI.java @@ -17,7 +17,11 @@ import java.util.ArrayList; import java.util.Vector; import java.util.logging.Level; +import org.adempiere.webui.ClientInfo; +import org.adempiere.webui.LayoutUtils; import org.adempiere.webui.apps.AEnv; +import org.adempiere.webui.component.Column; +import org.adempiere.webui.component.Columns; import org.adempiere.webui.component.Grid; import org.adempiere.webui.component.GridFactory; import org.adempiere.webui.component.Label; @@ -46,10 +50,9 @@ import org.compiere.util.DisplayType; import org.compiere.util.Env; import org.compiere.util.KeyNamePair; import org.compiere.util.Msg; +import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.EventListener; -import org.zkoss.zul.Borderlayout; -import org.zkoss.zul.Center; import org.zkoss.zul.Space; public class WCreateFromInvoiceUI extends CreateFromInvoice implements EventListener, ValueChangeListener @@ -99,6 +102,8 @@ public class WCreateFromInvoiceUI extends CreateFromInvoice implements EventList protected Label rmaLabel = new Label(); /** Combo box for selecting RMA document */ protected Listbox rmaField = ListboxFactory.newDropdownListbox(); + + private Grid parameterStdLayout; /** * Dynamic Init @@ -135,19 +140,16 @@ public class WCreateFromInvoiceUI extends CreateFromInvoice implements EventList shipmentLabel.setText(Msg.getElement(Env.getCtx(), "M_InOut_ID", isSOTrx)); rmaLabel.setText(Msg.translate(Env.getCtx(), "M_RMA_ID")); - Borderlayout parameterLayout = new Borderlayout(); - ZKUpdateUtil.setHeight(parameterLayout, "110px"); - ZKUpdateUtil.setWidth(parameterLayout, "100%"); Panel parameterPanel = window.getParameterPanel(); - parameterPanel.appendChild(parameterLayout); - Grid parameterStdLayout = GridFactory.newGridLayout(); + parameterStdLayout = GridFactory.newGridLayout(); Panel parameterStdPanel = new Panel(); parameterStdPanel.appendChild(parameterStdLayout); + + setupColumns(parameterStdLayout); - Center center = new Center(); - parameterLayout.appendChild(center); - center.appendChild(parameterStdPanel); + parameterPanel.appendChild(parameterStdPanel); + ZKUpdateUtil.setVflex(parameterStdLayout, "min"); Rows rows = (Rows) parameterStdLayout.newRows(); Row row = rows.newRow(); @@ -172,9 +174,46 @@ public class WCreateFromInvoiceUI extends CreateFromInvoice implements EventList row.appendChild(rmaLabel.rightAlign()); ZKUpdateUtil.setHflex(rmaField, "1"); row.appendChild(rmaField); + + if (ClientInfo.isMobile()) { + if (noOfParameterColumn == 2) + LayoutUtils.compactTo(parameterStdLayout, 2); + ClientInfo.onClientInfo(window, this::onClientInfo); + } + + hideEmptyRow(rows); + } + + private void hideEmptyRow(org.zkoss.zul.Rows rows) { + for(Component a : rows.getChildren()) { + Row row = (Row) a; + boolean visible = false; + for(Component b : row.getChildren()) { + if (b instanceof Space) + continue; + else if (!b.isVisible()) { + continue; + } else { + if (!b.getChildren().isEmpty()) { + for (Component c : b.getChildren()) { + if (c.isVisible()) { + visible = true; + break; + } + } + } else { + visible = true; + break; + } + } + } + row.setVisible(visible); + } } private boolean m_actionActive = false; + + private int noOfParameterColumn; /** * Action Listener @@ -388,4 +427,61 @@ public class WCreateFromInvoiceUI extends CreateFromInvoice implements EventList public Object getWindow() { return window; } + + protected void setupColumns(Grid parameterGrid) { + noOfParameterColumn = ClientInfo.maxWidth((ClientInfo.EXTRA_SMALL_WIDTH+ClientInfo.SMALL_WIDTH)/2) ? 2 : 4; + Columns columns = new Columns(); + parameterGrid.appendChild(columns); + if (ClientInfo.maxWidth((ClientInfo.EXTRA_SMALL_WIDTH+ClientInfo.SMALL_WIDTH)/2)) + { + Column column = new Column(); + ZKUpdateUtil.setWidth(column, "35%"); + columns.appendChild(column); + column = new Column(); + ZKUpdateUtil.setWidth(column, "65%"); + columns.appendChild(column); + } + else + { + Column column = new Column(); + columns.appendChild(column); + column = new Column(); + ZKUpdateUtil.setWidth(column, "15%"); + columns.appendChild(column); + ZKUpdateUtil.setWidth(column, "35%"); + column = new Column(); + ZKUpdateUtil.setWidth(column, "15%"); + columns.appendChild(column); + column = new Column(); + ZKUpdateUtil.setWidth(column, "35%"); + columns.appendChild(column); + } + } + + protected void onClientInfo() + { + if (ClientInfo.isMobile() && parameterStdLayout != null && parameterStdLayout.getRows() != null) + { + int nc = ClientInfo.maxWidth((ClientInfo.EXTRA_SMALL_WIDTH+ClientInfo.SMALL_WIDTH)/2) ? 2 : 4; + int cc = noOfParameterColumn; + if (nc == cc) + return; + + parameterStdLayout.getColumns().detach(); + setupColumns(parameterStdLayout); + if (cc > nc) + { + LayoutUtils.compactTo(parameterStdLayout, nc); + } + else + { + LayoutUtils.expandTo(parameterStdLayout, nc, false); + } + hideEmptyRow(parameterStdLayout.getRows()); + + ZKUpdateUtil.setCSSHeight(window); + ZKUpdateUtil.setCSSWidth(window); + window.invalidate(); + } + } } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WCreateFromRMAUI.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WCreateFromRMAUI.java index fc11fa07c7..c8ddb471fe 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WCreateFromRMAUI.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WCreateFromRMAUI.java @@ -16,6 +16,7 @@ package org.adempiere.webui.apps.form; import java.util.Vector; import java.util.logging.Level; +import org.adempiere.webui.ClientInfo; import org.adempiere.webui.apps.AEnv; import org.adempiere.webui.component.Grid; import org.adempiere.webui.component.GridFactory; @@ -40,8 +41,6 @@ import org.compiere.util.CLogger; import org.compiere.util.DisplayType; import org.compiere.util.Env; import org.compiere.util.Msg; -import org.zkoss.zul.Borderlayout; -import org.zkoss.zul.Center; public class WCreateFromRMAUI extends CreateFromRMA implements ValueChangeListener { @@ -105,25 +104,24 @@ public class WCreateFromRMAUI extends CreateFromRMA implements ValueChangeListen { bPartnerLabel.setText(Msg.getElement(Env.getCtx(), "C_BPartner_ID")); - Borderlayout parameterLayout = new Borderlayout(); - ZKUpdateUtil.setHeight(parameterLayout, "110px"); - ZKUpdateUtil.setWidth(parameterLayout, "100%"); Panel parameterPanel = window.getParameterPanel(); - parameterPanel.appendChild(parameterLayout); Grid parameterStdLayout = GridFactory.newGridLayout(); Panel parameterStdPanel = new Panel(); parameterStdPanel.appendChild(parameterStdLayout); - Center center = new Center(); - parameterLayout.appendChild(center); - center.appendChild(parameterStdPanel); + parameterPanel.appendChild(parameterStdPanel); + ZKUpdateUtil.setVflex(parameterStdLayout, "min"); Rows rows = (Rows) parameterStdLayout.newRows(); Row row = rows.newRow(); row.appendChild(bPartnerLabel.rightAlign()); if (bPartnerField != null) row.appendChild(bPartnerField.getComponent()); + + if (ClientInfo.isMobile()) { + ClientInfo.onClientInfo(window, this::onClientInfo); + } } /** @@ -196,4 +194,10 @@ public class WCreateFromRMAUI extends CreateFromRMA implements ValueChangeListen public Object getWindow() { return window; } + + protected void onClientInfo() { + ZKUpdateUtil.setCSSHeight(window); + ZKUpdateUtil.setCSSWidth(window); + window.invalidate(); + } } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WCreateFromShipmentUI.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WCreateFromShipmentUI.java index cc44e13d51..045738d401 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WCreateFromShipmentUI.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WCreateFromShipmentUI.java @@ -21,8 +21,12 @@ import java.util.Vector; import java.util.logging.Level; import org.adempiere.exceptions.AdempiereException; +import org.adempiere.webui.ClientInfo; +import org.adempiere.webui.LayoutUtils; import org.adempiere.webui.apps.AEnv; import org.adempiere.webui.component.Checkbox; +import org.adempiere.webui.component.Column; +import org.adempiere.webui.component.Columns; import org.adempiere.webui.component.Grid; import org.adempiere.webui.component.GridFactory; import org.adempiere.webui.component.Label; @@ -113,6 +117,10 @@ public class WCreateFromShipmentUI extends CreateFromShipment implements EventLi protected WLocatorEditor locatorField = new WLocatorEditor(); protected Label upcLabel = new Label(); protected WStringEditor upcField = new WStringEditor(); + + private Grid parameterStdLayout; + + private int noOfParameterColumn; /** * Dynamic Init @@ -157,13 +165,16 @@ public class WCreateFromShipmentUI extends CreateFromShipment implements EventLi upcLabel.setText(Msg.getElement(Env.getCtx(), "UPC", false)); Vlayout vlayout = new Vlayout(); - ZKUpdateUtil.setVflex(vlayout, "1"); + ZKUpdateUtil.setVflex(vlayout, "min"); ZKUpdateUtil.setWidth(vlayout, "100%"); Panel parameterPanel = window.getParameterPanel(); parameterPanel.appendChild(vlayout); - Grid parameterStdLayout = GridFactory.newGridLayout(); + parameterStdLayout = GridFactory.newGridLayout(); vlayout.appendChild(parameterStdLayout); + ZKUpdateUtil.setVflex(vlayout, "parameterStdLayout"); + + setupColumns(parameterStdLayout); Rows rows = (Rows) parameterStdLayout.newRows(); Row row = rows.newRow(); @@ -194,12 +205,19 @@ public class WCreateFromShipmentUI extends CreateFromShipment implements EventLi row = rows.newRow(); row.appendChild(upcLabel.rightAlign()); row.appendChild(upcField.getComponent()); + ZKUpdateUtil.setHflex(upcField.getComponent(), "1"); if (isRMAWindow) { // Add RMA document selection to panel row.appendChild(rmaLabel.rightAlign()); row.appendChild(rmaField); ZKUpdateUtil.setHflex(rmaField, "1"); } + + if (ClientInfo.isMobile()) { + if (noOfParameterColumn == 2) + LayoutUtils.compactTo(parameterStdLayout, 2); + ClientInfo.onClientInfo(window, this::onClientInfo); + } } private boolean m_actionActive = false; @@ -559,4 +577,60 @@ public class WCreateFromShipmentUI extends CreateFromShipment implements EventLi public Object getWindow() { return window; } + + protected void setupColumns(Grid parameterGrid) { + noOfParameterColumn = ClientInfo.maxWidth((ClientInfo.EXTRA_SMALL_WIDTH+ClientInfo.SMALL_WIDTH)/2) ? 2 : 4; + Columns columns = new Columns(); + parameterGrid.appendChild(columns); + if (ClientInfo.maxWidth((ClientInfo.EXTRA_SMALL_WIDTH+ClientInfo.SMALL_WIDTH)/2)) + { + Column column = new Column(); + ZKUpdateUtil.setWidth(column, "35%"); + columns.appendChild(column); + column = new Column(); + ZKUpdateUtil.setWidth(column, "65%"); + columns.appendChild(column); + } + else + { + Column column = new Column(); + columns.appendChild(column); + column = new Column(); + ZKUpdateUtil.setWidth(column, "15%"); + columns.appendChild(column); + ZKUpdateUtil.setWidth(column, "35%"); + column = new Column(); + ZKUpdateUtil.setWidth(column, "15%"); + columns.appendChild(column); + column = new Column(); + ZKUpdateUtil.setWidth(column, "35%"); + columns.appendChild(column); + } + } + + protected void onClientInfo() + { + if (ClientInfo.isMobile() && parameterStdLayout != null && parameterStdLayout.getRows() != null) + { + int nc = ClientInfo.maxWidth((ClientInfo.EXTRA_SMALL_WIDTH+ClientInfo.SMALL_WIDTH)/2) ? 2 : 4; + int cc = noOfParameterColumn; + if (nc == cc) + return; + + parameterStdLayout.getColumns().detach(); + setupColumns(parameterStdLayout); + if (cc > nc) + { + LayoutUtils.compactTo(parameterStdLayout, nc); + } + else + { + LayoutUtils.expandTo(parameterStdLayout, nc, false); + } + + ZKUpdateUtil.setCSSHeight(window); + ZKUpdateUtil.setCSSWidth(window); + window.invalidate(); + } + } } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WCreateFromStatementUI.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WCreateFromStatementUI.java index 09a37de727..637127696e 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WCreateFromStatementUI.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WCreateFromStatementUI.java @@ -19,6 +19,8 @@ import java.sql.Timestamp; import java.util.Vector; import java.util.logging.Level; +import org.adempiere.webui.ClientInfo; +import org.adempiere.webui.LayoutUtils; import org.adempiere.webui.apps.AEnv; import org.adempiere.webui.component.Button; import org.adempiere.webui.component.Column; @@ -53,8 +55,6 @@ import org.compiere.util.Msg; import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.event.Events; -import org.zkoss.zul.Borderlayout; -import org.zkoss.zul.Center; import org.zkoss.zul.Hbox; /** @@ -124,6 +124,8 @@ public class WCreateFromStatementUI extends CreateFromStatement implements Event protected Label dateToLabel = new Label("-"); protected WDateEditor dateToField = new WDateEditor("DateTo", false, false, true, Msg.translate(Env.getCtx(), "DateTo")); + protected Grid parameterBankLayout; + /** * Dynamic Init * @throws Exception if Lookups cannot be initialized @@ -179,6 +181,8 @@ public class WCreateFromStatementUI extends CreateFromStatement implements Event protected void zkInit() throws Exception { + LayoutUtils.addSclass("create-from-bank-statement", window); + bankAccountLabel.setText(Msg.translate(Env.getCtx(), "C_BankAccount_ID")); authorizationLabel.setText(Msg.translate(Env.getCtx(), "R_AuthCode")); @@ -191,34 +195,13 @@ public class WCreateFromStatementUI extends CreateFromStatement implements Event amtFromField.getComponent().setTooltiptext(Msg.translate(Env.getCtx(), "AmtFrom")); amtToField.getComponent().setTooltiptext(Msg.translate(Env.getCtx(), "AmtTo")); - Borderlayout parameterLayout = new Borderlayout(); - ZKUpdateUtil.setHeight(parameterLayout, "130px"); - ZKUpdateUtil.setWidth(parameterLayout, "100%"); Panel parameterPanel = window.getParameterPanel(); - parameterPanel.appendChild(parameterLayout); - Grid parameterBankLayout = GridFactory.newGridLayout(); - Panel parameterBankPanel = new Panel(); - parameterBankPanel.appendChild(parameterBankLayout); + parameterBankLayout = GridFactory.newGridLayout(); + ZKUpdateUtil.setVflex(parameterBankLayout, "min"); + parameterPanel.appendChild(parameterBankLayout); - Center center = new Center(); - parameterLayout.appendChild(center); - center.appendChild(parameterBankPanel); - - Columns columns = new Columns(); - parameterBankLayout.appendChild(columns); - Column column = new Column(); - columns.appendChild(column); - column = new Column(); - ZKUpdateUtil.setWidth(column, "15%"); - columns.appendChild(column); - ZKUpdateUtil.setWidth(column, "35%"); - column = new Column(); - ZKUpdateUtil.setWidth(column, "15%"); - columns.appendChild(column); - column = new Column(); - ZKUpdateUtil.setWidth(column, "35%"); - columns.appendChild(column); + setupColumns(parameterBankLayout); Rows rows = (Rows) parameterBankLayout.newRows(); Row row = rows.newRow(); @@ -254,6 +237,41 @@ public class WCreateFromStatementUI extends CreateFromStatement implements Event hbox.appendChild(dateToLabel.rightAlign()); hbox.appendChild(dateToField.getComponent()); row.appendChild(hbox); + + if (ClientInfo.isMobile()) { + if (ClientInfo.maxWidth(ClientInfo.EXTRA_SMALL_WIDTH)) + LayoutUtils.compactTo(parameterBankLayout, 2); + ClientInfo.onClientInfo(window, this::onClientInfo); + } + } + + protected void setupColumns(Grid parameterBankLayout) { + Columns columns = new Columns(); + parameterBankLayout.appendChild(columns); + if (ClientInfo.maxWidth(ClientInfo.EXTRA_SMALL_WIDTH)) + { + Column column = new Column(); + ZKUpdateUtil.setWidth(column, "35%"); + columns.appendChild(column); + column = new Column(); + ZKUpdateUtil.setWidth(column, "65%"); + columns.appendChild(column); + } + else + { + Column column = new Column(); + columns.appendChild(column); + column = new Column(); + ZKUpdateUtil.setWidth(column, "15%"); + columns.appendChild(column); + ZKUpdateUtil.setWidth(column, "35%"); + column = new Column(); + ZKUpdateUtil.setWidth(column, "15%"); + columns.appendChild(column); + column = new Column(); + ZKUpdateUtil.setWidth(column, "35%"); + columns.appendChild(column); + } } /** @@ -309,4 +327,30 @@ public class WCreateFromStatementUI extends CreateFromStatement implements Event { return window; } + + protected void onClientInfo() + { + if (ClientInfo.isMobile() && parameterBankLayout != null && parameterBankLayout.getColumns() != null) + { + org.zkoss.zul.Rows rows = parameterBankLayout.getRows(); + if (rows != null) + { + int nc = ClientInfo.maxWidth(ClientInfo.EXTRA_SMALL_WIDTH) ? 2 : 4; + int cc = rows.getFirstChild().getChildren().size(); + if (cc != nc) + { + parameterBankLayout.getColumns().detach(); + setupColumns(parameterBankLayout); + if (cc > nc) + LayoutUtils.compactTo(parameterBankLayout, nc); + else + LayoutUtils.expandTo(parameterBankLayout, nc); + + ZKUpdateUtil.setCSSHeight(window); + ZKUpdateUtil.setCSSWidth(window); + window.invalidate(); + } + } + } + } } \ No newline at end of file diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WCreateFromWindow.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WCreateFromWindow.java index 1ed359fc6f..af1deabadf 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WCreateFromWindow.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WCreateFromWindow.java @@ -13,6 +13,7 @@ *****************************************************************************/ package org.adempiere.webui.apps.form; +import org.adempiere.webui.LayoutUtils; import org.adempiere.webui.component.Button; import org.adempiere.webui.component.ConfirmPanel; import org.adempiere.webui.component.ListModelTable; @@ -25,6 +26,7 @@ import org.adempiere.webui.event.DialogEvents; import org.adempiere.webui.event.WTableModelEvent; import org.adempiere.webui.event.WTableModelListener; import org.adempiere.webui.panel.StatusBarPanel; +import org.adempiere.webui.theme.ThemeManager; import org.adempiere.webui.util.ZKUpdateUtil; import org.adempiere.webui.window.FDialog; import org.compiere.grid.CreateFrom; @@ -88,6 +90,12 @@ public class WCreateFromWindow extends Window implements EventListener, W North north = new North(); contentPane.appendChild(north); north.appendChild(parameterPanel); + north.setAutoscroll(true); + north.setSplittable(true); + north.setCollapsible(true); + LayoutUtils.addSlideSclass(north); + ZKUpdateUtil.setVflex(parameterPanel, "1"); + ZKUpdateUtil.setHflex(parameterPanel, "1"); Center center = new Center(); contentPane.appendChild(center); @@ -108,8 +116,19 @@ public class WCreateFromWindow extends Window implements EventListener, W southPanel.appendChild(new Separator()); southPanel.appendChild(statusBar); - ZKUpdateUtil.setWidth(this, "750px"); - ZKUpdateUtil.setHeight(this, "550px"); + if (!ThemeManager.isUseCSSForWindowSize()) + { + ZKUpdateUtil.setWindowWidthX(this, 750); + ZKUpdateUtil.setWindowHeightX(this, 550); + } + else + { + addCallback(AFTER_PAGE_ATTACHED, t -> { + ZKUpdateUtil.setCSSHeight(this); + ZKUpdateUtil.setCSSWidth(this); + }); + } + setSclass("create-from-window"); setSizable(true); setBorder("normal"); ZKUpdateUtil.setWidth(contentPane, "100%"); @@ -245,5 +264,5 @@ public class WCreateFromWindow extends Window implements EventListener, W public boolean isCancel() { return isCancel; - } + } } \ No newline at end of file diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WFactReconcile.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WFactReconcile.java index 0eb77462e6..441def6dad 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WFactReconcile.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WFactReconcile.java @@ -8,6 +8,8 @@ import java.util.Calendar; import java.util.Vector; import java.util.logging.Level; +import org.adempiere.webui.ClientInfo; +import org.adempiere.webui.LayoutUtils; import org.adempiere.webui.apps.AEnv; import org.adempiere.webui.component.Button; import org.adempiere.webui.component.Checkbox; @@ -168,9 +170,13 @@ implements IFormController, EventListener, WTableModelListener, ValueChan // Parameter Panel North north = new North(); - north.setStyle("border: none"); + north.setStyle("border: none; max-height: 60%;"); mainLayout.appendChild(north); north.appendChild(parameterPanel); + north.setCollapsible(true); + north.setSplittable(true); + north.setAutoscroll(true); + LayoutUtils.addSlideSclass(north); Rows rows = null; Row row = null; @@ -205,12 +211,17 @@ implements IFormController, EventListener, WTableModelListener, ValueChan row.appendCellChild(fieldDateAcct2.getComponent(), 2); row = rows.newRow(); row.appendChild(bRefresh); + if (ClientInfo.maxWidth(ClientInfo.EXTRA_SMALL_WIDTH-1)) + { + LayoutUtils.compactTo(parameterLayout, 3); + LayoutUtils.addSclass("btn-small small-img-btn", bRefresh); + } // Data Panel Center center = new Center(); mainLayout.appendChild(center); center.appendChild(miniTable); - ZKUpdateUtil.setWidth(miniTable, "99%"); + ZKUpdateUtil.setWidth(miniTable, "100%"); //ZKUpdateUtil.setHeight(miniTable, "99%"); center.setStyle("border: none"); @@ -220,22 +231,38 @@ implements IFormController, EventListener, WTableModelListener, ValueChan mainLayout.appendChild(south); south.appendChild(commandPanel); commandPanel.appendChild(commandLayout); - ZKUpdateUtil.setWidth(commandLayout, "90%"); + ZKUpdateUtil.setWidth(commandLayout, "100%"); rows = commandLayout.newRows(); row = rows.newRow(); - row.appendCellChild(bZoom, 2); + row.appendCellChild(bZoom, 1); ZKUpdateUtil.setHflex(bZoom, "true"); ZKUpdateUtil.setWidth(bZoom, "100%"); row.appendCellChild(differenceLabel.rightAlign()); ZKUpdateUtil.setHflex(differenceLabel, "true"); row.appendCellChild(differenceField, 2); ZKUpdateUtil.setHflex(differenceField, "true"); - row.appendCellChild(bGenerate, 2); + row.appendCellChild(bGenerate, 1); ZKUpdateUtil.setHflex(bGenerate, "true"); - row.appendCellChild(bReset, 2); + row.appendCellChild(bReset, 1); ZKUpdateUtil.setHflex(bReset, "true"); row.appendCellChild(bCancel); ZKUpdateUtil.setHflex(bCancel, "true"); + if (ClientInfo.maxWidth(ClientInfo.MEDIUM_WIDTH-1)) + { + bZoom.setTooltiptext(bZoom.getLabel()); + bZoom.setLabel(null); + bGenerate.setTooltiptext(bGenerate.getLabel()); + bGenerate.setLabel(null); + bReset.setTooltiptext(bReset.getLabel()); + bReset.setLabel(null); + if (ClientInfo.maxWidth(ClientInfo.EXTRA_SMALL_WIDTH-1)) + { + LayoutUtils.addSclass("btn-small small-img-btn", bZoom); + LayoutUtils.addSclass("btn-small small-img-btn", bGenerate); + LayoutUtils.addSclass("btn-small small-img-btn", bReset); + LayoutUtils.addSclass("btn-small small-img-btn", bCancel); + } + } } /** diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WGenForm.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WGenForm.java index 0f387f76b0..40692f4e0e 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WGenForm.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WGenForm.java @@ -122,20 +122,20 @@ public class WGenForm extends ADForm implements EventListener, WTableMode dynInit(); Borderlayout contentPane = new Borderlayout(); this.appendChild(contentPane); - ZKUpdateUtil.setWidth(contentPane, "99%"); + ZKUpdateUtil.setWidth(contentPane, "100%"); ZKUpdateUtil.setHeight(contentPane, "100%"); Center center = new Center(); - center.setStyle("border: none"); + center.setBorder("none"); contentPane.appendChild(center); center.appendChild(tabbedPane); ZKUpdateUtil.setVflex(tabbedPane, "1"); ZKUpdateUtil.setHflex(tabbedPane, "1"); South south = new South(); - south.setStyle("border: none"); + south.setBorder("none"); contentPane.appendChild(south); south.appendChild(statusBar); LayoutUtils.addSclass("status-border", statusBar); - ZKUpdateUtil.setHeight(south, "22px"); + ZKUpdateUtil.setVflex(south, "min"); } catch(Exception ex) { @@ -157,9 +157,9 @@ public class WGenForm extends ADForm implements EventListener, WTableMode void zkInit() throws Exception { // - ZKUpdateUtil.setWidth(selPanel, "99%"); - ZKUpdateUtil.setHeight(selPanel, "90%"); - selPanel.setStyle("border: none; position: absolute"); + ZKUpdateUtil.setWidth(selPanel, "100%"); + ZKUpdateUtil.setHeight(selPanel, "100%"); + selPanel.setStyle("border: none; position: relative"); DesktopTabpanel tabpanel = new DesktopTabpanel(); tabpanel.appendChild(selPanel); Tabpanels tabPanels = new Tabpanels(); @@ -173,6 +173,9 @@ public class WGenForm extends ADForm implements EventListener, WTableMode North north = new North(); selPanel.appendChild(north); north.appendChild(selNorthPanel); + north.setCollapsible(true); + north.setSplittable(true); + LayoutUtils.addSlideSclass(north); South south = new South(); selPanel.appendChild(south); @@ -192,9 +195,9 @@ public class WGenForm extends ADForm implements EventListener, WTableMode tab = new Tab(Msg.getMsg(Env.getCtx(), "Generate")); tabs.appendChild(tab); tab.setDisabled(true); - ZKUpdateUtil.setWidth(genPanel, "99%"); - ZKUpdateUtil.setHeight(genPanel, "90%"); - genPanel.setStyle("border: none; position: absolute"); + ZKUpdateUtil.setWidth(genPanel, "100%"); + ZKUpdateUtil.setHeight(genPanel, "100%"); + genPanel.setStyle("border: none; position: relative"); center = new Center(); genPanel.appendChild(center); messageDiv = new Div(); @@ -576,4 +579,5 @@ public class WGenForm extends ADForm implements EventListener, WTableMode } messageDiv.appendChild(logMessageTable); } - } + +} diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WInOutGen.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WInOutGen.java index 9f9db9b95d..e83d8413da 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WInOutGen.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WInOutGen.java @@ -16,6 +16,10 @@ package org.adempiere.webui.apps.form; import java.util.ArrayList; import java.util.logging.Level; +import org.adempiere.webui.ClientInfo; +import org.adempiere.webui.LayoutUtils; +import org.adempiere.webui.component.Column; +import org.adempiere.webui.component.Columns; import org.adempiere.webui.component.Label; import org.adempiere.webui.component.Listbox; import org.adempiere.webui.component.ListboxFactory; @@ -38,10 +42,11 @@ import org.compiere.util.DisplayType; import org.compiere.util.Env; import org.compiere.util.KeyNamePair; import org.compiere.util.Msg; +import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.WrongValueException; import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.EventListener; -import org.zkoss.zul.Space; +import org.zkoss.zul.North; /** * Generate Shipment (manual) view class @@ -63,6 +68,8 @@ public class WInOutGen extends InOutGen implements IFormController, EventListene private Label lDocAction = new Label(); private WTableDirEditor docAction; + private int noOfColumn; + public WInOutGen() { log.info(""); @@ -82,6 +89,8 @@ public class WInOutGen extends InOutGen implements IFormController, EventListene { log.log(Level.SEVERE, "init", ex); } + + ClientInfo.onClientInfo(form, this::onClientInfo); } // init /** @@ -97,30 +106,54 @@ public class WInOutGen extends InOutGen implements IFormController, EventListene */ void zkInit() throws Exception { + setupColumns(); + lBPartner.setText(Msg.translate(Env.getCtx(), "C_BPartner_ID")); Row row = form.getParameterPanel().newRows().newRow(); row.appendCellChild(lWarehouse.rightAlign()); ZKUpdateUtil.setHflex(fWarehouse.getComponent(), "true"); row.appendCellChild(fWarehouse.getComponent()); - row.appendCellChild(new Space()); row.appendCellChild(lBPartner.rightAlign()); ZKUpdateUtil.setHflex(fBPartner.getComponent(), "true"); - row.appendCellChild(fBPartner.getComponent()); - row.appendCellChild(new Space()); + row.appendCellChild(fBPartner.getComponent()); row = new Row(); form.getParameterPanel().getRows().appendChild(row); row.appendCellChild(lDocType.rightAlign()); ZKUpdateUtil.setHflex(cmbDocType, "true"); row.appendCellChild(cmbDocType); - row.appendCellChild(new Space()); row.appendCellChild(lDocAction.rightAlign()); - ZKUpdateUtil.setHflex(docAction.getComponent(), "true"); + ZKUpdateUtil.setHflex(docAction.getComponent(), "true"); row.appendCellChild(docAction.getComponent()); - row.appendCellChild(new Space()); + if (noOfColumn < 6) + LayoutUtils.compactTo(form.getParameterPanel(), noOfColumn); + else + LayoutUtils.expandTo(form.getParameterPanel(), noOfColumn, true); } // jbInit + protected void setupColumns() { + noOfColumn = 6; + if (ClientInfo.maxWidth(ClientInfo.MEDIUM_WIDTH-1)) + { + if (ClientInfo.maxWidth(ClientInfo.SMALL_WIDTH-1)) + noOfColumn = 2; + else + noOfColumn = 4; + } + if (noOfColumn == 2) + { + Columns columns = new Columns(); + Column column = new Column(); + column.setWidth("35%"); + columns.appendChild(column); + column = new Column(); + column.setWidth("65%"); + columns.appendChild(column); + form.getParameterPanel().appendChild(columns); + } + } + /** * Fill Picks. * Column_ID from C_Order @@ -165,10 +198,44 @@ public class WInOutGen extends InOutGen implements IFormController, EventListene { KeyNamePair docTypeKNPair = cmbDocType.getSelectedItem().toKeyNamePair(); executeQuery(docTypeKNPair, form.getMiniTable()); + if (ClientInfo.maxHeight(ClientInfo.SMALL_HEIGHT-1)) + { + Component comp = form.getParameterPanel().getParent(); + if (comp instanceof North) + ((North)comp).setOpen(false); + } form.getMiniTable().repaint(); form.invalidate(); } // executeQuery + protected void onClientInfo() + { + if (ClientInfo.isMobile() && form.getPage() != null) + { + if (noOfColumn > 0 && form.getParameterPanel().getRows() != null) + { + int t = 6; + if (ClientInfo.maxWidth(ClientInfo.MEDIUM_WIDTH-1)) + { + if (ClientInfo.maxWidth(ClientInfo.SMALL_WIDTH-1)) + t = 2; + else + t = 4; + } + if (t != noOfColumn) + { + form.getParameterPanel().getRows().detach(); + if (form.getParameterPanel().getColumns() != null) + form.getParameterPanel().getColumns().detach(); + try { + zkInit(); + form.invalidate(); + } catch (Exception e1) {} + } + } + } + } + /** * Action Listener * @param e event diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WInvoiceGen.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WInvoiceGen.java index ccc0186023..ecb1aa09af 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WInvoiceGen.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WInvoiceGen.java @@ -16,6 +16,10 @@ package org.adempiere.webui.apps.form; import java.util.ArrayList; import java.util.logging.Level; +import org.adempiere.webui.ClientInfo; +import org.adempiere.webui.LayoutUtils; +import org.adempiere.webui.component.Column; +import org.adempiere.webui.component.Columns; import org.adempiere.webui.component.Label; import org.adempiere.webui.component.Listbox; import org.adempiere.webui.component.ListboxFactory; @@ -38,10 +42,11 @@ import org.compiere.util.DisplayType; import org.compiere.util.Env; import org.compiere.util.KeyNamePair; import org.compiere.util.Msg; +import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.WrongValueException; import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.EventListener; -import org.zkoss.zul.Space; +import org.zkoss.zul.North; /** * Generate Invoice (manual) view class @@ -63,11 +68,13 @@ public class WInvoiceGen extends InvoiceGen implements IFormController, EventLis private Label lDocAction = new Label(); private WTableDirEditor docAction; + private int noOfColumn; + public WInvoiceGen() { log.info(""); - form = new WGenForm(this); + form = new WGenForm(this); Env.setContext(Env.getCtx(), form.getWindowNo(), "IsSOTrx", "Y"); try @@ -82,6 +89,8 @@ public class WInvoiceGen extends InvoiceGen implements IFormController, EventLis { log.log(Level.SEVERE, "init", ex); } + + ClientInfo.onClientInfo(form, this::onClientInfo); } // init /** @@ -97,6 +106,8 @@ public class WInvoiceGen extends InvoiceGen implements IFormController, EventLis */ void zkInit() throws Exception { + setupColumns(); + lOrg.setText(Msg.translate(Env.getCtx(), "AD_Org_ID")); lBPartner.setText(Msg.translate(Env.getCtx(), "C_BPartner_ID")); @@ -104,24 +115,46 @@ public class WInvoiceGen extends InvoiceGen implements IFormController, EventLis row.appendCellChild(lOrg.rightAlign()); ZKUpdateUtil.setHflex(fOrg.getComponent(), "true"); row.appendCellChild(fOrg.getComponent()); - row.appendCellChild(new Space()); row.appendCellChild(lBPartner.rightAlign()); ZKUpdateUtil.setHflex(fBPartner.getComponent(), "true"); row.appendCellChild(fBPartner.getComponent()); - row.appendCellChild(new Space()); row = new Row(); form.getParameterPanel().getRows().appendChild(row); row.appendCellChild(lDocType.rightAlign()); ZKUpdateUtil.setHflex(cmbDocType, "true"); row.appendCellChild(cmbDocType); - row.appendCellChild(new Space()); row.appendCellChild(lDocAction.rightAlign()); ZKUpdateUtil.setHflex(docAction.getComponent(), "true"); row.appendCellChild(docAction.getComponent()); - row.appendCellChild(new Space()); + if (noOfColumn < 6) + LayoutUtils.compactTo(form.getParameterPanel(), noOfColumn); + else + LayoutUtils.expandTo(form.getParameterPanel(), noOfColumn, true); } // jbInit + protected void setupColumns() { + noOfColumn = 6; + if (ClientInfo.maxWidth(ClientInfo.MEDIUM_WIDTH-1)) + { + if (ClientInfo.maxWidth(ClientInfo.SMALL_WIDTH-1)) + noOfColumn = 2; + else + noOfColumn = 4; + } + if (noOfColumn == 2) + { + Columns columns = new Columns(); + Column column = new Column(); + column.setWidth("35%"); + columns.appendChild(column); + column = new Column(); + column.setWidth("65%"); + columns.appendChild(column); + form.getParameterPanel().appendChild(columns); + } + } + /** * Fill Picks. * Column_ID from C_Order @@ -164,10 +197,44 @@ public class WInvoiceGen extends InvoiceGen implements IFormController, EventLis { KeyNamePair docTypeKNPair = cmbDocType.getSelectedItem().toKeyNamePair(); executeQuery(docTypeKNPair, form.getMiniTable()); + if (ClientInfo.maxHeight(ClientInfo.SMALL_HEIGHT-1)) + { + Component comp = form.getParameterPanel().getParent(); + if (comp instanceof North) + ((North)comp).setOpen(false); + } form.getMiniTable().repaint(); form.invalidate(); } // executeQuery + protected void onClientInfo() + { + if (ClientInfo.isMobile() && form.getPage() != null) + { + if (noOfColumn > 0 && form.getParameterPanel().getRows() != null) + { + int t = 6; + if (ClientInfo.maxWidth(ClientInfo.MEDIUM_WIDTH-1)) + { + if (ClientInfo.maxWidth(ClientInfo.SMALL_WIDTH-1)) + t = 2; + else + t = 4; + } + if (t != noOfColumn) + { + form.getParameterPanel().getRows().detach(); + if (form.getParameterPanel().getColumns() != null) + form.getParameterPanel().getColumns().detach(); + try { + zkInit(); + form.invalidate(); + } catch (Exception e1) {} + } + } + } + } + /** * Action Listener * @param e event diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WMatch.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WMatch.java index c9039b3017..2088c0b1c3 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WMatch.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WMatch.java @@ -16,14 +16,21 @@ *****************************************************************************/ package org.adempiere.webui.apps.form; +import static org.adempiere.webui.ClientInfo.MEDIUM_WIDTH; +import static org.adempiere.webui.ClientInfo.SMALL_WIDTH; +import static org.adempiere.webui.ClientInfo.maxWidth; + import java.math.BigDecimal; import java.sql.Timestamp; import java.util.logging.Level; +import org.adempiere.webui.ClientInfo; import org.adempiere.webui.LayoutUtils; import org.adempiere.webui.apps.AEnv; import org.adempiere.webui.component.Button; import org.adempiere.webui.component.Checkbox; +import org.adempiere.webui.component.Column; +import org.adempiere.webui.component.Columns; import org.adempiere.webui.component.Grid; import org.adempiere.webui.component.GridFactory; import org.adempiere.webui.component.Label; @@ -63,6 +70,7 @@ import org.zkoss.zul.North; import org.zkoss.zul.South; import org.zkoss.zul.Separator; import org.zkoss.zul.Space; +import org.zkoss.zul.Vlayout; /** * Manual Matching @@ -110,6 +118,11 @@ public class WMatch extends Match { log.log(Level.SEVERE, "", e); } + + if (ClientInfo.isMobile()) + { + ClientInfo.onClientInfo(form, this::onClientInfo); + } } // init /** Window No */ @@ -182,7 +195,8 @@ public class WMatch extends Match private Checkbox sameProduct = new Checkbox(); private Checkbox sameBPartner = new Checkbox(); private Checkbox sameQty = new Checkbox(); - + private int noOfColumn; + /** * Static Init. *
@@ -199,10 +213,11 @@ public class WMatch extends Match
 	private void zkInit() throws Exception
 	{
 		form.appendChild(mainPanel);
-		mainPanel.setStyle("width: 99%; height: 100%; padding: 0; margin: 0");
+		mainPanel.setStyle("width: 100%; height: 100%; padding: 0; margin: 0; overflow: auto;");
 		mainPanel.appendChild(mainLayout);
 		ZKUpdateUtil.setWidth(mainLayout, "100%");
 		ZKUpdateUtil.setHeight(mainLayout, "100%");
+		mainLayout.setStyle("min-height: 750px");
 		northPanel.appendChild(northLayout);
 		matchFromLabel.setText(Msg.translate(Env.getCtx(), "MatchFrom"));
 		matchToLabel.setText(Msg.translate(Env.getCtx(), "MatchTo"));
@@ -225,9 +240,64 @@ public class WMatch extends Match
 		sameQty.setSelected(false);
 		sameQty.setText(Msg.translate(Env.getCtx(), "SameQty"));
 		
+		// north - parameters
 		North north = new North();
 		mainLayout.appendChild(north);
 		north.appendChild(northPanel);
+		north.setCollapsible(true);
+		north.setSplittable(true);
+		
+		layoutParameterAndSummary();
+		
+		// center - match from and match to list
+		Center center = new Center();
+		center.setAutoscroll(true);
+		mainLayout.appendChild(center);
+		center.appendChild(centerPanel);
+		ZKUpdateUtil.setHflex(centerPanel, "1");
+		ZKUpdateUtil.setVflex(centerPanel, "1");
+		ZKUpdateUtil.setWidth(centerLayout, "100%");
+		ZKUpdateUtil.setHeight(centerLayout, "100%");
+		north = new North();
+		centerLayout.appendChild(north);
+		north.setStyle("border: none");
+		Panel p = new Panel();
+		p.appendChild(xMatchedBorder);
+		p.appendChild(xMatchedTable);
+		ZKUpdateUtil.setWidth(xMatchedTable, "100%");
+		p.setStyle("width: 100%; height: 100%; padding: 0; margin: 0");
+		north.appendChild(p);
+		ZKUpdateUtil.setHeight(north, "45%");
+		north.setSplittable(true);
+		north.setCollapsible(true);
+						
+		center = new Center();
+		centerLayout.appendChild(center);
+		center.setBorder("none");
+		Vlayout vlayout = new Vlayout();
+		vlayout.setVflex("1");
+		vlayout.setHflex("1");
+		center.appendChild(vlayout);
+		ZKUpdateUtil.setVflex(xPanel, "1");
+		ZKUpdateUtil.setHflex(xPanel, "1");
+		xPanel.appendChild(sameBPartner);
+		xPanel.appendChild(new Space());
+		xPanel.appendChild(sameProduct);
+		xPanel.appendChild(new Space());
+		xPanel.appendChild(sameQty);
+		ZKUpdateUtil.setVflex(xPanel, "min");
+		xPanel.appendChild(new Separator());
+		vlayout.appendChild(xPanel);
+		vlayout.appendChild(xMatchedToBorder);
+		ZKUpdateUtil.setWidth(xMatchedToTable, "100%");
+		vlayout.appendChild(xMatchedToTable);
+		ZKUpdateUtil.setVflex(xMatchedTable, true);
+				
+		centerPanel.setStyle("min-height: 300px;");
+	}   //  jbInit
+
+	protected void layoutParameterAndSummary() {
+		setupParameterColumns();
 		
 		Rows rows = northLayout.newRows();
 		Row row = rows.newRow();
@@ -235,27 +305,31 @@ public class WMatch extends Match
 		row.appendChild(matchFrom);
 		row.appendChild(matchToLabel.rightAlign());
 		row.appendChild(matchTo);
-		row.appendChild(new Space());
 		
 		row = rows.newRow();
 		row.appendCellChild(matchModeLabel.rightAlign(), 1);
 		row.appendCellChild(matchMode, 1);
-		row.appendCellChild(new Space(), 3);
 		
 		row = rows.newRow();
 		row.appendChild(onlyVendorLabel.rightAlign());
 		row.appendChild(onlyVendor.getComponent());
 		row.appendChild(onlyProductLabel.rightAlign());
-		row.appendChild(onlyProduct.getComponent());
-		row.appendChild(new Space());
+		row.appendChild(onlyProduct.getComponent());	
 		
 		row = rows.newRow();
 		row.appendChild(dateFromLabel.rightAlign());		
 		row.appendChild(dateFrom.getComponent());
 		row.appendChild(dateToLabel.rightAlign());
 		row.appendChild(dateTo.getComponent());
-		row.appendChild(bSearch);
+		bSearch.setStyle("float: right");
+		int r = row.getChildren().size() % noOfColumn;
+		row.appendCellChild(bSearch, noOfColumn-r);
+		if (noOfColumn < 6)
+			LayoutUtils.compactTo(northLayout, noOfColumn);
+		else
+			LayoutUtils.expandTo(northLayout, noOfColumn, true);
 		
+		// south - summary	
 		South south = new South();
 		mainLayout.appendChild(south);
 		south.appendChild(southPanel);
@@ -269,51 +343,48 @@ public class WMatch extends Match
 		row.appendChild(xMatchedTo.getComponent());
 		row.appendChild(differenceLabel.rightAlign());
 		row.appendChild(difference.getComponent());
-		row.appendChild(bProcess);
 		
-		Center center = new Center();
-		mainLayout.appendChild(center);
-		center.appendChild(centerPanel);
-		ZKUpdateUtil.setHflex(centerPanel, "1");
-		ZKUpdateUtil.setVflex(centerPanel, "1");
-		ZKUpdateUtil.setWidth(centerLayout, "100%");
-		ZKUpdateUtil.setHeight(centerLayout, "100%");
-		north = new North();
-		centerLayout.appendChild(north);
-		north.setStyle("border: none");
-		Panel p = new Panel();
-		p.appendChild(xMatchedBorder);
-		p.appendChild(xMatchedTable);
-		ZKUpdateUtil.setWidth(xMatchedTable, "99%");
-		//ZKUpdateUtil.setHeight(xMatchedTable, "85%");
-		p.setStyle("width: 100%; height: 100%; padding: 0; margin: 0");
-		north.appendChild(p);
-		ZKUpdateUtil.setHeight(north, "44%");
-		
-		south = new South();
-		centerLayout.appendChild(south);
-		south.setStyle("border: none");
-		ZKUpdateUtil.setWidth(xMatchedToTable, "99%");
-		//ZKUpdateUtil.setHeight(xMatchedToTable, "99%");
-		south.appendChild(xMatchedToTable);
-		ZKUpdateUtil.setHeight(south, "44%");
-		
-		center = new Center();
-		centerLayout.appendChild(center);
-		center.setStyle("border: none");
-//		ZKUpdateUtil.setHeight(center, "6%");
-		center.appendChild(xPanel);
-		ZKUpdateUtil.setVflex(xPanel, "1");
-		ZKUpdateUtil.setHflex(xPanel, "1");
-		xPanel.appendChild(sameBPartner);
-		xPanel.appendChild(new Space());
-		xPanel.appendChild(sameProduct);
-		xPanel.appendChild(new Space());
-		xPanel.appendChild(sameQty);
-		ZKUpdateUtil.setHeight(xPanel, "50px");
-		xPanel.appendChild(new Separator());
-		xPanel.appendChild(xMatchedToBorder);
-	}   //  jbInit
+		row = rows.newRow();
+		row.appendCellChild(bProcess, noOfColumn);
+		bProcess.setStyle("float: right");
+		if (noOfColumn < 6)
+			LayoutUtils.compactTo(southLayout, noOfColumn);
+	}
+
+	protected void setupParameterColumns() {
+		noOfColumn = 6;
+		if (maxWidth(MEDIUM_WIDTH-1))
+		{
+			if (maxWidth(SMALL_WIDTH-1))
+				noOfColumn = 2;
+			else
+				noOfColumn = 4;
+		}
+		Columns columns = new Columns();
+		Column column = new Column();
+		column.setWidth(noOfColumn == 2 ? "35%" : (noOfColumn == 4 ? "15%" : "10%"));
+		columns.appendChild(column);
+		column = new Column();
+		column.setWidth(noOfColumn == 2 ? "65%" : "35%");
+		columns.appendChild(column);
+		if (noOfColumn > 2) {
+			column = new Column();
+			column.setWidth(noOfColumn == 4 ? "15%" : "10%");
+			columns.appendChild(column);
+			column = new Column();
+			column.setWidth("35%");
+			columns.appendChild(column);
+		}
+		if (noOfColumn == 6) {
+			column = new Column();
+			column.setWidth("5%");
+			columns.appendChild(column);
+			column = new Column();
+			column.setWidth("5%");
+			columns.appendChild(column);
+		}
+		northLayout.appendChild(columns);
+	}
 
 	/**
 	 *  Dynamic Init.
@@ -373,6 +444,36 @@ public class WMatch extends Match
 	}	//	dispose
 
 	
+	protected void onClientInfo()
+	{
+		if (ClientInfo.isMobile() && form.getPage() != null) 
+		{
+			if (noOfColumn > 0 && northLayout.getRows() != null)
+			{
+				int t = 6;
+				if (maxWidth(MEDIUM_WIDTH-1))
+				{
+					if (maxWidth(SMALL_WIDTH-1))
+						t = 2;
+					else
+						t = 4;
+				}
+				if (t != noOfColumn)
+				{
+					northLayout.getRows().detach();
+					if (northLayout.getColumns() != null)
+						northLayout.getColumns().detach();
+					if (mainLayout.getSouth() != null)
+						mainLayout.getSouth().detach();
+					if (southLayout.getRows() != null)
+						southLayout.getRows().detach();
+					layoutParameterAndSummary();
+					form.invalidate();
+				}
+			}
+		}
+	}
+	
 	/**************************************************************************
 	 *  Action Listener
 	 *  @param e event
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPayPrint.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPayPrint.java
index 692eda2558..89b769bf6f 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPayPrint.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPayPrint.java
@@ -25,8 +25,12 @@ import java.util.List;
 import java.util.logging.Level;
 
 import org.adempiere.util.Callback;
+import org.adempiere.webui.ClientInfo;
+import org.adempiere.webui.LayoutUtils;
 import org.adempiere.webui.apps.AEnv;
 import org.adempiere.webui.component.Button;
+import org.adempiere.webui.component.Column;
+import org.adempiere.webui.component.Columns;
 import org.adempiere.webui.component.ConfirmPanel;
 import org.adempiere.webui.component.Grid;
 import org.adempiere.webui.component.GridFactory;
@@ -104,6 +108,7 @@ public class WPayPrint extends PayPrint implements IFormController, EventListene
 			Center center = new Center();
 			contentLayout.appendChild(center);
 			center.appendChild(centerPanel);
+			center.setAutoscroll(true);
 			South south = new South();
 			south.setStyle("border: none");
 			contentLayout.appendChild(south);
@@ -212,6 +217,19 @@ public class WPayPrint extends PayPrint implements IFormController, EventListene
 		row.appendChild(lSumPayments.rightAlign()) ;
 		row.appendChild(fSumPayments.getComponent()) ;
 
+		if (ClientInfo.maxWidth(ClientInfo.MEDIUM_WIDTH))
+		{
+			Columns cols = new Columns();
+			centerLayout.appendChild(cols);
+			Column col = new Column();
+			col.setHflex("min");
+			cols.appendChild(col);
+			col = new Column();
+			col.setHflex("1");
+			cols.appendChild(col);
+			LayoutUtils.compactTo(centerLayout, 2);
+		}
+
 		southPanel.getButton(ConfirmPanel.A_OK).setVisible(false);
 		bExport.setDisabled(true);
 		bPrint.setDisabled(true);
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPaySelect.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPaySelect.java
index 53a7f31b4f..d61ddaa980 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPaySelect.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPaySelect.java
@@ -28,10 +28,14 @@ import java.util.logging.Level;
 
 import org.adempiere.util.Callback;
 import org.adempiere.util.IProcessUI;
+import org.adempiere.webui.ClientInfo;
+import org.adempiere.webui.LayoutUtils;
 import org.adempiere.webui.apps.AEnv;
 import org.adempiere.webui.apps.ProcessModalDialog;
 import org.adempiere.webui.component.Button;
 import org.adempiere.webui.component.Checkbox;
+import org.adempiere.webui.component.Column;
+import org.adempiere.webui.component.Columns;
 import org.adempiere.webui.component.ConfirmPanel;
 import org.adempiere.webui.component.Grid;
 import org.adempiere.webui.component.GridFactory;
@@ -160,6 +164,7 @@ public class WPaySelect extends PaySelect
 		//
 		labelBankAccount.setText(Msg.translate(Env.getCtx(), "C_BankAccount_ID"));
 		fieldBankAccount.addActionListener(this);
+		ZKUpdateUtil.setHflex(fieldBankAccount, "1");
 		labelBPartner.setText(Msg.translate(Env.getCtx(), "C_BPartner_ID"));
 		fieldBPartner.addActionListener(this);
 		bRefresh.addActionListener(this);
@@ -168,6 +173,7 @@ public class WPaySelect extends PaySelect
 		fieldPaymentRule.addActionListener(this);
 		labelDtype.setText(Msg.translate(Env.getCtx(), "C_DocType_ID"));
 		fieldDtype.addActionListener(this);
+		ZKUpdateUtil.setHflex(fieldDtype, "1");
 		//
 		labelBankBalance.setText(Msg.translate(Env.getCtx(), "CurrentBalance"));
 		labelBalance.setText("0");
@@ -176,6 +182,7 @@ public class WPaySelect extends PaySelect
 		dataStatus.setPre(true);
 		onlyDue.addActionListener(this);
 		fieldPayDate.addValueChangeListener(this);
+		ZKUpdateUtil.setHflex(fieldPayDate.getComponent(), "1");
 
 		//IDEMPIERE-2657, pritesh shah
 		bGenerate.setEnabled(false);
@@ -183,14 +190,44 @@ public class WPaySelect extends PaySelect
 		bCancel.addActionListener(this);
 		//
 		North north = new North();
-		north.setStyle("border: none");
+		north.setStyle("border: none; max-height: 60%;");
 		mainLayout.appendChild(north);
-		north.appendChild(parameterPanel);
+		north.appendChild(parameterPanel);		
+		north.setSplittable(true);
+		north.setCollapsible(true);
+		north.setAutoscroll(true);
+		LayoutUtils.addSlideSclass(north);
+		
+		if (ClientInfo.maxWidth(ClientInfo.MEDIUM_WIDTH-1))
+		{
+			Columns cols = new Columns();
+			parameterLayout.appendChild(cols);
+			Column col = new Column();
+			col.setHflex("min");
+			cols.appendChild(col);
+			col = new Column();
+			col.setHflex("1");
+			cols.appendChild(col);
+			col = new Column();
+			col.setHflex("min");
+			cols.appendChild(col);
+			if (ClientInfo.minWidth(ClientInfo.SMALL_WIDTH))
+			{
+				col = new Column();
+				col.setWidth("20%");
+				cols.appendChild(col);
+			}
+		}
 		
 		Rows rows = parameterLayout.newRows();
 		Row row = rows.newRow();
 		row.appendChild(labelBankAccount.rightAlign());
 		row.appendChild(fieldBankAccount);
+		if (ClientInfo.maxWidth(ClientInfo.MEDIUM_WIDTH-1))
+		{			
+			row.appendChild(new Space());
+			row = rows.newRow();
+		}
 		row.appendChild(labelBankBalance.rightAlign());
 		Panel balancePanel = new Panel();
 		balancePanel.appendChild(labelCurrency);
@@ -201,7 +238,12 @@ public class WPaySelect extends PaySelect
 		row = rows.newRow();
 		row.appendChild(labelBPartner.rightAlign());
 		row.appendChild(fieldBPartner);
-		row.appendChild(new Space());
+		if (ClientInfo.maxWidth(ClientInfo.MEDIUM_WIDTH-1))
+		{		
+			row.appendChild(new Space());
+			row = rows.newRow();
+		}
+		row.appendChild(new Space());		
 		row.appendChild(onlyDue);
 		row.appendChild(new Space());
 		
@@ -209,15 +251,25 @@ public class WPaySelect extends PaySelect
 		row.appendChild(labelDtype.rightAlign());
 		row.appendChild(fieldDtype);
 		row.appendChild(new Space());
-		row.appendChild(new Space());
-		row.appendChild(new Space());
+		if (ClientInfo.minWidth(ClientInfo.MEDIUM_WIDTH))
+		{			
+			row.appendChild(new Space());
+			row.appendChild(new Space());
+		}
 		
 		row = rows.newRow();
 		row.appendChild(labelPayDate.rightAlign());
 		row.appendChild(fieldPayDate.getComponent());
+		if (ClientInfo.maxWidth(ClientInfo.MEDIUM_WIDTH-1))
+		{			
+			row.appendChild(new Space());
+			row = rows.newRow();
+		}
 		row.appendChild(labelPaymentRule.rightAlign());
 		row.appendChild(fieldPaymentRule);
 		row.appendChild(bRefresh);
+		if (ClientInfo.minWidth(ClientInfo.SMALL_WIDTH))
+			LayoutUtils.expandTo(parameterLayout, 4, true);
 
 		South south = new South();
 		south.setStyle("border: none");
@@ -318,6 +370,11 @@ public class WPaySelect extends PaySelect
 		loadTableInfo(bi, payDate, paymentRule, onlyDue.isSelected(), bpartner, docType, miniTable);
 		
 		calculateSelection();
+		if (ClientInfo.maxHeight(ClientInfo.MEDIUM_HEIGHT-1))
+		{
+			mainLayout.getNorth().setOpen(false);
+			LayoutUtils.addSclass("slide", mainLayout.getNorth());
+		}
 	}   //  loadTableInfo
 
 	/**
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPaymentFormWindow.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPaymentFormWindow.java
index c07b83c446..d77afb30ce 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPaymentFormWindow.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WPaymentFormWindow.java
@@ -19,6 +19,7 @@ import org.adempiere.webui.component.ConfirmPanel;
 import org.adempiere.webui.component.Panel;
 import org.adempiere.webui.component.Window;
 import org.adempiere.webui.event.DialogEvents;
+import org.adempiere.webui.theme.ThemeManager;
 import org.adempiere.webui.util.ZKUpdateUtil;
 import org.adempiere.webui.window.FDialog;
 import org.compiere.grid.PaymentForm;
@@ -70,9 +71,10 @@ public class WPaymentFormWindow extends Window implements EventListener,
 		}
 		
 		this.setTitle(Msg.getMsg(Env.getCtx(), "Payment"));
-		this.setSclass("popup-dialog");
+		this.setSclass("popup-dialog payment-form-dialog");
 		this.setBorder("normal");
-		ZKUpdateUtil.setWidth(this, "500px");
+		if (!ThemeManager.isUseCSSForWindowSize())
+			ZKUpdateUtil.setWindowWidthX(this, 500);
 		this.setShadow(true);
 		this.setAttribute(Window.MODE_KEY, Window.MODE_HIGHLIGHTED);
 	}
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WReportCustomization.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WReportCustomization.java
index 3b1c05b0f4..8eb421178d 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WReportCustomization.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WReportCustomization.java
@@ -453,8 +453,8 @@ public class WReportCustomization  implements IFormController,EventListener nc)
+						LayoutUtils.compactTo(parameterBankLayout, nc);
+					else
+						LayoutUtils.expandTo(parameterBankLayout, nc);
+					ZKUpdateUtil.setCSSHeight(form);
+					ZKUpdateUtil.setCSSWidth(form);
+					form.invalidate();
+				}				
+			}
+		}
+	}
+
 	protected void zkInit() throws Exception
 	{
 		bankAccountLabel.setText(Msg.translate(Env.getCtx(), "C_BankAccount_ID"));
@@ -191,34 +218,13 @@ public class WStatementCreateFromBatch extends StatementCreateFromBatch implemen
     	amtFromField.getComponent().setTooltiptext(Msg.translate(Env.getCtx(), "AmtFrom"));
     	amtToField.getComponent().setTooltiptext(Msg.translate(Env.getCtx(), "AmtTo"));
     	
-    	Borderlayout parameterLayout = new Borderlayout();
-    	ZKUpdateUtil.setHeight(parameterLayout, "130px");
-    	ZKUpdateUtil.setWidth(parameterLayout, "100%");
     	Panel parameterPanel = form.getParameterPanel();
-		parameterPanel.appendChild(parameterLayout);
 		
-		Grid parameterBankLayout = GridFactory.newGridLayout();
-    	Panel parameterBankPanel = new Panel();
-    	parameterBankPanel.appendChild(parameterBankLayout);
+		parameterBankLayout = GridFactory.newGridLayout();
+		ZKUpdateUtil.setVflex(parameterBankLayout, "min");
+    	parameterPanel.appendChild(parameterBankLayout);
 
-		Center center = new Center();
-		parameterLayout.appendChild(center);
-		center.appendChild(parameterBankPanel);
-		
-		Columns columns = new Columns();
-		parameterBankLayout.appendChild(columns);
-		Column column = new Column();
-		columns.appendChild(column);		
-		column = new Column();
-		ZKUpdateUtil.setWidth(column, "15%");
-		columns.appendChild(column);
-		ZKUpdateUtil.setWidth(column, "35%");
-		column = new Column();
-		ZKUpdateUtil.setWidth(column, "15%");
-		columns.appendChild(column);
-		column = new Column();
-		ZKUpdateUtil.setWidth(column, "35%");
-		columns.appendChild(column);
+    	setupColumns(parameterBankLayout);
 		
 		Rows rows = (Rows) parameterBankLayout.newRows();
 		Row row = rows.newRow();
@@ -254,8 +260,43 @@ public class WStatementCreateFromBatch extends StatementCreateFromBatch implemen
 		hbox.appendChild(dateToLabel.rightAlign());
 		hbox.appendChild(dateToField.getComponent());
 		row.appendChild(hbox);
+		
+		if (ClientInfo.isMobile()) {
+			if (ClientInfo.maxWidth(ClientInfo.EXTRA_SMALL_WIDTH))
+				LayoutUtils.compactTo(parameterBankLayout, 2);		
+			ClientInfo.onClientInfo(form, this::onClientInfo);
+		}
 	}
 
+	protected void setupColumns(Grid parameterBankLayout) {
+		Columns columns = new Columns();
+		parameterBankLayout.appendChild(columns);
+		if (ClientInfo.maxWidth(ClientInfo.EXTRA_SMALL_WIDTH))
+		{
+			Column column = new Column();
+			ZKUpdateUtil.setWidth(column, "35%");
+			columns.appendChild(column);
+			column = new Column();
+			ZKUpdateUtil.setWidth(column, "65%");
+			columns.appendChild(column);
+		}
+		else
+		{
+			Column column = new Column();
+			columns.appendChild(column);		
+			column = new Column();
+			ZKUpdateUtil.setWidth(column, "15%");
+			columns.appendChild(column);
+			ZKUpdateUtil.setWidth(column, "35%");
+			column = new Column();
+			ZKUpdateUtil.setWidth(column, "15%");
+			columns.appendChild(column);
+			column = new Column();
+			ZKUpdateUtil.setWidth(column, "35%");
+			columns.appendChild(column);
+		}
+	}
+	
 	/**
 	 *  Action Listener
 	 *  @param e event
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WTreeBOM.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WTreeBOM.java
index 9a400feb89..6d97119c78 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WTreeBOM.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WTreeBOM.java
@@ -22,17 +22,14 @@ import java.util.Properties;
 import java.util.Vector;
 import java.util.logging.Level;
 
+import org.adempiere.webui.ClientInfo;
 import org.adempiere.webui.component.Borderlayout;
 import org.adempiere.webui.component.Checkbox;
 import org.adempiere.webui.component.ConfirmPanel;
-import org.adempiere.webui.component.Grid;
-import org.adempiere.webui.component.GridFactory;
 import org.adempiere.webui.component.Label;
 import org.adempiere.webui.component.ListModelTable;
 import org.adempiere.webui.component.ListboxFactory;
 import org.adempiere.webui.component.Panel;
-import org.adempiere.webui.component.Row;
-import org.adempiere.webui.component.Rows;
 import org.adempiere.webui.component.SimpleTreeModel;
 import org.adempiere.webui.component.WListbox;
 import org.adempiere.webui.editor.WSearchEditor;
@@ -61,8 +58,8 @@ import org.zkoss.zk.ui.event.EventListener;
 import org.zkoss.zk.ui.event.Events;
 import org.zkoss.zul.Center;
 import org.zkoss.zul.DefaultTreeNode;
+import org.zkoss.zul.Hlayout;
 import org.zkoss.zul.North;
-import org.zkoss.zul.Separator;
 import org.zkoss.zul.South;
 import org.zkoss.zul.Space;
 import org.zkoss.zul.Tree;
@@ -94,8 +91,8 @@ public class WTreeBOM extends TreeBOM implements IFormController, EventListener<
 	private ConfirmPanel confirmPanel = new ConfirmPanel(true);
 	private WListbox tableBOM = ListboxFactory.newDataTable();
 	private Vector> dataBOM = new Vector>();
-	private Grid northLayout = GridFactory.newGridLayout();
-	private Grid southLayout = GridFactory.newGridLayout();
+	private Hlayout northLayout = new Hlayout();
+	private Hlayout southLayout = new Hlayout();
 	private mySimpleTreeNode  	m_root = null;
 	private boolean reload = false;
 	private Checkbox treeExpand = new Checkbox();
@@ -169,11 +166,12 @@ public class WTreeBOM extends TreeBOM implements IFormController, EventListener<
 		ZKUpdateUtil.setHeight(m_frame, "100%");
 		m_frame.setStyle("position: absolute; padding: 0; margin: 0");
 		m_frame.appendChild (mainLayout);
-		ZKUpdateUtil.setWidth(mainLayout, "100%");
+		ZKUpdateUtil.setHflex(mainLayout, "1");
 		ZKUpdateUtil.setHeight(mainLayout, "100%");
-		mainLayout.setStyle("position: absolute");
 		northPanel.appendChild(northLayout);
 		southPanel.appendChild(southLayout);
+		ZKUpdateUtil.setVflex(southPanel, "min");
+		
 		
 		labelProduct.setText (Msg.getElement(Env.getCtx(), "M_Product_ID"));
 		implosion.setText (Msg.getElement(Env.getCtx(), "Implosion"));
@@ -181,39 +179,47 @@ public class WTreeBOM extends TreeBOM implements IFormController, EventListener<
 		
 		North north = new North();
 		north.appendChild(northPanel);
-		ZKUpdateUtil.setHeight(north, "6%");
+		ZKUpdateUtil.setVflex(north, "min");
 		ZKUpdateUtil.setWidth(northPanel, "100%");
 		mainLayout.appendChild(north);
 
-		Rows rows = northLayout.newRows();
-
-		Row north_row = rows.newRow();
-		north_row.appendChild(labelProduct.rightAlign());
-		north_row.appendChild(fieldProduct.getComponent());
-		north_row.appendChild(new Separator());		
-		north_row.appendChild(implosion);
-		north_row.appendChild(new Space());
-		north_row.appendChild(new Separator());
-		north_row.appendChild(new Space());
-		north_row.appendChild(treeInfo);
+		northLayout.setValign("middle");
+		northLayout.setStyle("padding: 4px;");
+		northLayout.appendChild(labelProduct.rightAlign());
+		if (ClientInfo.maxWidth(ClientInfo.EXTRA_SMALL_WIDTH-1))
+			ZKUpdateUtil.setWidth(fieldProduct.getComponent(), "150px");
+		else if (ClientInfo.maxWidth(ClientInfo.SMALL_WIDTH-1))
+			ZKUpdateUtil.setWidth(fieldProduct.getComponent(), "200px");
+		else if (ClientInfo.minWidth(ClientInfo.MEDIUM_WIDTH))
+			ZKUpdateUtil.setWidth(fieldProduct.getComponent(), "400px");
+		else
+			ZKUpdateUtil.setWidth(fieldProduct.getComponent(), "300px");
+		northLayout.appendChild(fieldProduct.getComponent());
+		northLayout.appendChild(new Space());
+		northLayout.appendChild(implosion);
+		northLayout.appendChild(new Space());
+		northLayout.appendChild(treeInfo);
+		if (ClientInfo.maxWidth(ClientInfo.SMALL_WIDTH-1))
+			treeInfo.setVisible(false);
 		
 		treeExpand.setText(Msg.getMsg(Env.getCtx(), "ExpandTree"));
 
 		South south = new South();
 		south.appendChild(southPanel);
-		ZKUpdateUtil.setHeight(south, "10%");
+		ZKUpdateUtil.setVflex(south, "min");
 		ZKUpdateUtil.setWidth(southPanel, "100%");
 		mainLayout.appendChild(south);
 		
-		Rows rows2 = southLayout.newRows();
-		
-		Row south_row = rows2.newRow();
-
-		south_row.appendChild(treeExpand);
-		south_row.appendChild(new Space());
-		south_row.appendChild(new Separator());
-		south_row.appendChild(new Space());
-		south_row.appendChild(confirmPanel);
+		southLayout.setValign("middle");
+		southLayout.setStyle("padding: 4px");
+		ZKUpdateUtil.setHflex(southLayout, "1");
+		ZKUpdateUtil.setVflex(southLayout, "min");
+		southLayout.appendChild(treeExpand);
+		ZKUpdateUtil.setHflex(treeExpand, "1");
+		treeExpand.setStyle("float: left;");
+		southLayout.appendChild(confirmPanel);
+		ZKUpdateUtil.setHflex(confirmPanel, "1");
+		confirmPanel.setStyle("float: right;");
 		confirmPanel.addActionListener(this);
 		
 		mainLayout.appendChild(west);
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WTreeMaintenance.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WTreeMaintenance.java
index 5c1c94c344..e54166e24f 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WTreeMaintenance.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WTreeMaintenance.java
@@ -20,8 +20,8 @@ import java.util.ArrayList;
 import java.util.logging.Level;
 
 import org.adempiere.util.Callback;
+import org.adempiere.webui.ClientInfo;
 import org.adempiere.webui.LayoutUtils;
-import org.adempiere.webui.component.Button;
 import org.adempiere.webui.component.Checkbox;
 import org.adempiere.webui.component.Label;
 import org.adempiere.webui.component.Listbox;
@@ -29,6 +29,7 @@ import org.adempiere.webui.component.Panel;
 import org.adempiere.webui.component.Searchbox;
 import org.adempiere.webui.component.SimpleListModel;
 import org.adempiere.webui.component.SimpleTreeModel;
+import org.adempiere.webui.component.ToolBarButton;
 import org.adempiere.webui.panel.ADForm;
 import org.adempiere.webui.panel.CustomForm;
 import org.adempiere.webui.panel.IFormController;
@@ -48,12 +49,11 @@ import org.zkoss.zk.ui.event.Event;
 import org.zkoss.zk.ui.event.EventListener;
 import org.zkoss.zk.ui.event.Events;
 import org.zkoss.zul.Borderlayout;
-import org.zkoss.zul.Cell;
 import org.zkoss.zul.Center;
 import org.zkoss.zul.DefaultTreeNode;
-import org.zkoss.zul.Div;
 import org.zkoss.zul.East;
 import org.zkoss.zul.Hbox;
+import org.zkoss.zul.Hlayout;
 import org.zkoss.zul.ListModel;
 import org.zkoss.zul.North;
 import org.zkoss.zul.Space;
@@ -77,12 +77,11 @@ public class WTreeMaintenance extends TreeMaintenance implements IFormController
 	private Panel 			northPanel	= new Panel ();
 	private Label			treeLabel	= new Label ();
 	private Listbox			treeField;
-	private Button			bAddAll		= new Button ();
-	private Button			bAdd		= new Button ();
-	private Button			bDelete		= new Button ();
-	private Button			bDeleteAll	= new Button ();
+	private ToolBarButton	bAddAll		= new ToolBarButton ();
+	private ToolBarButton	bAdd		= new ToolBarButton ();
+	private ToolBarButton	bDelete		= new ToolBarButton ();
+	private ToolBarButton	bDeleteAll	= new ToolBarButton ();
 	private Checkbox		cbAllNodes	= new Checkbox ();
-	private Label			treeInfo	= new Label ();
 	private Searchbox      searchBox   = new Searchbox();
 	//
 	@SuppressWarnings("unused")
@@ -132,33 +131,32 @@ public class WTreeMaintenance extends TreeMaintenance implements IFormController
 		bDelete.setImage(ThemeManager.getThemeResource("images/StepForward24.png"));
 		bDeleteAll.setImage(ThemeManager.getThemeResource("images/FastForward24.png"));
 		
-		ZKUpdateUtil.setWidth(form,"99%");
+		ZKUpdateUtil.setWidth(form,"100%");
 		ZKUpdateUtil.setHeight(form, "100%");
-		form.setStyle("position: absolute; padding: 0; margin: 0");
+		form.setStyle("position: relative; padding: 0; margin: 0");
 		form.appendChild (mainLayout);
 		ZKUpdateUtil.setWidth(mainLayout, "100%");
 		ZKUpdateUtil.setHeight(mainLayout, "100%");
-		mainLayout.setStyle("position: absolute");
 		
 		treeLabel.setText (Msg.translate(Env.getCtx(), "AD_Tree_ID"));
 		cbAllNodes.setEnabled (false);
 		cbAllNodes.setText (Msg.translate(Env.getCtx(), "IsAllNodes"));
-		treeInfo.setText (" ");
 		bAdd.setTooltiptext(Msg.getMsg(Env.getCtx(), "AddToTree"));
 		bAddAll.setTooltiptext(Msg.getMsg(Env.getCtx(), "AddAllToTree"));
 		bDelete.setTooltiptext(Msg.getMsg(Env.getCtx(), "DeleteFromTree"));
 		bDeleteAll.setTooltiptext(Msg.getMsg(Env.getCtx(), "DeleteAllFromTree"));
-		bAdd.addActionListener(this);
-		bAddAll.addActionListener(this);
-		bDelete.addActionListener(this);
-		bDeleteAll.addActionListener(this);
+		bAdd.addEventListener(Events.ON_CLICK, this);
+		bAddAll.addEventListener(Events.ON_CLICK, this);
+		bDelete.addEventListener(Events.ON_CLICK, this);
+		bDeleteAll.addEventListener(Events.ON_CLICK, this);
 		
 		North north = new North();
 		mainLayout.appendChild(north);
 		north.appendChild(northPanel);
 		ZKUpdateUtil.setHflex(north, "1");
-		ZKUpdateUtil.setVflex(north, "1");
+		ZKUpdateUtil.setVflex(north, "min");
 		ZKUpdateUtil.setWidth(northPanel, "100%");
+		ZKUpdateUtil.setVflex(northPanel, "min");
 		//
 		Hbox hbox = new Hbox();
 		hbox.setStyle("padding: 3px;");
@@ -167,31 +165,43 @@ public class WTreeMaintenance extends TreeMaintenance implements IFormController
 		ZKUpdateUtil.setVflex(hbox, "1");
 		northPanel.appendChild(hbox);
 		
-		hbox.appendChild (new Space());
+		if (ClientInfo.maxWidth(ClientInfo.EXTRA_SMALL_WIDTH-1))
+			treeField.setStyle("max-width: 200px");
 		hbox.appendChild (treeLabel);
 		hbox.appendChild (treeField);
 		hbox.appendChild (new Space());
-		hbox.appendChild (cbAllNodes);
-		hbox.appendChild (new Space());
-		Cell cell = new Cell();
-		cell.setColspan(1);
-		cell.setRowspan(1);
-		ZKUpdateUtil.setHflex(cell, "1");
-		cell.appendChild(treeInfo);
-		hbox.appendChild (cell);
-		hbox.appendChild (new Space());
+		hbox.appendChild (cbAllNodes);		
 
-		Div div = new Div();
+		if (ClientInfo.maxWidth(ClientInfo.SMALL_WIDTH-1))
+		{
+			hbox = new Hbox();
+			hbox.setAlign("center");
+			hbox.setStyle("padding-top: 3px; padding-bottom: 3px;");
+			ZKUpdateUtil.setWidth(hbox, "100%");
+			ZKUpdateUtil.setVflex(hbox, "min");
+			northPanel.appendChild(hbox);
+		}
+		else
+		{
+			hbox.appendChild (new Space());
+		}
+		
+		Hlayout div = new Hlayout();
 		div.appendChild (bAddAll);
 		div.appendChild (bAdd);
 		div.appendChild (bDelete);
 		div.appendChild (bDeleteAll);
+		ZKUpdateUtil.setVflex(div, "min");
 
 		searchBox.addEventListener(Events.ON_CLICK, this);
 		searchBox.getTextbox().addEventListener(Events.ON_OK, this);
 		searchBox.getButton().setImage(ThemeManager.getThemeResource("images/Find16.png"));
 		searchBox.setToolTipText(Msg.getCleanMsg(Env.getCtx(), "TreeSearch"));
-		ZKUpdateUtil.setWidth(searchBox, "200px");
+		if (ClientInfo.maxWidth(ClientInfo.SMALL_WIDTH-1))
+			ZKUpdateUtil.setHflex(searchBox, "1");
+		else
+			ZKUpdateUtil.setWidth(searchBox, "200px");
+		ZKUpdateUtil.setVflex(searchBox, "min");
 		div.appendChild(searchBox);
 		hbox.appendChild(div);
 		//
@@ -289,10 +299,10 @@ public class WTreeMaintenance extends TreeMaintenance implements IFormController
 		//	Tree
 		m_tree = new MTree (Env.getCtx(), tree.getKey(), null);
 		cbAllNodes.setSelected(m_tree.isAllNodes());
-		bAddAll.setEnabled(!m_tree.isAllNodes());
-		bAdd.setEnabled(!m_tree.isAllNodes());
-		bDelete.setEnabled(!m_tree.isAllNodes());
-		bDeleteAll.setEnabled(!m_tree.isAllNodes());
+		bAddAll.setDisabled(m_tree.isAllNodes());
+		bAdd.setDisabled(m_tree.isAllNodes());
+		bDelete.setDisabled(m_tree.isAllNodes());
+		bDeleteAll.setDisabled(m_tree.isAllNodes());
 		
 		//	List
 		SimpleListModel model = new SimpleListModel();
@@ -356,7 +366,7 @@ public class WTreeMaintenance extends TreeMaintenance implements IFormController
 				Treeitem ti = centerTree.renderItemByPath(path);
 				ti.setSelected(true);
 			}
-			bAdd.setEnabled(stn == null);
+			bAdd.setDisabled(stn != null);
 		}
 	}	//	valueChanged
 	
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WTrxMaterial.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WTrxMaterial.java
index 4c813a777d..17a9f458c4 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WTrxMaterial.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/form/WTrxMaterial.java
@@ -20,6 +20,7 @@ import java.sql.Timestamp;
 import java.util.Properties;
 import java.util.logging.Level;
 
+import org.adempiere.webui.ClientInfo;
 import org.adempiere.webui.LayoutUtils;
 import org.adempiere.webui.adwindow.ADTabpanel;
 import org.adempiere.webui.apps.AEnv;
@@ -55,7 +56,6 @@ import org.zkoss.zul.Borderlayout;
 import org.zkoss.zul.Center;
 import org.zkoss.zul.North;
 import org.zkoss.zul.South;
-import org.zkoss.zul.Separator;
 
 /**
  * Material Transaction History
@@ -92,6 +92,8 @@ public class WTrxMaterial extends TrxMaterial
 	private ConfirmPanel confirmPanel = new ConfirmPanel(true, true, false, false, false, true, false);
 	private StatusBarPanel statusBar = new StatusBarPanel();
 
+	private int noOfColumns;
+
 
 	/**
 	 *	Initialize Panel
@@ -104,7 +106,9 @@ public class WTrxMaterial extends TrxMaterial
 			m_WindowNo = form.getWindowNo();
 			dynParameter();
 			zkInit();
-			dynInit();			
+			dynInit();		
+			if (ClientInfo.isMobile())
+				ClientInfo.onClientInfo(form, this::onClientInfo);
 		}
 		catch(Exception ex)
 		{
@@ -119,7 +123,7 @@ public class WTrxMaterial extends TrxMaterial
 	void zkInit() throws Exception
 	{
 		form.appendChild(mainPanel);
-		mainPanel.setStyle("width: 99%; height: 100%; border: none; padding: 0; margin: 0");
+		mainPanel.setStyle("width: 100%; height: 100%; border: none; padding: 0; margin: 0");
 		mainPanel.appendChild(mainLayout);
 		ZKUpdateUtil.setWidth(mainLayout, "100%");
 		ZKUpdateUtil.setHeight(mainLayout, "100%");
@@ -135,39 +139,85 @@ public class WTrxMaterial extends TrxMaterial
 		North north = new North();
 		mainLayout.appendChild(north);
 		north.appendChild(parameterPanel);
+		north.setSplittable(true);
+		north.setCollapsible(true);
+		north.setAutoscroll(true);
+		LayoutUtils.addSlideSclass(north);
 		
-		Rows rows = parameterLayout.newRows();
-		Row row = rows.newRow();
-		row.appendCellChild(orgLabel.rightAlign());
-		ZKUpdateUtil.setHflex(orgField.getComponent(), "true");
-		row.appendCellChild(orgField.getComponent());
-		row.appendCellChild(mtypeLabel.rightAlign());
-		ZKUpdateUtil.setHflex(mtypeField.getComponent(), "true");
-		row.appendCellChild(mtypeField.getComponent());
-		row.appendCellChild(dateFLabel.rightAlign());
-		row.appendCellChild(dateFField.getComponent());
-
-		row = rows.newRow();
-		row.appendCellChild(locatorLabel.rightAlign());
-		ZKUpdateUtil.setHflex(locatorField.getComponent(), "true");
-		row.appendCellChild(locatorField.getComponent());
-		row.appendCellChild(productLabel.rightAlign());
-		ZKUpdateUtil.setHflex(productField.getComponent(), "true");
-		row.appendCellChild(productField.getComponent());
-		row.appendCellChild(dateTLabel.rightAlign());
-		row.appendCellChild(dateTField.getComponent());
+		layoutParameters();
 		//
 		southPanel.appendChild(confirmPanel);
-		southPanel.appendChild(new Separator());
 		southPanel.appendChild(statusBar);
 		South south = new South();
 		south.setStyle("border: none");
 		mainLayout.appendChild(south);
 		south.appendChild(southPanel);
+		ZKUpdateUtil.setHeight(southPanel, "64px");
+		ZKUpdateUtil.setHeight(south, "64px");
+		ZKUpdateUtil.setHeight(confirmPanel, "32px");
+		ZKUpdateUtil.setHeight(statusBar, "32px");
+		
+		ZKUpdateUtil.setWidth(southPanel, "100%");
+		ZKUpdateUtil.setWidth(confirmPanel, "100%");
+		ZKUpdateUtil.setWidth(statusBar, "100%");
 		
 		LayoutUtils.addSclass("status-border", statusBar);
 	}   //  jbInit
 
+	protected void layoutParameters() {
+		noOfColumns = 6;
+		if (ClientInfo.maxWidth(639))
+			noOfColumns = 2;
+		else if (ClientInfo.maxWidth(ClientInfo.MEDIUM_WIDTH-1))
+			noOfColumns = 4;
+		
+		int childCnt = 0;
+		Rows rows = parameterLayout.newRows();
+		Row row = rows.newRow();
+		row.appendCellChild(orgLabel.rightAlign());
+		ZKUpdateUtil.setHflex(orgField.getComponent(), "true");
+		row.appendCellChild(orgField.getComponent());
+		childCnt += 2;
+		if ((childCnt % noOfColumns) ==0 )
+			row = rows.newRow();
+		row.appendCellChild(mtypeLabel.rightAlign());
+		ZKUpdateUtil.setHflex(mtypeField.getComponent(), "true");
+		row.appendCellChild(mtypeField.getComponent());
+		childCnt += 2;
+		if ((childCnt % noOfColumns) ==0 )
+			row = rows.newRow();
+		if (noOfColumns == 6)
+		{
+			row.appendCellChild(dateFLabel.rightAlign());
+			row.appendCellChild(dateFField.getComponent());
+			childCnt += 2;
+			if ((childCnt % noOfColumns) ==0 )
+				row = rows.newRow();
+		}
+		row.appendCellChild(locatorLabel.rightAlign());
+		ZKUpdateUtil.setHflex(locatorField.getComponent(), "true");		
+		row.appendCellChild(locatorField.getComponent());
+		childCnt += 2;
+		if ((childCnt % noOfColumns) ==0 )
+			row = rows.newRow();
+		row.appendCellChild(productLabel.rightAlign());
+		ZKUpdateUtil.setHflex(productField.getComponent(), "true");
+		row.appendCellChild(productField.getComponent());
+		childCnt +=2;
+		if ((childCnt % noOfColumns) ==0 )
+			row = rows.newRow();
+		if (noOfColumns < 6)
+		{
+			row.appendCellChild(dateFLabel.rightAlign());
+			row.appendCellChild(dateFField.getComponent());
+			childCnt += 2;
+			if ((childCnt % noOfColumns) ==0 )
+				row = rows.newRow();
+		}
+		row.appendCellChild(dateTLabel.rightAlign());
+		row.appendCellChild(dateTField.getComponent());
+	}
+
 	/**
 	 *  Initialize Parameter fields
 	 *  @throws Exception if Lookups cannot be initialized
@@ -269,6 +319,8 @@ public class WTrxMaterial extends TrxMaterial
 		Timestamp movementDateTo = (Timestamp)dateTField.getValue();
 		
 		refresh(organization, locator, product, movementType, movementDateFrom, movementDateTo, statusBar);
+		if (ClientInfo.maxHeight(ClientInfo.MEDIUM_HEIGHT-1))
+			mainLayout.getNorth().setOpen(false);
 	}   //  refresh
 
 	/**
@@ -287,4 +339,21 @@ public class WTrxMaterial extends TrxMaterial
 		return form;
 	}
 
+	protected void onClientInfo() 
+	{
+		if (noOfColumns > 0 && parameterLayout.getRows() != null)
+		{
+			int n = 6;
+			if (ClientInfo.maxWidth(639))
+				n = 2;
+			else if (ClientInfo.maxWidth(ClientInfo.MEDIUM_WIDTH-1))
+				n = 4;
+			if (n != noOfColumns)
+			{
+				parameterLayout.getRows().detach();
+				layoutParameters();
+				form.invalidate();
+			}
+		}
+	}
 }   //  VTrxMaterial
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/graph/WGraph.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/graph/WGraph.java
index 3cf72dc072..7006a6000a 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/graph/WGraph.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/graph/WGraph.java
@@ -22,6 +22,7 @@ import java.util.List;
 
 import org.adempiere.apps.graph.GraphColumn;
 import org.adempiere.base.Service;
+import org.adempiere.webui.ClientInfo;
 import org.adempiere.webui.apps.AEnv;
 import org.adempiere.webui.apps.graph.model.GoalModel;
 import org.adempiere.webui.editor.WTableDirEditor;
@@ -181,7 +182,7 @@ public class WGraph extends Div implements IdSpace {
 		if (m_renderTable && m_renderChart) {
 			layout = new Borderlayout();
 			appendChild(layout);
-			layout.setStyle("height: 100%; width: 100%; position: absolute;");
+			layout.setStyle("height: 100%; width: 100%; position: relative;");
 			Center center = new Center();
 			layout.appendChild(center);
 			center.appendChild(panel);
@@ -196,6 +197,11 @@ public class WGraph extends Div implements IdSpace {
 			if (m_renderChart) {
 				East east = new East();
 				east.setAutoscroll(true);
+				if (ClientInfo.maxWidth(ClientInfo.MEDIUM_WIDTH-1)) {
+					east.setOpen(false);
+					east.setSplittable(true);
+					east.setCollapsible(true);
+				}
 				layout.appendChild(east);
 				renderTable(east);
 			} else {
@@ -251,12 +257,17 @@ public class WGraph extends Div implements IdSpace {
 	private void renderChart(String type) {
 		int width = 560;
 		int height = 400;
+		if (ClientInfo.maxWidth(width-1)) {
+			width = ClientInfo.get().desktopWidth;
+			height = (int)(width * (400f / 560f));
+		}
 		if (panel.getPanelchildren() != null) {
 			panel.getPanelchildren().getChildren().clear();
 		} else {
 			Panelchildren pc = new Panelchildren();
 			panel.appendChild(pc);
 		}
+		panel.getPanelchildren().setStyle("overflow: auto;");
 		GoalModel goalModel = new GoalModel();
 		goalModel.goal = m_goal;
 		goalModel.chartType = type != null ? type : m_goal.getChartType();
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/ConfirmPanel.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/ConfirmPanel.java
index cc8d9a28ab..1e2ddf530c 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/ConfirmPanel.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/ConfirmPanel.java
@@ -22,9 +22,11 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
+import org.adempiere.webui.LayoutUtils;
 import org.adempiere.webui.factory.ButtonFactory;
 import org.adempiere.webui.theme.ThemeManager;
 import org.adempiere.webui.util.ZKUpdateUtil;
+import org.compiere.util.Util;
 import org.zkoss.zk.ui.event.EventListener;
 import org.zkoss.zk.ui.event.Events;
 import org.zkoss.zul.Div;
@@ -106,6 +108,8 @@ public final class ConfirmPanel extends Div
         Button button = ButtonFactory.createNamedButton(name, m_withText, m_withImage);        
         button.setId(name);
         buttonMap.put(name, button);
+        if (!Util.isEmpty(extraButtonSClass))
+        	LayoutUtils.addSclass(extraButtonSClass, button);
 
         return button;
     }
@@ -226,6 +230,8 @@ public final class ConfirmPanel extends Div
     // IDEMPIERE-1334 center panel, contain all process button
     private Hlayout pnlBtnCenter;
 
+	private String extraButtonSClass;
+
     /**
      * initialise components
      */
@@ -523,4 +529,16 @@ public final class ConfirmPanel extends Div
 		return getButton(A_OK);
 	}
 
+	public void addButtonSclass(String cls) {
+		for(Button btn : buttonMap.values()) {
+			LayoutUtils.addSclass(cls, btn);
+		}
+		extraButtonSClass = cls;
+	}
+	
+	public void removeButtonSclass(String cls) {
+		for(Button btn : buttonMap.values()) {
+			LayoutUtils.removeSclass(cls, btn);
+		}
+	}
 }   //  ConfirmPanel
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/FolderBrowser.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/FolderBrowser.java
index 48a3dd3613..8076b6173c 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/FolderBrowser.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/FolderBrowser.java
@@ -81,8 +81,8 @@ public class FolderBrowser extends Window implements EventListener
 		this.browseForFolder = browseForFolder;
 
 		setTitle(browseForFolder ? "Directory Browser" : "File Browser");
-		ZKUpdateUtil.setWidth(this, "500px");
-		ZKUpdateUtil.setHeight(this, "500px");
+		ZKUpdateUtil.setWindowWidthX(this, 500);
+		ZKUpdateUtil.setWindowHeightX(this, 500);
 		setBorder("normal");
 		
 		Borderlayout contentLayout = new Borderlayout();
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/Messagebox.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/Messagebox.java
index 0834be083d..525a6b34e9 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/Messagebox.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/Messagebox.java
@@ -21,6 +21,7 @@ import java.util.Properties;
 
 import org.adempiere.util.Callback;
 import org.adempiere.webui.AdempiereIdGenerator;
+import org.adempiere.webui.ClientInfo;
 import org.adempiere.webui.apps.AEnv;
 import org.adempiere.webui.factory.ButtonFactory;
 import org.adempiere.webui.session.SessionManager;
@@ -54,6 +55,7 @@ public class Messagebox extends Window implements EventListener
 	private static final long serialVersionUID = 8928526331932742124L;
 
 	private static final String MESSAGE_PANEL_STYLE = "text-align:left; word-break: break-all; overflow: auto; max-height: 350pt; min-width: 230pt; max-width: 450pt;";	
+	private static final String SMALLER_MESSAGE_PANEL_STYLE = "text-align:left; word-break: break-all; overflow: auto; max-height: 350pt; min-width: 180pt; ";
 	private String msg = new String("");
 	private String imgSrc = new String("");
 
@@ -126,6 +128,7 @@ public class Messagebox extends Window implements EventListener
 		Properties ctx = Env.getCtx();
 		lblMsg.setEncode(false);
 		lblMsg.setValue(msg);
+		lblMsg.setClientAttribute("style", "word-break: normal;");
 		// Invert - Unify  OK/Cancel IDEMPIERE-77
 		btnOk = ButtonFactory.createNamedButton(ConfirmPanel.A_OK);
 		btnOk.setId("btnOk");
@@ -162,8 +165,15 @@ public class Messagebox extends Window implements EventListener
 		btnIgnore.setId("btnIgnore");
 
 		Panel pnlMessage = new Panel();
-		pnlMessage.setStyle(MESSAGE_PANEL_STYLE);
+		if (ClientInfo.maxWidth(399))
+		{
+			pnlMessage.setStyle(SMALLER_MESSAGE_PANEL_STYLE);
+			this.setWidth("100%");
+		}
+		else
+			pnlMessage.setStyle(MESSAGE_PANEL_STYLE);
 		pnlMessage.appendChild(lblMsg);
+		ZKUpdateUtil.setHflex(pnlMessage, "min");
 		
 		Panel pnlInput= new Panel();
 		pnlInput.setStyle(MESSAGE_PANEL_STYLE);
@@ -188,6 +198,7 @@ public class Messagebox extends Window implements EventListener
 		north.appendChild(pnlImage);
 		north.appendChild(pnlText);
 		north.setSclass("dialog-content");
+		north.setWidth("100%");;
 
 		Hbox pnlButtons = new Hbox();
 		pnlButtons.setAlign("center");
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/NumberBox.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/NumberBox.java
index 00fd1315db..f44a66d4b9 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/NumberBox.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/NumberBox.java
@@ -21,6 +21,7 @@ import java.math.BigDecimal;
 import java.text.NumberFormat;
 import java.text.ParseException;
 
+import org.adempiere.webui.ClientInfo;
 import org.adempiere.webui.LayoutUtils;
 import org.adempiere.webui.theme.ThemeManager;
 import org.adempiere.webui.util.ZKUpdateUtil;
@@ -87,7 +88,7 @@ public class NumberBox extends Div
     	ZKUpdateUtil.setHflex(decimalBox, "0");
     	decimalBox.setSclass("editor-input");
         decimalBox.setId(decimalBox.getUuid());
-
+        
         char separatorChar = DisplayType.getNumberFormat(DisplayType.Number, Env.getLanguage(Env.getCtx())).getDecimalFormatSymbols().getDecimalSeparator();
         String separator = Character.toString(separatorChar);
         boolean processDotKeypad = MSysConfig.getBooleanValue(MSysConfig.ZK_DECIMALBOX_PROCESS_DOTKEYPAD, true, Env.getAD_Client_ID(Env.getCtx()));
@@ -138,6 +139,13 @@ public class NumberBox extends Div
      
         LayoutUtils.addSclass("number-box", this);	     
         LayoutUtils.addSclass("editor-box", this);
+        
+        if (ClientInfo.isMobile())
+        {
+        	LayoutUtils.addSclass("mobile", decimalBox);
+        	btn.setVisible(false);
+        }
+
     }
     
     /**
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/SimpleTreeModel.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/SimpleTreeModel.java
index a477f557a2..ae3cb8b2d0 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/SimpleTreeModel.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/SimpleTreeModel.java
@@ -18,6 +18,7 @@ import java.util.Enumeration;
 import java.util.List;
 import java.util.logging.Level;
 
+import org.adempiere.webui.ClientInfo;
 import org.compiere.model.MTree;
 import org.compiere.model.MTreeNode;
 import org.compiere.util.CLogger;
@@ -160,12 +161,16 @@ public class SimpleTreeModel extends org.zkoss.zul.DefaultTreeModel impl
 		if(ti.getTreerow()==null){
 			tr = new Treerow();			
 			tr.setParent(ti);
-			if (isItemDraggable()) {
-				tr.setDraggable("true");
-			}
-			if (!onDropListners.isEmpty()) {
-				tr.setDroppable("true");
-				tr.addEventListener(Events.ON_DROP, this);
+			//zk's dnd doesn't work well on touch device with vertical scroll enable
+			//need different approach
+			if (!ClientInfo.isMobile()) {
+				if (isItemDraggable()) {
+					tr.setDraggable("true");
+				}
+				if (!onDropListners.isEmpty()) {
+					tr.setDroppable("true");
+					tr.addEventListener(Events.ON_DROP, this);
+				}
 			}
 
 			// Color
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/Tabbox.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/Tabbox.java
index dadd2efade..dff33cb2f9 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/Tabbox.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/Tabbox.java
@@ -45,6 +45,7 @@ public class Tabbox extends org.zkoss.zul.Tabbox implements EventListener
 	private static final long serialVersionUID = 1400484283064851775L;
 	private boolean isSupportTabDragDrop = false;
 	private boolean isActiveBySeq = false;
+	private boolean isCheckVisibleOnlyForNextActive = true;
 
 	private Deque activeTabSeq = new ArrayDeque<>();
 	public Tabbox () {
@@ -140,7 +141,7 @@ public class Tabbox extends org.zkoss.zul.Tabbox implements EventListener
 	public Tab getNextActiveBySeq (Tab currentTab) {
 		Tab cadidateTabActive = null;
 		while ((cadidateTabActive = activeTabSeq.peek()) != null) {
-			boolean canNotActive = cadidateTabActive.isDisabled() || !cadidateTabActive.isVisible();
+			boolean canNotActive = cadidateTabActive.isDisabled() || (!cadidateTabActive.isVisible() && isCheckVisibleOnlyForNextActive());
 			if (canNotActive) {
 				// move disable item to last stack it can be active late
 				cadidateTabActive = activeTabSeq.pop();
@@ -163,4 +164,16 @@ public class Tabbox extends org.zkoss.zul.Tabbox implements EventListener
 	public void removeTabFromActiveSeq (Tab closeTab) {
 		activeTabSeq.remove(closeTab);
 	}
+	
+	public boolean isCheckVisibleOnlyForNextActive() {
+		return isCheckVisibleOnlyForNextActive;
+	}
+	
+	/**
+	 * Ignore invisible tab for next active by seq
+	 * @param isVisibleOnly
+	 */
+	public void setCheckVisibleOnlyForNextActive(boolean isVisibleOnly) {
+		isCheckVisibleOnlyForNextActive = isVisibleOnly;
+	}
 }
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/WListItemRenderer.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/WListItemRenderer.java
index e64d254040..e8e9931174 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/WListItemRenderer.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/WListItemRenderer.java
@@ -32,6 +32,7 @@ import java.util.List;
 import java.util.Set;
 
 import org.adempiere.webui.AdempiereWebUI;
+import org.adempiere.webui.ClientInfo;
 import org.adempiere.webui.apps.AEnv;
 import org.adempiere.webui.event.TableValueChangeEvent;
 import org.adempiere.webui.event.TableValueChangeListener;
@@ -279,8 +280,10 @@ public class WListItemRenderer implements ListitemRenderer, EventListene
 						numberbox.setEnabled(true);
 						numberbox.setStyle("text-align:right; width: 96%;"
 										+ listcell.getStyle());
-						numberbox.addEventListener(Events.ON_CHANGE, this);
+						numberbox.addEventListener(Events.ON_CHANGE, this);						
 						listcell.appendChild(numberbox);
+						if (ClientInfo.isMobile())
+							numberbox.getButton().setVisible(false);
 					}
 					else
 					{
@@ -461,6 +464,8 @@ public class WListItemRenderer implements ListitemRenderer, EventListene
         	{
         		header = new ListHeader("");
         		ZKUpdateUtil.setWidth(header, "30px");
+        		header.setAlign("center");
+        		header.setValign("middle");
         	}
         	else
         	{
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/Window.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/Window.java
index 0e083db3f0..a3caa9fdef 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/Window.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/component/Window.java
@@ -17,6 +17,8 @@
 
 package org.adempiere.webui.component;
 
+import java.util.Collection;
+
 import org.adempiere.webui.ISupportMask;
 import org.adempiere.webui.ShowMaskWrapper;
 import org.adempiere.webui.event.DialogEvents;
@@ -25,6 +27,7 @@ import org.zkoss.zk.ui.Executions;
 import org.zkoss.zk.ui.Page;
 import org.zkoss.zk.ui.event.Event;
 import org.zkoss.zk.ui.event.Events;
+import org.zkoss.zk.ui.util.Callback;
 
 /**
  *
@@ -76,6 +79,7 @@ public class Window extends org.zkoss.zul.Window implements ISupportMask
 	/* (non-Javadoc)
 	 * @see org.zkoss.zul.Window#onPageDetached(org.zkoss.zk.ui.Page)
 	 */
+	@SuppressWarnings({ "rawtypes", "unchecked" })
 	@Override
 	public void onPageDetached(Page page) {
 		super.onPageDetached(page);
@@ -83,8 +87,14 @@ public class Window extends org.zkoss.zul.Window implements ISupportMask
 				Executions.getCurrent().getDesktop().getExecution() != null) {
 			Events.sendEvent(this, new Event(DialogEvents.ON_WINDOW_CLOSE, this, null));
 		}
+		//org.zkoss.zul.Window.onPageDetached doesn't call super.onPageDetached, bug ?
+		Collection callbacks = getCallback(AFTER_PAGE_DETACHED);
+		for (Callback callback : callbacks) {
+			callback.call(this);
+		}
 	}
 
+	
 	/**
 	 * Get the window mode attribute
 	 * @return Window.Mode
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/RequestWindow.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/RequestWindow.java
index 7f0d70d2ff..70c78a1756 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/RequestWindow.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/dashboard/RequestWindow.java
@@ -31,6 +31,7 @@ import org.adempiere.webui.component.Rows;
 import org.adempiere.webui.component.Textbox;
 import org.adempiere.webui.component.Window;
 import org.adempiere.webui.editor.WTableDirEditor;
+import org.adempiere.webui.theme.ThemeManager;
 import org.adempiere.webui.util.ZKUpdateUtil;
 import org.adempiere.webui.window.FDialog;
 import org.compiere.model.MColumn;
@@ -47,7 +48,7 @@ import org.zkoss.zk.ui.WrongValueException;
 import org.zkoss.zk.ui.event.Event;
 import org.zkoss.zk.ui.event.EventListener;
 import org.zkoss.zk.ui.event.Events;
-import org.zkoss.zul.North;
+import org.zkoss.zul.Center;
 import org.zkoss.zul.South;
 import org.zkoss.zul.Timebox;
 
@@ -87,8 +88,16 @@ public class RequestWindow extends Window implements EventListener {
 		Properties ctx = Env.getCtx();
 		setTitle(Msg.getMsg(Env.getCtx(),"Event"));
 		setAttribute(Window.MODE_KEY, Window.MODE_HIGHLIGHTED);
-		ZKUpdateUtil.setWidth(this, "400px");
-		this.setSclass("popup-dialog");
+		if (!ThemeManager.isUseCSSForWindowSize()) {
+			ZKUpdateUtil.setWindowWidthX(this, 400);
+			ZKUpdateUtil.setWindowHeightX(this, 550);
+		} else {
+			addCallback(AFTER_PAGE_ATTACHED, t -> {
+				ZKUpdateUtil.setCSSHeight(this);
+				ZKUpdateUtil.setCSSWidth(this);
+			});
+		}
+		this.setSclass("popup-dialog request-dialog");
 		this.setBorder("normal");
 		this.setShadow(true);
 		this.setClosable(true);
@@ -248,16 +257,17 @@ public class RequestWindow extends Window implements EventListener {
 		Borderlayout borderlayout = new Borderlayout();
 		this.appendChild(borderlayout);
 		ZKUpdateUtil.setHflex(borderlayout, "1");
-		ZKUpdateUtil.setVflex(borderlayout, "min");
+		ZKUpdateUtil.setVflex(borderlayout, "1");
 		
-		North northPane = new North();
-		northPane.setSclass("dialog-content");
-		northPane.setAutoscroll(true);
-		borderlayout.appendChild(northPane);
+		Center centerPane = new Center();
+		centerPane.setSclass("dialog-content");
+		centerPane.setAutoscroll(true);
+		borderlayout.appendChild(centerPane);
 		
-		northPane.appendChild(grid);
-		ZKUpdateUtil.setVflex(grid, "1");
+		centerPane.appendChild(grid);
+		ZKUpdateUtil.setVflex(grid, "min");
 		ZKUpdateUtil.setHflex(grid, "1");
+		ZKUpdateUtil.setVflex(centerPane, "min");
 
 		South southPane = new South();
 		southPane.setSclass("dialog-footer");
@@ -353,5 +363,5 @@ public class RequestWindow extends Window implements EventListener {
 		} else {
 			return false;
 		}	
-	}
+	}	
 }
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/desktop/DashboardController.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/desktop/DashboardController.java
index 8f68320a3e..1d18995526 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/desktop/DashboardController.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/desktop/DashboardController.java
@@ -28,6 +28,7 @@ import java.util.logging.Level;
 
 import org.adempiere.base.Service;
 import org.adempiere.exceptions.AdempiereException;
+import org.adempiere.webui.ClientInfo;
 import org.adempiere.webui.apps.AEnv;
 import org.adempiere.webui.apps.graph.IChartRendererService;
 import org.adempiere.webui.apps.graph.WGraph;
@@ -63,6 +64,7 @@ import org.zkoss.util.media.AMedia;
 import org.zkoss.zk.ui.Component;
 import org.zkoss.zk.ui.Desktop;
 import org.zkoss.zk.ui.Executions;
+import org.zkoss.zk.ui.HtmlBasedComponent;
 import org.zkoss.zk.ui.Page;
 import org.zkoss.zk.ui.event.AfterSizeEvent;
 import org.zkoss.zk.ui.event.DropEvent;
@@ -91,16 +93,19 @@ import org.zkoss.zul.Vlayout;
  */
 public class DashboardController implements EventListener {
 
+	private static final String PANEL_EMPTY_ATTR = "panel.empty";
 	private final static CLogger logger = CLogger.getCLogger(DashboardController.class);
 	private Component prevParent;
 	private Component prevNext;
 
 	private List panelList = new ArrayList();
-	private List columnList = new ArrayList();
+	private List columnList;
 	private Anchorlayout dashboardLayout;
 	private Anchorchildren maximizedHolder;	
 	private DashboardRunnable dashboardRunnable;
 	private Timer dashboardTimer;
+	private boolean isShowInDashboard;
+	private int noOfCols;
 	
 	private final static int DEFAULT_DASHBOARD_WIDTH = 95;
 	
@@ -116,13 +121,24 @@ public class DashboardController implements EventListener {
 	}
 	
 	public void render(Component parent, IDesktop desktopImpl, boolean isShowInDashboard) {
-		parent.appendChild(dashboardLayout);
+		render(parent, desktopImpl, isShowInDashboard, false);
+	}
+	
+	protected void render(Component parent, IDesktop desktopImpl, boolean isShowInDashboard, boolean update) {
+		this.isShowInDashboard = isShowInDashboard;
+		if (!update)
+			parent.appendChild(dashboardLayout);
+		if (!update && isShowInDashboard)
+			((HtmlBasedComponent)parent).setStyle("overflow-x: auto;");
 		dashboardLayout.getChildren().clear();
         
         if (!dashboardLayout.getDesktop().isServerPushEnabled())
         	dashboardLayout.getDesktop().enableServerPush(true);
         
-        dashboardRunnable = new DashboardRunnable(parent.getDesktop());
+        if (!update)
+        	dashboardRunnable = new DashboardRunnable(parent.getDesktop());
+        
+        columnList = new ArrayList();
         
         // Dashboard content
         Vlayout dashboardColumnLayout = null;
@@ -148,7 +164,17 @@ public class DashboardController implements EventListener {
         		}
         	}
         	               
-        	noOfCols = MDashboardPreference.getForSessionColumnCount(isShowInDashboard, AD_User_ID, AD_Role_ID);
+        	noOfCols = MDashboardPreference.getForSessionColumnCount(isShowInDashboard, AD_User_ID, AD_Role_ID);        	
+        	if (ClientInfo.isMobile() && isShowInDashboard) {
+	        	if (ClientInfo.maxWidth(ClientInfo.MEDIUM_WIDTH-1)) {
+	        		if (ClientInfo.maxWidth(ClientInfo.SMALL_WIDTH-1)) {
+	        			noOfCols = 1;
+	        		} else if (noOfCols > 2) {
+	        			noOfCols = 2;
+	        		}
+	        	}
+        	}
+        	this.noOfCols = noOfCols;
             
         	int dashboardWidth = isShowInDashboard ? DEFAULT_DASHBOARD_WIDTH : 100;
             width = noOfCols <= 0 ? dashboardWidth : dashboardWidth / noOfCols;
@@ -164,57 +190,75 @@ public class DashboardController implements EventListener {
             	MDashboardContent dc = new MDashboardContent(dp.getCtx(), dp.getPA_DashboardContent_ID(), dp.get_TrxName());
             	
 	        	int columnNo = dp.getColumnNo();
-	        	if(dashboardColumnLayout == null || currentColumnNo != columnNo)
+	        	int effColumn = columnNo;
+	        	if (effColumn+1 > noOfCols)
+	        		effColumn = noOfCols-1;
+	        	if(dashboardColumnLayout == null || currentColumnNo != effColumn)
 	        	{
 	        		dashboardColumnLayout = new Vlayout();
+	        		dashboardColumnLayout.setSclass("dashboard-column");
 	        		dashboardColumnLayout.setAttribute("ColumnNo", columnNo);
 	        		dashboardColumnLayout.setAttribute("IsShowInDashboard", isShowInDashboard);
 	        		dashboardColumnLayout.setAttribute("IsAdditionalColumn", false);
 	        		Anchorchildren dashboardColumn = new Anchorchildren();
 	        		dashboardColumn.setAnchor(width + "%" + " 100%");
-	        		dashboardColumn.setDroppable("true");
-	        		dashboardColumn.addEventListener(Events.ON_DROP, this);
+	        		if (!ClientInfo.isMobile())
+	        		{
+		        		dashboardColumn.setDroppable("true");
+		        		dashboardColumn.addEventListener(Events.ON_DROP, this);
+	        		}
 	        		dashboardColumn.appendChild(dashboardColumnLayout);
 	        		columnList.add(dashboardColumn);
 	                dashboardLayout.appendChild(dashboardColumn);
 	                ZKUpdateUtil.setHflex(dashboardColumnLayout, "1");
 
-	                currentColumnNo = columnNo;
+	                currentColumnNo = effColumn;
 	        	}
 
-	        	Panel panel = new Panel();
-	        	Caption caption = new Caption(dc.get_Translation(MDashboardContent.COLUMNNAME_Name));
-	        	panel.appendChild(caption);
-	        	panel.setAttribute("PA_DashboardContent_ID", dp.getPA_DashboardContent_ID());
-	        	panel.setAttribute("PA_DashboardPreference_ID", dp.getPA_DashboardPreference_ID());
-	        	panelList.add(panel);
-	        	panel.addEventListener(Events.ON_MAXIMIZE, this);
-	        	panel.setSclass("dashboard-widget");
-	        	panel.setMaximizable(true);
+	        	Panel panel = null;
+	        	if (update) {
+	        		panel = findPanel(dp.getPA_DashboardContent_ID(), dp.getPA_DashboardPreference_ID());
+	        	} else {
+		        	panel = new Panel();
+		        	Caption caption = new Caption(dc.get_Translation(MDashboardContent.COLUMNNAME_Name));
+		        	panel.appendChild(caption);
+		        	panel.setAttribute("PA_DashboardContent_ID", dp.getPA_DashboardContent_ID());
+		        	panel.setAttribute("PA_DashboardPreference_ID", dp.getPA_DashboardPreference_ID());
+		        	panelList.add(panel);
+		        	panel.addEventListener(Events.ON_MAXIMIZE, this);
+		        	panel.setSclass("dashboard-widget");
+		        	panel.setMaximizable(true);	        	
 	        	
-	        	String description = dc.get_Translation(MDashboardContent.COLUMNNAME_Description);
-            	if(description != null)
-            		panel.setTooltiptext(description);
-
-            	panel.setCollapsible(dc.isCollapsible());
-            	panel.setOpen(!dp.isCollapsedByDefault());
-            	panel.addEventListener(Events.ON_OPEN, this);
-            	
-            	panel.setDroppable("true");
-            	panel.getCaption().setDraggable("true");
-            	panel.addEventListener(Events.ON_DROP, this);
-
-	        	panel.setBorder("normal");
-	        	dashboardColumnLayout.appendChild(panel);
-	            Panelchildren content = new Panelchildren();
-	            panel.appendChild(content);
-
-	            boolean panelEmpty = true;
-
-	            panelEmpty = !render(content, dc, dashboardRunnable);	            		
-	        	
-	        	if (panelEmpty)
-	        		panel.detach();	        	
+		        	String description = dc.get_Translation(MDashboardContent.COLUMNNAME_Description);
+	            	if(description != null)
+	            		panel.setTooltiptext(description);
+	
+	            	panel.setCollapsible(dc.isCollapsible());
+	            	panel.setOpen(!dp.isCollapsedByDefault());
+	            	panel.addEventListener(Events.ON_OPEN, this);
+	            	
+	            	if (!ClientInfo.isMobile()) {
+	            		panel.setDroppable("true");
+	            		panel.getCaption().setDraggable("true");	            	
+	            		panel.addEventListener(Events.ON_DROP, this);
+	            	}
+		        	panel.setBorder("normal");
+	        	}
+	        	if (panel != null && panel.getAttribute(PANEL_EMPTY_ATTR) == null)
+	        		dashboardColumnLayout.appendChild(panel);
+	        	if (!update) {
+		            Panelchildren content = new Panelchildren();
+		            panel.appendChild(content);
+	
+		            boolean panelEmpty = true;
+	
+		            panelEmpty = !render(content, dc, dashboardRunnable);	            		
+		        	
+		        	if (panelEmpty) {
+		        		panel.detach();
+		        		panel.setAttribute(PANEL_EMPTY_ATTR, Boolean.TRUE);
+		        	}
+	        	}
 	        }
             
             if (dps.length == 0)
@@ -225,8 +269,11 @@ public class DashboardController implements EventListener {
         		dashboardColumnLayout.setAttribute("IsAdditionalColumn", true);
         		Anchorchildren dashboardColumn = new Anchorchildren();
         		dashboardColumn.setAnchor((width-5) + "%" + " 100%");
-        		dashboardColumn.setDroppable("true");
-        		dashboardColumn.addEventListener(Events.ON_DROP, this);
+        		if (!ClientInfo.isMobile())
+        		{
+        			dashboardColumn.setDroppable("true");
+        			dashboardColumn.addEventListener(Events.ON_DROP, this);
+        		}
         		dashboardColumn.appendChild(dashboardColumnLayout);
         		columnList.add(dashboardColumn);
                 dashboardLayout.appendChild(dashboardColumn);
@@ -242,8 +289,11 @@ public class DashboardController implements EventListener {
         		dashboardColumnLayout.setAttribute("IsAdditionalColumn", true);
         		Anchorchildren dashboardColumn = new Anchorchildren();
         		dashboardColumn.setAnchor(extraWidth + "% 100%");
-        		dashboardColumn.setDroppable("true");
-        		dashboardColumn.addEventListener(Events.ON_DROP, this);
+        		if (!ClientInfo.isMobile())
+        		{
+        			dashboardColumn.setDroppable("true");
+        			dashboardColumn.addEventListener(Events.ON_DROP, this);
+        		}
         		dashboardColumn.appendChild(dashboardColumnLayout);
         		columnList.add(dashboardColumn);
                 dashboardLayout.appendChild(dashboardColumn);
@@ -256,7 +306,7 @@ public class DashboardController implements EventListener {
 		}
         //
                 
-        if (!dashboardRunnable.isEmpty())
+        if (!update && !dashboardRunnable.isEmpty())
         {
         	dashboardRunnable.refreshDashboard(false);
 
@@ -277,6 +327,20 @@ public class DashboardController implements EventListener {
 		}
 	}
 
+	private Panel findPanel(int PA_DashboardContent_ID, int PA_DashboardPreference_ID) {
+		for(Panel panel : panelList) {
+			Object value1 = panel.getAttribute("PA_DashboardContent_ID");
+			Object value2 = panel.getAttribute("PA_DashboardPreference_ID");
+			if (value1 != null && value1 instanceof Number && value2 != null && value2 instanceof Number) {
+				int id1 = ((Number)value1).intValue();
+				int id2 = ((Number)value2).intValue();
+				if (id1 == PA_DashboardContent_ID && id2 == PA_DashboardPreference_ID)
+					return panel;
+			}
+		}
+		return null;
+	}
+
 	public  boolean render(Component content, MDashboardContent dc, DashboardRunnable dashboardRunnable) throws Exception {
 		boolean empty = true;
 		
@@ -704,8 +768,10 @@ public class DashboardController implements EventListener {
 			        		dashboardColumnLayout.setAttribute("IsAdditionalColumn", true);
 			        		Anchorchildren dashboardColumn = new Anchorchildren();
 			        		dashboardColumn.setAnchor(extraWidth + "% 100%");
-			        		dashboardColumn.setDroppable("true");
-			        		dashboardColumn.addEventListener(Events.ON_DROP, this);
+			        		if (!ClientInfo.isMobile()) {
+			        			dashboardColumn.setDroppable("true");
+			        			dashboardColumn.addEventListener(Events.ON_DROP, this);
+			        		}
 			        		dashboardColumn.appendChild(dashboardColumnLayout);
 			        		columnList.add(dashboardColumn);
 			                dashboardLayout.appendChild(dashboardColumn);
@@ -882,4 +948,23 @@ public class DashboardController implements EventListener {
 			}
 		}				
 	}
+	
+	public void updateLayout(ClientInfo clientInfo) {
+		if (isShowInDashboard) {
+			if (ClientInfo.isMobile()) {
+				int n = 0;
+	        	if (ClientInfo.maxWidth(ClientInfo.MEDIUM_WIDTH-1)) {	        		
+	        		if (ClientInfo.maxWidth(ClientInfo.SMALL_WIDTH-1)) {
+	        			n = 1;
+	        		} else {
+	        			n = 2;
+	        		}
+	        	}
+	        	if (noOfCols > 0 && n > 0 && noOfCols != n) {
+	        		render(null, null, true, true);
+	        		dashboardLayout.invalidate();
+	        	}
+        	}
+		}			
+	}
 }
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/desktop/DefaultDesktop.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/desktop/DefaultDesktop.java
index 1c18d3173f..f1bd75980a 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/desktop/DefaultDesktop.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/desktop/DefaultDesktop.java
@@ -98,9 +98,13 @@ import org.zkoss.zk.ui.event.SwipeEvent;
 import org.zkoss.zk.ui.metainfo.PageDefinition;
 import org.zkoss.zk.ui.util.Clients;
 import org.zkoss.zk.ui.util.DesktopCleanup;
+import org.zkoss.zul.Anchorchildren;
+import org.zkoss.zul.Anchorlayout;
 import org.zkoss.zul.Borderlayout;
 import org.zkoss.zul.Center;
 import org.zkoss.zul.East;
+import org.zkoss.zul.Image;
+import org.zkoss.zul.Popup;
 import org.zkoss.zul.West;
 
 /**
@@ -114,6 +118,10 @@ import org.zkoss.zul.West;
  */
 public class DefaultDesktop extends TabbedDesktop implements MenuListener, Serializable, EventListener, EventHandler, DesktopCleanup
 {
+	private static final String POPUP_OPEN_ATTR = "popup.open";
+
+	private static final String HOME_TAB_RENDER_ATTR = "homeTab.render";
+
 	/**
 	 * 
 	 */
@@ -160,6 +168,16 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
 
 	private Window headerPopup;
 
+	private Image logo;
+
+	private boolean mobile;
+
+	private Popup eastPopup;
+	
+	private Popup westPopup;
+	
+	private ToolBarButton westBtn;
+
     public DefaultDesktop()
     {
     	super();
@@ -205,6 +223,7 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
 					West w = (West) event.getTarget();
 					if (w.isOpen()) {
 						w.setOpen(false);
+						LayoutUtils.addSclass("slide", w);
 						updateMenuCollapsedPreference(true);
 					}
 				}
@@ -223,9 +242,12 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
         UserPreference pref = SessionManager.getSessionApplication().getUserPreference();
         boolean menuCollapsed= pref.isPropertyBool(UserPreference.P_MENU_COLLAPSED);
         w.setOpen(!menuCollapsed);
+        if (!w.isOpen())
+        	LayoutUtils.addSclass("slide", w);
         
-        boolean mobile = Executions.getCurrent().getBrowser("mobile") !=null;
+        mobile = ClientInfo.isMobile();
     	w.setCollapsible(true);
+    	LayoutUtils.addSlideSclass(w);
 
         if (mobile) {
         	w.setOpen(false);
@@ -254,6 +276,7 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
 					East e = (East) event.getTarget();
 					if (e.isOpen()) {
 						e.setOpen(false);
+						LayoutUtils.addSclass("slide", e);
 						updateHelpCollapsedPreference(true);
 					}
 				}
@@ -303,6 +326,30 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
         if (mobile) {
         	e.setVisible(false);
         	e.setOpen(false);
+        	Component content = e.getFirstChild();
+        	eastPopup = new Popup();
+        	ToolBarButton btn = new ToolBarButton();
+        	btn.setIconSclass("z-icon-remove");
+        	btn.addEventListener(Events.ON_CLICK, evt -> eastPopup.close());
+        	eastPopup.appendChild(btn);
+        	btn.setStyle("position: absolute; top: 4px; right: 4px; padding: 2px 6px;");
+        	eastPopup.setStyle("padding-top: 20px;");
+        	eastPopup.appendChild(content);
+        	eastPopup.setPage(getComponent().getPage());
+        	eastPopup.setHeight("100%");        	
+        	helpController.setupFieldTooltip();
+        	
+        	westPopup = new Popup();        	
+        	westPopup.setStyle("padding-top: 10px;");
+        	westPopup.setPage(getComponent().getPage());
+        	westPopup.setHeight("100%");        	
+        	westPopup.addEventListener(Events.ON_OPEN, (OpenEvent oe) -> {
+        		if (oe.isOpen()) {
+        			westPopup.setAttribute(POPUP_OPEN_ATTR, Boolean.TRUE);
+        		} else {
+        			westPopup.removeAttribute(POPUP_OPEN_ATTR);
+        		}
+        	});
         }
 
         Center windowArea = layout.getCenter();
@@ -354,32 +401,33 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
 
 		Adempiere.getThreadPoolExecutor().submit(new DesktopRunnable(runnable,layout.getDesktop()));
 
-		ToolBar toolbar = new ToolBar();
-        windowContainer.getComponent().appendChild(toolbar);
-                
-        showHeader = new ToolBarButton() {
-			@Override
-			public void onPageDetached(Page page) {
-				super.onPageDetached(page);
-				if (DefaultDesktop.this.headerPopup != null) {
-					DefaultDesktop.this.headerPopup.setPage(null);
+		ToolBar toolbar = windowContainer.getToobar();
+      
+		if (!mobile) {
+	        showHeader = new ToolBarButton() {
+				@Override
+				public void onPageDetached(Page page) {
+					super.onPageDetached(page);
+					if (DefaultDesktop.this.headerPopup != null) {
+						DefaultDesktop.this.headerPopup.setPage(null);
+					}
 				}
-			}
-        	
-        };
-        toolbar.appendChild(showHeader);
-        showHeader.setImage(ThemeManager.getThemeResource(IMAGES_THREELINE_MENU_PNG));
-        showHeader.addEventListener(Events.ON_CLICK, this);
-        showHeader.setSclass("window-container-toolbar-btn");
-        showHeader.setStyle("cursor: pointer; border: 1px solid transparent; padding: 2px;");
-        showHeader.setVisible(false);
-        
-        max = new ToolBarButton();
-        toolbar.appendChild(max);
-        max.setImage(ThemeManager.getThemeResource(IMAGES_UPARROW_PNG));
-        max.addEventListener(Events.ON_CLICK, this);
-        max.setSclass("window-container-toolbar-btn");
-        max.setStyle("cursor: pointer; border: 1px solid transparent; padding: 2px;");
+	        	
+	        };
+	        toolbar.appendChild(showHeader);
+	        showHeader.setImage(ThemeManager.getThemeResource(IMAGES_THREELINE_MENU_PNG));
+	        showHeader.addEventListener(Events.ON_CLICK, this);
+	        showHeader.setSclass("window-container-toolbar-btn");
+	        showHeader.setStyle("cursor: pointer; border: 1px solid transparent; padding: 2px;");
+	        showHeader.setVisible(false);
+	        
+	        max = new ToolBarButton();
+	        toolbar.appendChild(max);
+	        max.setImage(ThemeManager.getThemeResource(IMAGES_UPARROW_PNG));
+	        max.addEventListener(Events.ON_CLICK, this);
+	        max.setSclass("window-container-toolbar-btn");
+	        max.setStyle("cursor: pointer; border: 1px solid transparent; padding: 2px;");
+		}
         
         contextHelp = new ToolBarButton();
         toolbar.appendChild(contextHelp);
@@ -390,9 +438,19 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
         contextHelp.setTooltiptext(Util.cleanAmp(Msg.getElement(Env.getCtx(), "AD_CtxHelp_ID")));
         contextHelp.setVisible(!e.isVisible());
         
-        boolean headerCollapsed= pref.isPropertyBool(UserPreference.P_HEADER_COLLAPSED);
-        if (headerCollapsed) {
-        	collapseHeader();
+        if (!mobile) {
+	        boolean headerCollapsed= pref.isPropertyBool(UserPreference.P_HEADER_COLLAPSED);
+	        if (headerCollapsed) {
+	        	collapseHeader();
+	        }
+        }
+        
+        if (mobile) {
+	        westBtn = new ToolBarButton();
+	        westBtn.setImage(ThemeManager.getThemeResource(IMAGES_THREELINE_MENU_PNG));
+	        westBtn.addEventListener(Events.ON_CLICK, this);
+	        westBtn.setSclass("window-container-toolbar-btn");
+	        westBtn.setStyle("cursor: pointer; padding: 0px; margin: 0px;");
         }
         
         return layout;
@@ -506,11 +564,70 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
 		homeTab.getChildren().clear();		
 
 		dashboardController.render(homeTab, this, true);
+		
+		homeTab.setAttribute(HOME_TAB_RENDER_ATTR, Boolean.TRUE);
 	
 		West w = layout.getWest();
-		w.getChildren().clear();
-		sideController.render(w, this, false);
+		Component side = null;
+		if (mobile)
+		{
+			westPopup.getChildren().clear();			
+			side = westPopup;
+			w.setVisible(false);	
+			if (westBtn.getParent() == null)
+			{
+				Component menuSearchPanel = pnlHead.getFellow("menuLookup");
+				menuSearchPanel.getParent().insertBefore(westBtn, menuSearchPanel);				
+			}
+        	setSidePopupWidth(westPopup);
+        	setSidePopupWidth(eastPopup);
+		}
+		else
+		{
+			w.getChildren().clear();
+			side = w;
+		}
+		sideController.render(side, this, false);
+		if (mobile)
+		{
+			ToolBarButton btn = new ToolBarButton();
+        	btn.setIconSclass("z-icon-remove");
+        	btn.addEventListener(Events.ON_CLICK, evt -> {
+        		westPopup.close();
+        		westPopup.removeAttribute(POPUP_OPEN_ATTR);
+        	});
+        	westPopup.appendChild(btn);
+        	btn.setStyle("position: absolute; top: 4px; right: 4px; padding: 2px 6px;");
+		}
+		logo = pnlHead.getLogo();
+		if (mobile && logo != null)
+		{
+			Anchorchildren ac = new Anchorchildren();
+			ac.appendChild(logo);
+			ac.setStyle("padding: 4px;");
+			Anchorlayout layout = (Anchorlayout) side.getFirstChild();
+			layout.insertBefore(ac, layout.getFirstChild());
+		}
 		
+		if (mobile)
+		{
+			pnlHead.invalidate();
+		}
+	}
+
+	protected void setSidePopupWidth(Popup popup) {
+		if (ClientInfo.minWidth(ClientInfo.LARGE_WIDTH))
+			popup.setWidth("30%");
+		else if (ClientInfo.minWidth(ClientInfo.MEDIUM_WIDTH))
+			popup.setWidth("40%");
+		else if (ClientInfo.minWidth(ClientInfo.SMALL_WIDTH))
+			popup.setWidth("50%");
+		else if (ClientInfo.minWidth(ClientInfo.EXTRA_SMALL_WIDTH))
+			popup.setWidth("60%");
+		else if (ClientInfo.minWidth(400))
+			popup.setWidth("70%");
+		else
+			popup.setWidth("80%");
 	}
 
 	public void onEvent(Event event)
@@ -540,10 +657,23 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
         	}
         	else if (comp == contextHelp)
         	{
-        		layout.getEast().setVisible(true);
-        		layout.getEast().setOpen(true);
-        		contextHelp.setVisible(false);
-        		updateHelpCollapsedPreference(false);
+        		if (mobile && eastPopup != null)
+        		{
+        			eastPopup.open(layout.getCenter(), "overlap_end");
+        		}
+        		else
+        		{
+	        		layout.getEast().setVisible(true);
+	        		layout.getEast().setOpen(true);
+	        		LayoutUtils.removeSclass("slide", layout.getEast());
+	        		contextHelp.setVisible(false);
+	        		updateHelpCollapsedPreference(false);
+        		}
+        	}
+        	else if (comp == westBtn)
+        	{
+        		westPopup.open(layout.getNorth(), "overlap_start");
+        		westPopup.setAttribute(POPUP_OPEN_ATTR, Boolean.TRUE);
         	}
         	else if(comp instanceof ToolBarButton)
             {
@@ -716,7 +846,14 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
 			"var e=new Object;e.target=t;w._docClick(e);}catch(error){}";
 	
 	private void autoHideMenu() {
-		if (layout.getWest().isCollapsible() && !layout.getWest().isOpen())
+		if (mobile) {
+			if (westPopup.getAttribute(POPUP_OPEN_ATTR) != null) {
+				westPopup.close();
+				westPopup.removeAttribute(POPUP_OPEN_ATTR);
+			}
+			pnlHead.closeSearchPopup();
+				
+		} else if (layout.getWest().isCollapsible() && !layout.getWest().isOpen())
 		{
 			String id = layout.getWest().getUuid();
 			Tab tab = windowContainer.getSelectedTab();
@@ -904,7 +1041,7 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
 	@Override
 	public void onMenuSelected(int menuId) {
 		super.onMenuSelected(menuId);
-		if (showHeader.isVisible()) {
+		if (showHeader != null && showHeader.isVisible()) {
 			//ensure header popup is close
 			String script = "var w=zk.Widget.$('#" + layout.getUuid()+"'); " +
 					"zWatch.fire('onFloatUp', w);";
@@ -974,5 +1111,23 @@ public class DefaultDesktop extends TabbedDesktop implements MenuListener, Seria
 				}
 			}
 		}
-	}    
+	}
+
+	@Override
+	public void setClientInfo(ClientInfo clientInfo) {
+		super.setClientInfo(clientInfo);
+		if (clientInfo.tablet) {
+			if (homeTab != null && homeTab.getAttribute(HOME_TAB_RENDER_ATTR) != null) {
+				dashboardController.updateLayout(clientInfo);
+				updateSideLayout();
+			}
+		}
+	}
+
+	private void updateSideLayout() {
+		if (westPopup != null && westPopup.getChildren().size() > 1)
+			setSidePopupWidth(westPopup);
+		if (eastPopup != null && eastPopup.getChildren().size() > 1)
+			setSidePopupWidth(eastPopup);
+	}  
 }
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WEditor.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WEditor.java
index 524855ef94..b818062846 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WEditor.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WEditor.java
@@ -23,6 +23,7 @@ import java.beans.PropertyChangeListener;
 import java.util.ArrayList;
 
 import org.adempiere.webui.AdempiereWebUI;
+import org.adempiere.webui.ClientInfo;
 import org.adempiere.webui.LayoutUtils;
 import org.adempiere.webui.component.Bandbox;
 import org.adempiere.webui.component.Button;
@@ -118,26 +119,34 @@ public abstract class WEditor implements EventListener, PropertyChangeLis
 		
 		// when field have label, add action zoom when click to label, and show menu when right click to label
 		if (!readOnly)
-		{				
-			if (popupMenu.isZoomEnabled() && this instanceof IZoomableEditor)
+		{		
+			//long press conflict with text selection gesture on mobile
+			if (ClientInfo.isMobile())
 			{
-				// add action zoom when click to label
-				label.addEventListener(Events.ON_CLICK, new EventListener (){
-					public void onEvent(Event event) throws Exception {
-						if (Events.ON_CLICK.equals(event.getName())) {
-							((IZoomableEditor)WEditor.this).actionZoom();
-						}
-
-					}
-				});
+				label.addEventListener(Events.ON_CLICK, evt-> popupMenu.open(label, "after_end"));
 			}
-
-			// show menu when right click to label
-			popupMenu.addContextElement(label);
-			
-			if (component instanceof XulElement) 
+			else
 			{
-				popupMenu.addContextElement((XulElement) component);
+				if (popupMenu.isZoomEnabled() && this instanceof IZoomableEditor)
+				{
+					// add action zoom when click to label
+					label.addEventListener(Events.ON_CLICK, new EventListener (){
+						public void onEvent(Event event) throws Exception {
+							if (Events.ON_CLICK.equals(event.getName())) {
+								((IZoomableEditor)WEditor.this).actionZoom();
+							}
+	
+						}
+					});
+				}
+	
+				// show menu when right click to label
+				popupMenu.addContextElement(label);
+				
+				if (component instanceof XulElement) 
+				{
+					popupMenu.addContextElement((XulElement) component);
+				}
 			}
 		}
 		
@@ -551,7 +560,13 @@ public abstract class WEditor implements EventListener, PropertyChangeLis
 
 	protected void applyLabelStyles() {
 		if (label != null) {
-			String style = (isZoomable() ? STYLE_ZOOMABLE_LABEL : "") + (isMandatoryStyle() ? STYLE_EMPTY_MANDATORY_LABEL : STYLE_NORMAL_LABEL);			
+			boolean zoomable = isZoomable();
+			String style = (zoomable ? STYLE_ZOOMABLE_LABEL : "") + (isMandatoryStyle() ? STYLE_EMPTY_MANDATORY_LABEL : STYLE_NORMAL_LABEL);
+			if (ClientInfo.isMobile()) {
+				if (!zoomable && popupMenu != null) {
+					style = style + STYLE_MOBILE_ZOOMABLE;
+				}
+			}
 			if (gridField.getAD_LabelStyle_ID() > 0) 
 			{
 				String s = buildStyle(gridField.getAD_LabelStyle_ID());
@@ -785,6 +800,7 @@ public abstract class WEditor implements EventListener, PropertyChangeLis
 	private static final String STYLE_ZOOMABLE_LABEL = "cursor: pointer; text-decoration: underline;";
 	private static final String STYLE_NORMAL_LABEL = "color: #333;";
 	private static final String STYLE_EMPTY_MANDATORY_LABEL = "color: red;";
+	private static final String STYLE_MOBILE_ZOOMABLE = "cursor: pointer;";
 	
 	private static class EvaluateeWrapper implements Evaluatee {
 		
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WLocationEditor.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WLocationEditor.java
index f4f2b5704a..e9a116ecb3 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WLocationEditor.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WLocationEditor.java
@@ -21,6 +21,7 @@ import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
 import java.util.logging.Level;
 
+import org.adempiere.webui.ClientInfo;
 import org.adempiere.webui.LayoutUtils;
 import org.adempiere.webui.ValuePreference;
 import org.adempiere.webui.component.Locationbox;
@@ -29,6 +30,7 @@ import org.adempiere.webui.event.ContextMenuListener;
 import org.adempiere.webui.event.DialogEvents;
 import org.adempiere.webui.event.ValueChangeEvent;
 import org.adempiere.webui.theme.ThemeManager;
+import org.adempiere.webui.util.ZKUpdateUtil;
 import org.adempiere.webui.window.WFieldRecordInfo;
 import org.adempiere.webui.window.WLocationDialog;
 import org.compiere.model.GridField;
@@ -90,7 +92,7 @@ public class WLocationEditor extends WEditor implements EventListener, Pr
     	
     	popupMenu = new WEditorPopupMenu(false, false, isShowPreference());
     	popupMenu.addMenuListener(this);
-    	addChangeLogMenu(popupMenu);
+    	addChangeLogMenu(popupMenu);    	
     }
     
 	@Override
@@ -208,6 +210,25 @@ public class WLocationEditor extends WEditor implements EventListener, Pr
 			});
             ld.setTitle(null);
             LayoutUtils.openPopupWindow(getComponent(), ld);
+            if (ClientInfo.isMobile())
+    		{
+            	ld.setAttribute("mobile.orientation", ClientInfo.get().orientation);
+    			ClientInfo.onClientInfo(ld, () -> {
+    				if (ld.getPage() != null) {
+    					String orientation = (String) ld.getAttribute("mobile.orientation");
+    					String newOrientation = ClientInfo.get().orientation;
+    					if (!newOrientation.equals(orientation)) {
+    						ld.setAttribute("mobile.orientation", newOrientation);
+    						
+    						ZKUpdateUtil.setCSSHeight(ld);
+    						ZKUpdateUtil.setCSSWidth(ld);    						
+    						ld.invalidate();
+    						LayoutUtils.openPopupWindow(getComponent(), ld, 100);
+    						
+    					}	    				
+    				}
+    			});
+    		}
         }
     }
     
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WLocatorEditor.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WLocatorEditor.java
index 9076f310ac..0071db9dce 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WLocatorEditor.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WLocatorEditor.java
@@ -24,6 +24,7 @@ import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.util.logging.Level;
 
+import org.adempiere.webui.ClientInfo;
 import org.adempiere.webui.LayoutUtils;
 import org.adempiere.webui.ValuePreference;
 import org.adempiere.webui.apps.AEnv;
@@ -33,6 +34,7 @@ import org.adempiere.webui.event.ContextMenuListener;
 import org.adempiere.webui.event.DialogEvents;
 import org.adempiere.webui.event.ValueChangeEvent;
 import org.adempiere.webui.theme.ThemeManager;
+import org.adempiere.webui.util.ZKUpdateUtil;
 import org.adempiere.webui.window.WFieldRecordInfo;
 import org.adempiere.webui.window.WLocatorDialog;
 import org.compiere.model.GridField;
@@ -255,6 +257,25 @@ public class WLocatorEditor extends WEditor implements EventListener, Pro
 			//	display
 			ld.setTitle(null);
 			LayoutUtils.openPopupWindow(getComponent(), ld);
+			if (ClientInfo.isMobile())
+    		{
+            	ld.setAttribute("mobile.orientation", ClientInfo.get().orientation);
+    			ClientInfo.onClientInfo(ld, () -> {
+    				if (ld.getPage() != null) {
+    					String orientation = (String) ld.getAttribute("mobile.orientation");
+    					String newOrientation = ClientInfo.get().orientation;
+    					if (!newOrientation.equals(orientation)) {
+    						ld.setAttribute("mobile.orientation", newOrientation);
+    						
+    						ZKUpdateUtil.setCSSHeight(ld);
+    						ZKUpdateUtil.setCSSWidth(ld);    						
+    						ld.invalidate();
+    						LayoutUtils.openPopupWindow(getComponent(), ld, 100);
+    						
+    					}	    				
+    				}
+    			});
+    		}
 		}
 	}
 	
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WNumberEditor.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WNumberEditor.java
index 168ac43828..710f7d4858 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WNumberEditor.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WNumberEditor.java
@@ -20,6 +20,7 @@ package org.adempiere.webui.editor;
 import java.math.BigDecimal;
 import java.text.DecimalFormat;
 
+import org.adempiere.webui.ClientInfo;
 import org.adempiere.webui.ValuePreference;
 import org.adempiere.webui.apps.AEnv;
 import org.adempiere.webui.component.NumberBox;
@@ -153,6 +154,9 @@ public class WNumberEditor extends WEditor implements ContextMenuListener
     	addChangeLogMenu(popupMenu);
     	
     	originalStyle = getComponent().getDecimalbox().getStyle();
+    	getComponent().getDecimalbox().setClientAttribute("type", "number");
+    	if (ClientInfo.isMobile())
+    		getComponent().getButton().setVisible(false);
     }
 	
 	/**
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WSearchEditor.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WSearchEditor.java
index 3d1e357fba..9a3ad5cbb1 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WSearchEditor.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WSearchEditor.java
@@ -26,6 +26,7 @@ import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.util.logging.Level;
 
+import org.adempiere.webui.ClientInfo;
 import org.adempiere.webui.LayoutUtils;
 import org.adempiere.webui.ValuePreference;
 import org.adempiere.webui.adwindow.ADWindow;
@@ -500,7 +501,7 @@ public class WSearchEditor extends WEditor implements ContextMenuListener, Value
 
 		vqe.setSizable(true);
 		adwindow = ADWindow.findADWindow(getComponent());
-		if (adwindow != null) {
+		if (adwindow != null && !ClientInfo.isMobile()) {
 			ADWindowContent content = adwindow.getADWindowContent();				
 			content.getComponent().getParent().appendChild(vqe);
 			content.showBusyMask(vqe);
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WStringEditor.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WStringEditor.java
index d89e1efea2..130bc1e6b7 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WStringEditor.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WStringEditor.java
@@ -170,6 +170,8 @@ public class WStringEditor extends WEditor implements ContextMenuListener
 	        		combo.appendItem(s);
 	        	}
 	        }
+	        if ("email".equalsIgnoreCase(gridField.getColumnName()))
+	        	getComponent().setClientAttribute("type", "email");
 		}
     }
 
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WUrlEditor.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WUrlEditor.java
index fa18ab0b71..46d86ac6b8 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WUrlEditor.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/editor/WUrlEditor.java
@@ -41,6 +41,8 @@ public class WUrlEditor extends WEditor implements ContextMenuListener
 		popupMenu = new WEditorPopupMenu(false, false, isShowPreference());
 		popupMenu.addMenuListener(this);
 		addChangeLogMenu(popupMenu);
+		
+		getComponent().getTextbox().setClientAttribute("type", "url");
 	}
 
 
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/factory/DefaultEditorFactory.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/factory/DefaultEditorFactory.java
index 95d31750d9..c2d269b612 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/factory/DefaultEditorFactory.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/factory/DefaultEditorFactory.java
@@ -70,7 +70,7 @@ public class DefaultEditorFactory implements IEditorFactory {
 
         /** String (clear/password) */
         if (displayType == DisplayType.String
-            || displayType == DisplayType.PrinterName
+            || displayType == DisplayType.PrinterName || displayType == DisplayType.Color
             || (tableEditor && (displayType == DisplayType.Text || displayType == DisplayType.TextLong)))
         {
             if (gridField.isEncryptedField())
@@ -81,6 +81,9 @@ public class DefaultEditorFactory implements IEditorFactory {
             {
                 editor = new WStringEditor(gridField, tableEditor);
             }
+            //enable html5 color input type
+            if (displayType == DisplayType.Color)
+            	((WStringEditor)editor).getComponent().setClientAttribute("type", "color");
         }
         /** File */
         else if (displayType == DisplayType.FileName)
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/grid/WQuickEntry.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/grid/WQuickEntry.java
index 5502d08c66..1401808269 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/grid/WQuickEntry.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/grid/WQuickEntry.java
@@ -19,6 +19,7 @@ import java.util.List;
 import java.util.logging.Level;
 
 import org.adempiere.base.Core;
+import org.adempiere.webui.ClientInfo;
 import org.adempiere.webui.component.ConfirmPanel;
 import org.adempiere.webui.component.Label;
 import org.adempiere.webui.component.Window;
@@ -28,6 +29,7 @@ import org.adempiere.webui.editor.WebEditorFactory;
 import org.adempiere.webui.event.ValueChangeEvent;
 import org.adempiere.webui.event.ValueChangeListener;
 import org.adempiere.webui.session.SessionManager;
+import org.adempiere.webui.theme.ThemeManager;
 import org.adempiere.webui.util.ZKUpdateUtil;
 import org.adempiere.webui.window.FDialog;
 import org.compiere.model.GridField;
@@ -89,6 +91,8 @@ public class WQuickEntry extends Window implements EventListener, ValueCh
 	protected int m_AD_Window_ID;
 	
 	private boolean isHasField = false;
+
+	private String orientation;
 	/**
 	 *	Constructor.
 	 *	Requires call loadRecord
@@ -136,7 +140,16 @@ public class WQuickEntry extends Window implements EventListener, ValueCh
 
 	private void jbInit() throws Exception
 	{
-		ZKUpdateUtil.setWidth(this, "350px");
+		if (!ThemeManager.isUseCSSForWindowSize()) {
+			ZKUpdateUtil.setWindowWidthX(this, 350);
+		} else {
+			addCallback(AFTER_PAGE_ATTACHED, t -> {
+				ZKUpdateUtil.setCSSWidth(this);
+				ZKUpdateUtil.setCSSHeight(this);
+			});
+		}
+		
+		this.setSclass("quick-entry-dialog");
 		this.setBorder("normal");
 		this.setClosable(true);
 		this.setSizable(true);
@@ -145,8 +158,31 @@ public class WQuickEntry extends Window implements EventListener, ValueCh
 		ZKUpdateUtil.setWidth(centerPanel, "100%");
 
 		confirmPanel.addActionListener(Events.ON_CLICK, this);
+		
+		if (ClientInfo.isMobile())
+		{
+			if (ClientInfo.maxWidth(ClientInfo.EXTRA_SMALL_WIDTH) || ClientInfo.maxHeight(ClientInfo.SMALL_HEIGHT))
+			{
+				confirmPanel.addButtonSclass("btn-small small-image-btn");
+			}
+			orientation = ClientInfo.get().orientation;
+			ClientInfo.onClientInfo(this, this::onClientInfo);
+		}
 	}
 
+	protected void onClientInfo()
+	{
+		if (getPage() != null) {
+			String newOrientation = ClientInfo.get().orientation;
+			if (!newOrientation.equals(orientation)) {
+				orientation = newOrientation;
+				ZKUpdateUtil.setCSSWidth(this);
+				ZKUpdateUtil.setCSSHeight(this);
+				this.invalidate();
+			}			
+		}
+	}
+	
 	/**
 	 *	Dynamic Init
 	 */
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoProductWindow.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoProductWindow.java
index ff600abc55..b6c92bb009 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoProductWindow.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoProductWindow.java
@@ -11,6 +11,7 @@ import java.util.ArrayList;
 import java.util.Vector;
 import java.util.logging.Level;
 
+import org.adempiere.webui.ClientInfo;
 import org.adempiere.webui.component.Borderlayout;
 import org.adempiere.webui.component.Button;
 import org.adempiere.webui.component.Checkbox;
@@ -336,6 +337,11 @@ public class InfoProductWindow extends InfoWindow {
 			}
 		});
 		south.setSclass("south-collapsible-with-title");
+		if (ClientInfo.maxHeight(ClientInfo.MEDIUM_HEIGHT-1))
+		{
+			south.setOpen(false);
+			ZKUpdateUtil.setHeight(south, "100%");
+		}
 		contentBorderLayout.appendChild(south);
 		tabbedPane.setSclass("info-product-tabbedpane");
 		south.appendChild(tabbedPane);
@@ -355,7 +361,8 @@ public class InfoProductWindow extends InfoWindow {
 					for(int i = 0; i < columnInfos.length; i++) {
 						if (columnInfos[i].getGridField() != null && columnInfos[i].getGridField().getColumnName().equals("Value")) {
 							refresh(M_Warehouse_ID, M_PriceList_Version_ID);
-		        			contentBorderLayout.getSouth().setOpen(true);
+							if (ClientInfo.minHeight(ClientInfo.MEDIUM_HEIGHT))
+								contentBorderLayout.getSouth().setOpen(true);
 		        			break;
 						}
 					}
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoWindow.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoWindow.java
index 21d14192a8..6318f6dd8d 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoWindow.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/info/InfoWindow.java
@@ -18,6 +18,7 @@ import org.adempiere.model.IInfoColumn;
 import org.adempiere.model.MInfoProcess;
 import org.adempiere.model.MInfoRelated;
 import org.adempiere.webui.AdempiereWebUI;
+import org.adempiere.webui.ClientInfo;
 import org.adempiere.webui.ISupportMask;
 import org.adempiere.webui.LayoutUtils;
 import org.adempiere.webui.apps.AEnv;
@@ -139,6 +140,7 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
 	 * Menu contail process menu item
 	 */
 	protected Menupopup ipMenu;
+	private int noOfParameterColumn;
 	/**
 	 * @param WindowNo
 	 * @param tableName
@@ -214,6 +216,10 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
 			}			
 		}
 		
+		if (ClientInfo.isMobile()) {
+			ClientInfo.onClientInfo(this, this::onClientInfo);
+		}
+		
 	}
 	
 	/**
@@ -1100,7 +1106,7 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
 		ZKUpdateUtil.setHeight(layout, "100%");
         if (!isLookup())
         {
-        	layout.setStyle("position: absolute");
+        	layout.setStyle("position: relative");
         }
         this.appendChild(layout);
 		
@@ -1113,6 +1119,10 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
         contentPanel.setSpan(true);
         
         North north = new North();
+        north.setCollapsible(true);
+        north.setSplittable(true);
+        north.setAutoscroll(true);
+        LayoutUtils.addSlideSclass(north);
         layout.appendChild(north);
         renderParameterPane(north);
         
@@ -1172,10 +1182,7 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
 		ZKUpdateUtil.setWidth(inner, "100%");
 		ZKUpdateUtil.setHeight(inner, "100%");
 		int height = SessionManager.getAppDesktop().getClientInfo().desktopHeight * 90 / 100;
-		if (isLookup())
-			inner.setStyle("border: none; position: relative; ");
-		else
-			inner.setStyle("border: none; position: absolute; ");
+		inner.setStyle("border: none; position: relative; ");
 		inner.appendCenter(div);
 		//true will conflict with listbox scrolling
 		inner.getCenter().setAutoscroll(false);
@@ -1220,12 +1227,21 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
 	}
 
 	protected void createParameterPanel() {
-		parameterGrid = GridFactory.newGridLayout();
-		parameterGrid.setWidgetAttribute(AdempiereWebUI.WIDGET_INSTANCE_NAME, "infoParameterPanel");
-		parameterGrid.setStyle("width: 95%; margin: auto !important;");
+		layoutParameterGrid(false);
+	}
+	
+	protected void layoutParameterGrid(boolean update) {
+		if (!update) {
+			parameterGrid = GridFactory.newGridLayout();
+			parameterGrid.setWidgetAttribute(AdempiereWebUI.WIDGET_INSTANCE_NAME, "infoParameterPanel");
+			parameterGrid.setStyle("width: 95%; margin: auto !important;");
+		}
+		if (parameterGrid.getColumns() != null)
+			parameterGrid.getColumns().detach();
 		Columns columns = new Columns();
 		parameterGrid.appendChild(columns);
-		for(int i = 0; i < 6; i++)
+		noOfParameterColumn = getNoOfParameterColumns();
+		for(int i = 0; i < noOfParameterColumn; i++)
 			columns.appendChild(new Column());
 		
 		Column column = new Column();
@@ -1233,11 +1249,15 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
 		column.setAlign("right");
 		columns.appendChild(column);
 		
+		if (parameterGrid.getRows() != null)
+			parameterGrid.getRows().detach();
 		Rows rows = new Rows();
 		parameterGrid.appendChild(rows);
 		
-		editors = new ArrayList();
-		identifiers = new ArrayList();
+		if (!update) {
+			editors = new ArrayList();
+			identifiers = new ArrayList();
+		}
 		TreeMap> tree = new TreeMap>();
 		for (int i = 0; i < infoColumns.length; i++)
 		{
@@ -1254,7 +1274,16 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
 		for (Integer i : tree.keySet()) {
 			List list = tree.get(i);
 			for(Object[] value : list) {
-				addSelectionColumn((MInfoColumn)value[0], (GridField)value[1]);
+				if (update) {
+					for (WEditor editor : editors) {
+						if (editor.getGridField() == value[1]) {
+							addSearchParameter(editor.getLabel(), editor.getComponent());
+							break;
+						}
+					}
+				} else {
+					addSelectionColumn((MInfoColumn)value[0], (GridField)value[1]);
+				}
 			}
 		}
 		
@@ -1271,10 +1300,11 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
 			}
 		}
 		evalDisplayLogic();
-		initParameters();
+		if (!update)
+			initParameters();
 		dynamicDisplay(null);
 	}
-
+	
 	protected void evalDisplayLogic() {
 		for(WEditor editor : editors) {
         	if (editor.getGridField() != null && !editor.getGridField().isDisplayed(true)) {        		
@@ -1364,7 +1394,7 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
         else
         {
         	panel = (Row) parameterGrid.getRows().getLastChild();
-        	if (panel.getChildren().size() == 6)
+        	if (panel.getChildren().size() == getNoOfParameterColumns())
         	{
         		if (parameterGrid.getRows().getChildren().size() == 1) 
         		{
@@ -1398,6 +1428,15 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
         panel.appendChild(outerParent);
 	}
 
+	protected int getNoOfParameterColumns() {
+		if (ClientInfo.maxWidth(ClientInfo.SMALL_WIDTH-1))
+			return 2;
+		else if (ClientInfo.maxWidth(ClientInfo.MEDIUM_WIDTH-1))
+			return 4;
+		else
+			return 6;
+	}
+
 	protected void createAndCheckbox() {
 		checkAND = new Checkbox();
 		checkAND.setLabel(Msg.getMsg(Env.getCtx(), "SearchAND", true));
@@ -1503,6 +1542,11 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
     protected void executeQuery() {
     	prepareTable();
     	super.executeQuery();
+    	if (ClientInfo.maxHeight(ClientInfo.SMALL_HEIGHT-1) ||
+    		ClientInfo.maxWidth(ClientInfo.SMALL_WIDTH-1)) {
+    		layout.getNorth().setOpen(false);
+    		LayoutUtils.addSclass("slide", layout.getNorth());
+    	}
     }
     
 	@Override
@@ -1676,6 +1720,14 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
 		}
 	}
 	
+	protected void onClientInfo() {
+		int t = getNoOfParameterColumns();
+		if (t > 0 && noOfParameterColumn > 0 && t != noOfParameterColumn) {
+			layoutParameterGrid(true);
+			this.invalidate();
+		}
+	}
+
 	/**
 	 * 	Test Row Count
 	 *	@return true if display
@@ -2055,7 +2107,7 @@ public class InfoWindow extends InfoPanel implements ValueChangeListener, EventL
 		// eval only mandatory field
 		if (validateGrid.isMandatory(true)){
 			// update color of field
-			wEditor.updateLabelStyle();
+			wEditor.updateStyle();
 			Object data = wEditor.getValue();
 			if (data == null || data.toString().length() == 0) {				
 				return false;
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/ADForm.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/ADForm.java
index 00e8985dd1..8f25684897 100755
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/ADForm.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/ADForm.java
@@ -78,8 +78,8 @@ public abstract class ADForm extends Window implements EventListener, IHe
          m_WindowNo = SessionManager.getAppDesktop().registerWindow(this);
 
          ZKUpdateUtil.setWidth(this, "100%");
-         ZKUpdateUtil.setHeight(this, "95%");
-         this.setStyle("position:absolute");
+         ZKUpdateUtil.setHeight(this, "99%");
+         this.setStyle("position:relative");
          this.setContentSclass("adform-content");
     }
 
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/CustomForm.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/CustomForm.java
index ebce62f905..adaf628f10 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/CustomForm.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/CustomForm.java
@@ -12,5 +12,5 @@ public class CustomForm extends ADForm
 	protected void initForm() 
 	{
 		
-	}
+	}	
 }
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/CustomizeGridViewPanel.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/CustomizeGridViewPanel.java
index ae0c13b930..dca206fe57 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/CustomizeGridViewPanel.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/CustomizeGridViewPanel.java
@@ -26,6 +26,7 @@ import java.util.logging.Level;
 
 import org.adempiere.exceptions.DBException;
 import org.adempiere.model.MTabCustomization;
+import org.adempiere.webui.ClientInfo;
 import org.adempiere.webui.LayoutUtils;
 import org.adempiere.webui.adwindow.GridView;
 import org.adempiere.webui.component.Button;
@@ -184,8 +185,11 @@ public class CustomizeGridViewPanel extends Panel
 		EventListener crossListMouseListener = new DragListener();
 		yesList.addOnDropListener(crossListMouseListener);
 		noList.addOnDropListener(crossListMouseListener);
-		yesList.setItemDraggable(true);
-		noList.setItemDraggable(true);
+		if (!ClientInfo.isMobile()) 
+		{
+			yesList.setItemDraggable(true);
+			noList.setItemDraggable(true);
+		}
 
 		actionListener = new EventListener()
 		{
@@ -262,7 +266,8 @@ public class CustomizeGridViewPanel extends Panel
 		chkSaveWidth.setLabel(Msg.getMsg(Env.getCtx(), "SaveColumnWidth"));
 
 		sep = new Separator("vertical");
-		sep.setSpacing("200px");
+		if (ClientInfo.minWidth(ClientInfo.SMALL_WIDTH))
+			sep.setSpacing("200px");
 		southPanel.appendChild(sep);
 		lblGridMode.setValue(Msg.getMsg(Env.getCtx(), "OpenInGridMode"));
 		southPanel.appendChild(lblGridMode);
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/HeaderPanel.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/HeaderPanel.java
index 94d5ad4f73..de5c29bd41 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/HeaderPanel.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/HeaderPanel.java
@@ -17,6 +17,8 @@
 
 package org.adempiere.webui.panel;
 
+import org.adempiere.webui.ClientInfo;
+import org.adempiere.webui.LayoutUtils;
 import org.adempiere.webui.apps.GlobalSearch;
 import org.adempiere.webui.apps.MenuSearchController;
 import org.adempiere.webui.component.Panel;
@@ -31,6 +33,7 @@ import org.zkoss.zk.ui.Page;
 import org.zkoss.zk.ui.event.Event;
 import org.zkoss.zk.ui.event.EventListener;
 import org.zkoss.zk.ui.event.Events;
+import org.zkoss.zk.ui.event.OpenEvent;
 import org.zkoss.zul.Image;
 import org.zkoss.zul.Popup;
 import org.zkoss.zul.impl.LabelImageElement;
@@ -57,7 +60,7 @@ public class HeaderPanel extends Panel implements EventListener
     public HeaderPanel()
     {
         super();
-        addEventListener(Events.ON_CREATE, this);
+        addEventListener(Events.ON_CREATE, this);              
     }
 
     protected void onCreate()
@@ -72,8 +75,13 @@ public class HeaderPanel extends Panel implements EventListener
     	createSearchPanel();
 
     	btnMenu = (LabelImageElement) getFellow("menuButton");
-    	btnMenu.setLabel(Util.cleanAmp(Msg.getMsg(Env.getCtx(),"Menu")));
+    	btnMenu.setIconSclass("z-icon-sitemap");
+    	btnMenu.setTooltiptext(Util.cleanAmp(Msg.getMsg(Env.getCtx(),"Menu")));
     	btnMenu.addEventListener(Events.ON_CLICK, this);
+    	if (ClientInfo.isMobile()) {
+    		LayoutUtils.addSclass("mobile", this);
+    		ClientInfo.onClientInfo(this, this::onClientInfo);
+    	}
     }
 
 	protected void createPopupMenu() {
@@ -82,8 +90,13 @@ public class HeaderPanel extends Panel implements EventListener
 		menuTreePanel = new MenuTreePanel(popMenu);
     	popMenu.setSclass("desktop-menu-popup");
     	ZKUpdateUtil.setHeight(popMenu, "90%");
-    	ZKUpdateUtil.setWidth(popMenu, "600px");
+    	ZKUpdateUtil.setWindowWidthX(popMenu, 600);
     	popMenu.setPage(this.getPage());
+    	popMenu.addEventListener(Events.ON_OPEN, (OpenEvent evt) -> popMenuOpenEvent(evt));
+	}
+
+	private void popMenuOpenEvent(OpenEvent evt) {
+		popMenu.setAttribute(popMenu.getUuid(), System.currentTimeMillis());
 	}
 
 	protected void createSearchPanel() {
@@ -104,6 +117,11 @@ public class HeaderPanel extends Panel implements EventListener
 			}
 			else if(event.getTarget() == btnMenu )
 			{
+				Long ts = (Long) popMenu.removeAttribute(popMenu.getUuid());
+				if (ts != null) {
+					if ((System.currentTimeMillis()-ts.longValue()) < 500)
+						return;
+				}
 				popMenu.open(btnMenu, "after_start");
 			}
 		} else if (Events.ON_CREATE.equals(event.getName())) {
@@ -131,5 +149,20 @@ public class HeaderPanel extends Panel implements EventListener
 			popMenu.setPage(null);
 	}
 	
+	public Image getLogo() {
+		return image;
+	}
 	
+	public void closeSearchPopup() {
+		Component c = getFellow("menuLookup");
+		if (c != null && c instanceof GlobalSearch)
+			((GlobalSearch)c).closePopup();
+	}
+	
+	protected void onClientInfo() {
+		ZKUpdateUtil.setWindowWidthX(popMenu, 600);
+		Component c = getFellow("menuLookup");
+		if (c != null && c instanceof GlobalSearch)
+			((GlobalSearch)c).onClientInfo();
+	}
 }
diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/HelpController.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/HelpController.java
index 121d191312..b4f8691325 100644
--- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/HelpController.java
+++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/HelpController.java
@@ -124,7 +124,7 @@ public class HelpController
         		"if (typeof description=='string' && description.length > 0) {s=s+'

'+description+'';}" + "if (typeof help=='string' && help.length > 0) {s=s+'

'+help;}}" + "s=s+'';this.setContent(s);}"); - Clients.response(new AuScript(htmlToolTip, "var w=zk.Widget.$('#"+htmlToolTip.getUuid()+"');zWatch.listen({onFieldTooltip: w});")); + setupFieldTooltip(); pnlContextHelp = new Panel(); pnlContextHelp.setSclass("dashboard-widget"); @@ -142,6 +142,10 @@ public class HelpController renderCtxHelp(X_AD_CtxHelp.CTXTYPE_Home, 0); renderQuickInfo(null); } + + public void setupFieldTooltip() { + Clients.response("helpControllerFieldTooltip", new AuScript(htmlToolTip, "var w=zk.Widget.$('#"+htmlToolTip.getUuid()+"');zWatch.listen({onFieldTooltip: w});")); + } /** * Make tooltip content for a field diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/InfoGeneralPanel.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/InfoGeneralPanel.java index f0b97f817a..32249229a2 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/InfoGeneralPanel.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/InfoGeneralPanel.java @@ -26,6 +26,7 @@ import java.util.ArrayList; import java.util.logging.Level; import org.adempiere.webui.AdempiereWebUI; +import org.adempiere.webui.ClientInfo; import org.adempiere.webui.component.Grid; import org.adempiere.webui.component.GridFactory; import org.adempiere.webui.component.Label; @@ -43,9 +44,11 @@ import org.compiere.util.DisplayType; import org.compiere.util.Env; import org.compiere.util.Msg; import org.compiere.util.Util; +import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zul.Borderlayout; +import org.zkoss.zul.Cell; import org.zkoss.zul.Center; import org.zkoss.zul.Div; import org.zkoss.zul.North; @@ -86,6 +89,8 @@ public class InfoGeneralPanel extends InfoPanel implements EventListener private Borderlayout layout; private Vbox southBody; + private int noOfParameterColumn; + public InfoGeneralPanel(String queryValue, int windowNo,String tableName,String keyColumn, boolean isSOTrx, String whereClause) { this(queryValue, windowNo, tableName, keyColumn, isSOTrx, whereClause, true); @@ -142,58 +147,42 @@ public class InfoGeneralPanel extends InfoPanel implements EventListener executeQuery(); renderItems(); } - + + if (ClientInfo.isMobile()) { + ClientInfo.onClientInfo(this, this::onClientInfo); + } } private void initComponents() { Grid grid = GridFactory.newGridLayout(); + ZKUpdateUtil.setWidth(grid, "100%"); + ZKUpdateUtil.setVflex(grid, "min"); - Rows rows = new Rows(); - grid.appendChild(rows); - - Row row = new Row(); - rows.appendChild(row); - row.appendChild(lbl1.rightAlign()); - row.appendChild(txt1); - ZKUpdateUtil.setHflex(txt1, "1"); - row.appendChild(lbl2.rightAlign()); - row.appendChild(txt2); - ZKUpdateUtil.setHflex(txt2, "1"); - row.appendChild(lbl3.rightAlign()); - row.appendChild(txt3); - ZKUpdateUtil.setHflex(txt3, "1"); - row.appendChild(lbl4.rightAlign()); - row.appendChild(txt4); - ZKUpdateUtil.setHflex(txt4, "1"); + layoutParameterGrid(grid); layout = new Borderlayout(); ZKUpdateUtil.setWidth(layout, "100%"); ZKUpdateUtil.setHeight(layout, "100%"); - if (!isLookup()) - { - layout.setStyle("position: absolute"); - } + layout.setStyle("position: relative"); this.appendChild(layout); North north = new North(); layout.appendChild(north); north.appendChild(grid); + ZKUpdateUtil.setVflex(north, "min"); Center center = new Center(); layout.appendChild(center); Div div = new Div(); div.appendChild(contentPanel); - if (isLookup()) - ZKUpdateUtil.setWidth(contentPanel, "99%"); - else - contentPanel.setStyle("width: 99%; margin: 0px auto;"); + ZKUpdateUtil.setWidth(contentPanel, "100%"); ZKUpdateUtil.setVflex(contentPanel, true); contentPanel.setSizedByContent(true); - div.setStyle("width :100%; height: 100%"); center.appendChild(div); ZKUpdateUtil.setVflex(div, "1"); ZKUpdateUtil.setHflex(div, "1"); + ZKUpdateUtil.setVflex(center, "1"); South south = new South(); layout.appendChild(south); @@ -203,6 +192,63 @@ public class InfoGeneralPanel extends InfoPanel implements EventListener southBody.appendChild(new Separator()); southBody.appendChild(confirmPanel); southBody.appendChild(statusBar); + ZKUpdateUtil.setVflex(south, "min"); + } + + protected void layoutParameterGrid(Grid grid) { + noOfParameterColumn = getNoOfParameterColumn(); + Rows rows = new Rows(); + grid.appendChild(rows); + + Row row = new Row(); + rows.appendChild(row); + row.appendChild(lbl1.rightAlign()); + row.appendChild(txt1); + ZKUpdateUtil.setHflex(txt1, "1"); + if (row.getChildren().size() % noOfParameterColumn == 0) + row = rows.newRow(); + row.appendChild(lbl2.rightAlign()); + row.appendChild(txt2); + ZKUpdateUtil.setHflex(txt2, "1"); + if (row.getChildren().size() % noOfParameterColumn == 0) + row = rows.newRow(); + Cell cell = new Cell(); + cell.setAlign("right"); + cell.setValign("middle"); + Div ldiv = new Div(); + ldiv.appendChild(lbl3); + cell.appendChild(ldiv); + row.appendChild(cell); + cell = new Cell(); + cell.setValign("middle"); + cell.appendChild(txt3); + row.appendChild(cell); + ZKUpdateUtil.setHflex(txt3, "1"); + if (row.getChildren().size() % noOfParameterColumn == 0) + row = rows.newRow(); + cell = new Cell(); + cell.setAlign("right"); + cell.setValign("middle"); + ldiv = new Div(); + ldiv.appendChild(lbl4); + cell.appendChild(ldiv); + row.appendChild(cell); + cell = new Cell(); + cell.setValign("middle"); + cell.appendChild(txt4); + row.appendChild(cell); + ZKUpdateUtil.setHflex(txt4, "1"); + } + + private int getNoOfParameterColumn() { + if (ClientInfo.maxWidth(ClientInfo.EXTRA_SMALL_WIDTH-1)) + return 2; + else if (ClientInfo.maxWidth(ClientInfo.SMALL_WIDTH-1)) + return 4; + else if (ClientInfo.maxWidth(ClientInfo.MEDIUM_WIDTH-1)) + return 6; + else + return 8; } private void init() @@ -258,6 +304,8 @@ public class InfoGeneralPanel extends InfoPanel implements EventListener { lbl3.setVisible(false); txt3.setVisible(false); + hideCell(lbl3); + hideCell(txt3); } if (m_queryColumns.size() > 3) @@ -268,10 +316,25 @@ public class InfoGeneralPanel extends InfoPanel implements EventListener { lbl4.setVisible(false); txt4.setVisible(false); + hideCell(lbl4); + hideCell(txt4); } return true; } + private void hideCell(Component comp) { + Component p = comp.getParent(); + while (p != null) + { + if (p instanceof Cell) + { + p.setVisible(false); + break; + } + p = p.getParent(); + } + } + private boolean initInfoTable () { // Get Query Columns @@ -517,4 +580,16 @@ public class InfoGeneralPanel extends InfoPanel implements EventListener southBody.insertBefore(paging, southBody.getFirstChild()); layout.invalidate(); } + + protected void onClientInfo() { + if (layout != null && layout.getNorth() != null && layout.getNorth().getFirstChild() instanceof Grid) { + int t = getNoOfParameterColumn(); + if (t > 0 && noOfParameterColumn > 0 && t != noOfParameterColumn) { + Grid grid = (Grid) layout.getNorth().getFirstChild(); + grid.getRows().detach(); + layoutParameterGrid(grid); + this.invalidate(); + } + } + } } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/InfoPAttributeInstancePanel.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/InfoPAttributeInstancePanel.java index 8a819334d7..2355cf09f1 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/InfoPAttributeInstancePanel.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/InfoPAttributeInstancePanel.java @@ -67,9 +67,12 @@ public class InfoPAttributeInstancePanel extends Window implements EventListener { super(); setTitle(Msg.getMsg(Env.getCtx(), "PAttributeInstance")); - ZKUpdateUtil.setWidth(this, "700px"); - ZKUpdateUtil.setHeight(this, "400px"); + ZKUpdateUtil.setWindowWidthX(this, 700); + ZKUpdateUtil.setWindowHeightX(this, 400); setSclass("popup-dialog"); + setBorder("normal"); + setSizable(true); + setMaximizable(true); init (M_Warehouse_ID, M_Locator_ID, M_Product_ID, C_BPartner_ID); AEnv.showCenterWindow(parent, this); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/InfoPanel.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/InfoPanel.java index 376011e0d4..0cc6b6ca30 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/InfoPanel.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/InfoPanel.java @@ -39,6 +39,7 @@ import org.adempiere.model.IInfoColumn; import org.adempiere.model.MInfoProcess; import org.adempiere.model.MInfoRelated; import org.adempiere.webui.AdempiereWebUI; +import org.adempiere.webui.ClientInfo; import org.adempiere.webui.LayoutUtils; import org.adempiere.webui.apps.AEnv; import org.adempiere.webui.apps.BusyDialog; @@ -274,10 +275,20 @@ public abstract class InfoPanel extends Window implements EventListener, setAttribute(Window.MODE_KEY, Window.MODE_HIGHLIGHTED); setBorder("normal"); setClosable(true); - int height = SessionManager.getAppDesktop().getClientInfo().desktopHeight * 85 / 100; - int width = SessionManager.getAppDesktop().getClientInfo().desktopWidth * 80 / 100; - ZKUpdateUtil.setWidth(this, width + "px"); - ZKUpdateUtil.setHeight(this, height + "px"); + int height = ClientInfo.get().desktopHeight; + int width = ClientInfo.get().desktopWidth; + if (width <= ClientInfo.MEDIUM_WIDTH) + { + ZKUpdateUtil.setWidth(this, "100%"); + ZKUpdateUtil.setHeight(this, "100%"); + } + else + { + height = height * 85 / 100; + width = width * 80 / 100; + ZKUpdateUtil.setWidth(this, width + "px"); + ZKUpdateUtil.setHeight(this, height + "px"); + } this.setContentStyle("overflow: auto"); } else @@ -293,6 +304,13 @@ public abstract class InfoPanel extends Window implements EventListener, confirmPanel.addComponentsLeft(confirmPanel.createButton(ConfirmPanel.A_NEW)); confirmPanel.addActionListener(Events.ON_CLICK, this); ZKUpdateUtil.setHflex(confirmPanel, "1"); + if (ClientInfo.isMobile()) + { + if (ClientInfo.maxWidth(ClientInfo.SMALL_WIDTH) || ClientInfo.maxHeight(ClientInfo.SMALL_HEIGHT)) + { + confirmPanel.addButtonSclass("btn-small small-img-btn"); + } + } // Elaine 2008/12/16 confirmPanel.getButton(ConfirmPanel.A_CUSTOMIZE).setVisible(hasCustomize()); @@ -1065,7 +1083,7 @@ public abstract class InfoPanel extends Window implements EventListener, countSql = countSql.trim(); countSql = countSql.substring(0, countSql.length() - 5); } - String otherClause = infoWindow.getOtherClause(); // Fix otherClause on count + String otherClause = infoWindow != null ? infoWindow.getOtherClause() : null; // Fix otherClause on count if (otherClause != null) countSql = countSql+" "+otherClause; diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/InvoiceHistory.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/InvoiceHistory.java index ec8007e243..5aeffebed6 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/InvoiceHistory.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/InvoiceHistory.java @@ -35,6 +35,7 @@ import org.adempiere.webui.component.Tabs; import org.adempiere.webui.component.WListbox; import org.adempiere.webui.component.Window; import org.adempiere.webui.info.InfoProductWindow; +import org.adempiere.webui.theme.ThemeManager; import org.adempiere.webui.util.ZKUpdateUtil; import org.compiere.model.MDocType; import org.compiere.model.MPriceList; @@ -95,7 +96,7 @@ public class InvoiceHistory extends Window implements EventListener log.log(Level.SEVERE, "", ex); } - this.setSclass("popup-dialog"); + this.setSclass("popup-dialog invoice-history-dialog"); AEnv.showCenterWindow(parent, this); if (parent instanceof InfoProductWindow) showDetailATP = ((InfoProductWindow)parent).isShowDetailATP(); @@ -182,12 +183,26 @@ public class InvoiceHistory extends Window implements EventListener tabbox.addEventListener(Events.ON_SELECT, this); confirmPanel.addActionListener(this); - Borderlayout borderlayout = new Borderlayout(); - ZKUpdateUtil.setWidth(this, "700px"); - ZKUpdateUtil.setHeight(this, "400px"); + Borderlayout borderlayout = new Borderlayout(); + if (!ThemeManager.isUseCSSForWindowSize()) + { + ZKUpdateUtil.setWindowWidthX(this, 700); + ZKUpdateUtil.setWindowHeightX(this, 400); + } + else + { + addCallback(AFTER_PAGE_ATTACHED, t-> { + ZKUpdateUtil.setCSSHeight(this); + ZKUpdateUtil.setCSSWidth(this); + this.invalidate(); + }); + } borderlayout.setStyle("border: none; position: relative"); this.appendChild(borderlayout); this.setClosable(true); + this.setSizable(true); + this.setMaximizable(true); + this.setBorder("normal"); North north = new North(); north.setStyle("border: none"); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/UserPanel.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/UserPanel.java index 11f7d702ef..7b23d1a960 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/UserPanel.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/UserPanel.java @@ -20,6 +20,7 @@ package org.adempiere.webui.panel; import java.util.Properties; import org.adempiere.util.Callback; +import org.adempiere.webui.ClientInfo; import org.adempiere.webui.LayoutUtils; import org.adempiere.webui.component.Label; import org.adempiere.webui.component.Menupopup; @@ -32,16 +33,23 @@ import org.compiere.model.MClient; import org.compiere.model.MOrg; import org.compiere.model.MRole; import org.compiere.model.MUser; +import org.compiere.model.MWarehouse; import org.compiere.util.Env; import org.compiere.util.Msg; +import org.compiere.util.Util; import org.zkoss.zk.ui.Component; +import org.zkoss.zk.ui.HtmlBasedComponent; import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.event.Events; import org.zkoss.zk.ui.event.KeyEvent; +import org.zkoss.zk.ui.event.OpenEvent; import org.zkoss.zk.ui.util.Clients; import org.zkoss.zk.ui.util.Composer; import org.zkoss.zul.Menuitem; +import org.zkoss.zul.Popup; +import org.zkoss.zul.Space; +import org.zkoss.zul.Vlayout; import org.zkoss.zul.impl.LabelImageElement; /** @@ -66,6 +74,10 @@ public class UserPanel implements EventListener, Composer protected Menupopup feedbackMenu; protected Component component; + + protected Component userPanelLinksContainer; + + private Popup popup; private static final String ON_DEFER_CHANGE_ROLE = "onDeferChangeRole"; private static final String ON_DEFER_LOGOUT = "onDeferLogout"; @@ -81,7 +93,15 @@ public class UserPanel implements EventListener, Composer String s = Msg.getMsg(Env.getCtx(), "CloseTabFromBrowser?").replace("\n", "
"); Clients.confirmClose(s); lblUserNameValue = (Label) component.getFellowIfAny("loginUserAndRole", true); - lblUserNameValue.setValue(getUserName() + "@" + getClientName() + "." + getOrgName()+"/"+this.getRoleName()); + if (isMobile()) + { + lblUserNameValue.setValue(getUserName()); + LayoutUtils.addSclass("mobile", (HtmlBasedComponent) component); + } + else + { + lblUserNameValue.setValue(getUserName() + "@" + getClientName() + "." + getOrgName()+"/"+this.getRoleName()); + } lblUserNameValue.addEventListener(Events.ON_CLICK, this); feedback = (LabelImageElement) component.getFellowIfAny("feedback", true); @@ -115,9 +135,19 @@ public class UserPanel implements EventListener, Composer component.addEventListener(ON_DEFER_LOGOUT, this); component.addEventListener(ON_DEFER_CHANGE_ROLE, this); + + userPanelLinksContainer = component.getFellowIfAny("userPanelLinksContainer", true); + if (isMobile() && userPanelLinksContainer != null) + { + userPanelLinksContainer.detach(); + } } - private String getUserName() + private boolean isMobile() { + return ClientInfo.isMobile(); + } + + private String getUserName() { MUser user = MUser.get(ctx); return user.getName(); @@ -173,9 +203,16 @@ public class UserPanel implements EventListener, Composer } else if (lblUserNameValue == event.getTarget()) { - String roleInfo = MRole.getDefault().toStringX(Env.getCtx()); - roleInfo = roleInfo.replace(Env.NL, "
"); - Messagebox.showDialog(roleInfo, Msg.getMsg(ctx, "RoleInfo"), Messagebox.OK, Messagebox.INFORMATION); + if (isMobile()) + { + openMobileUserPanelPopup(); + } + else + { + String roleInfo = MRole.getDefault().toStringX(Env.getCtx()); + roleInfo = roleInfo.replace(Env.NL, "
"); + Messagebox.showDialog(roleInfo, Msg.getMsg(ctx, "RoleInfo"), Messagebox.OK, Messagebox.INFORMATION); + } } else if (changeRole == event.getTarget()) { @@ -255,6 +292,65 @@ public class UserPanel implements EventListener, Composer } + protected void openMobileUserPanelPopup() { + if (popup != null) { + Object value = popup.removeAttribute(popup.getUuid()); + if (value != null && value instanceof Long) { + long ts = ((Long)value).longValue(); + long since = System.currentTimeMillis() - ts; + if (since < 500) { + popup.detach(); + popup = null; + return; + } + } + popup.detach(); + } + popup = new Popup(); + Vlayout layout = new Vlayout(); + layout.setStyle("padding: 8px 16px"); + String email = getUserEmail(); + if (!Util.isEmpty(email)) + { + layout.appendChild(new Label(getUserName() + " <" + email +">")); + } + else + { + layout.appendChild(new Label(getUserName())); + } + layout.appendChild(new Label(getRoleName())); + layout.appendChild(new Label(getClientName() + "." + getOrgName())); + String warehouse = getWarehouseName(); + if (!Util.isEmpty(warehouse)) + layout.appendChild(new Label(warehouse)); + layout.appendChild(new Space()); + layout.appendChild(userPanelLinksContainer); + + popup.appendChild(layout); + popup.setPage(component.getPage()); + popup.setVflex("min"); + popup.setHflex("min"); + popup.addEventListener(Events.ON_OPEN, (OpenEvent oe) -> { + if (!oe.isOpen()) + popup.setAttribute(popup.getUuid(), System.currentTimeMillis()); + }); + popup.open(lblUserNameValue, "after_start"); + + } + + private String getUserEmail() { + MUser user = MUser.get(ctx); + return user.getEMail(); + } + + private String getWarehouseName() { + int id = Env.getContextAsInt(Env.getCtx(), Env.M_WAREHOUSE_ID); + if (id > 0) { + return MWarehouse.get(Env.getCtx(), id).getName(); + } + return null; + } + @Override public void doAfterCompose(Component comp) throws Exception { this.component = comp; diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/WAttachment.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/WAttachment.java index af2c0a6561..81f52ead0c 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/WAttachment.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/WAttachment.java @@ -26,6 +26,7 @@ import java.util.logging.Level; import org.adempiere.util.Callback; import org.adempiere.webui.AdempiereWebUI; +import org.adempiere.webui.ClientInfo; import org.adempiere.webui.apps.AEnv; import org.adempiere.webui.component.Button; import org.adempiere.webui.component.ConfirmPanel; @@ -114,6 +115,8 @@ public class WAttachment extends Window implements EventListener private int displayIndex; + private String orientation; + private static List autoPreviewList; static { @@ -220,13 +223,23 @@ public class WAttachment extends Window implements EventListener { this.setAttribute(AdempiereWebUI.WIDGET_INSTANCE_NAME, "attachment"); this.setMaximizable(true); - ZKUpdateUtil.setWidth(this, "700px"); - ZKUpdateUtil.setHeight(this, "85%"); + if (!ThemeManager.isUseCSSForWindowSize()) + { + ZKUpdateUtil.setWindowWidthX(this, 700); + ZKUpdateUtil.setHeight(this, "85%"); + } + else + { + addCallback(AFTER_PAGE_ATTACHED, t -> { + ZKUpdateUtil.setCSSHeight(this); + ZKUpdateUtil.setCSSWidth(this); + }); + } this.setTitle(Msg.getMsg(Env.getCtx(), "Attachment")); this.setClosable(true); this.setSizable(true); this.setBorder("normal"); - this.setSclass("popup-dialog"); + this.setSclass("popup-dialog attachment-dialog"); this.setShadow(true); this.appendChild(mainPanel); ZKUpdateUtil.setHeight(mainPanel, "100%"); @@ -314,7 +327,28 @@ public class WAttachment extends Window implements EventListener hbox.appendChild(bCancel); - text.setTooltiptext(Msg.getElement(Env.getCtx(), "TextMsg")); + text.setTooltiptext(Msg.getElement(Env.getCtx(), "TextMsg")); + + if (ClientInfo.isMobile()) + { + orientation = ClientInfo.get().orientation; + ClientInfo.onClientInfo(this, this::onClientInfo); + } + } + + protected void onClientInfo() + { + if (getPage() != null) + { + String newOrienation = ClientInfo.get().orientation; + if (!newOrienation.equals(orientation)) + { + orientation = newOrienation; + ZKUpdateUtil.setCSSHeight(this); + ZKUpdateUtil.setCSSWidth(this); + invalidate(); + } + } } /** @@ -690,5 +724,5 @@ public class WAttachment extends Window implements EventListener } } return "UTF-8"; - } + } } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/WDocActionPanel.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/WDocActionPanel.java index fd3da6d805..04311db92c 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/WDocActionPanel.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/WDocActionPanel.java @@ -33,6 +33,7 @@ import org.adempiere.webui.component.Row; import org.adempiere.webui.component.Rows; import org.adempiere.webui.component.Window; import org.adempiere.webui.event.DialogEvents; +import org.adempiere.webui.theme.ThemeManager; import org.adempiere.webui.util.ZKUpdateUtil; import org.adempiere.webui.window.FDialog; import org.compiere.model.GridTab; @@ -270,7 +271,7 @@ public class WDocActionPanel extends Window implements EventListener, Dia private void init() { - setSclass("popup-dialog"); + setSclass("popup-dialog doc-action-dialog"); Vlayout vlayout = new Vlayout(); ZKUpdateUtil.setHflex(vlayout, "1"); this.appendChild(vlayout); @@ -308,7 +309,8 @@ public class WDocActionPanel extends Window implements EventListener, Dia ZKUpdateUtil.setVflex(confirmPanel, "min"); this.setTitle(Msg.translate(Env.getCtx(), "DocAction")); - ZKUpdateUtil.setWidth(this, "410px"); + if (!ThemeManager.isUseCSSForWindowSize()) + ZKUpdateUtil.setWindowWidthX(this, 410); this.setBorder("normal"); this.setZindex(1000); } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/WProcessParameterForm.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/WProcessParameterForm.java index 094f16589e..8cea3ca4e8 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/WProcessParameterForm.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/WProcessParameterForm.java @@ -26,6 +26,7 @@ import org.adempiere.webui.component.ConfirmPanel; import org.adempiere.webui.component.Panel; import org.adempiere.webui.component.VerticalBox; import org.adempiere.webui.factory.ButtonFactory; +import org.adempiere.webui.theme.ThemeManager; import org.adempiere.webui.util.ZKUpdateUtil; import org.compiere.model.MPInstancePara; import org.compiere.model.MScheduler; @@ -121,7 +122,11 @@ public class WProcessParameterForm extends ADForm } this.setSizable(true); this.setClosable(true); - ZKUpdateUtil.setWidth(this, "500px"); + if (!ThemeManager.isUseCSSForWindowSize()) { + ZKUpdateUtil.setWindowWidthX(this, 500); + } else { + ZKUpdateUtil.setWidth(this, null); + } ZKUpdateUtil.setVflex(this, "min"); } @@ -157,8 +162,8 @@ public class WProcessParameterForm extends ADForm hbox.appendChild(btn); hbox.setPack("end"); dialogBody.appendChild(hbox); - this.appendChild(dialogBody); - this.setSclass("popup-dialog"); + this.appendChild(dialogBody); + this.setSclass("popup-dialog process-parameter-form-dialog"); } /** @@ -234,4 +239,10 @@ public class WProcessParameterForm extends ADForm return true; } // init + + @Override + public void setWidth(String width) { + super.setWidth(width); + } + } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/WSchedule.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/WSchedule.java index 948118274b..c1dd3389c4 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/WSchedule.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/WSchedule.java @@ -202,6 +202,8 @@ public class WSchedule extends Window implements EventListener this.appendChild(button); divTabClicked(7); + + addEventListener("onAfterReCreate", this); } // jbInit /** @@ -214,7 +216,7 @@ public class WSchedule extends Window implements EventListener this.S_Resource_ID = S_Resource_ID; calendars.setCurrentDate(date); - updateModel(); + Events.echoEvent("onAfterReCreate", this, null); } // recreate private void updateModel() { @@ -296,6 +298,8 @@ public class WSchedule extends Window implements EventListener String text = String.valueOf(event.getData()); int days = Msg.getMsg(Env.getCtx(),"Day").equals(text) ? 1: Msg.getMsg(Env.getCtx(),"5Days").equals(text) ? 5: Msg.getMsg(Env.getCtx(),"Week" ).equals(text) ? 7: 0; divTabClicked(days); + } else if (type.equals("onAfterReCreate")) { + updateModel(); } else { Events.sendEvent(this, event); } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/action/CSVImportAction.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/action/CSVImportAction.java index 79bddcf11f..c2f72d2113 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/action/CSVImportAction.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/action/CSVImportAction.java @@ -143,7 +143,7 @@ public class CSVImportAction implements EventListener { winImportFile = new Window(); winImportFile.setTitle(Msg.getMsg(Env.getCtx(), "FileImport") + ": " + panel.getActiveGridTab().getName()); - ZKUpdateUtil.setWidth(winImportFile, "450px"); + ZKUpdateUtil.setWindowWidthX(winImportFile, 450); winImportFile.setClosable(true); winImportFile.setBorder("normal"); winImportFile.setStyle("position:absolute"); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/action/ExportAction.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/action/ExportAction.java index ac375bd74f..0435823bfc 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/action/ExportAction.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/action/ExportAction.java @@ -107,7 +107,7 @@ public class ExportAction implements EventListener { winExportFile = new Window(); winExportFile.setTitle(Msg.getMsg(Env.getCtx(), "Export") + ": " + panel.getActiveGridTab().getName()); - ZKUpdateUtil.setWidth(winExportFile, "450px"); + ZKUpdateUtil.setWindowWidthX(winExportFile, 450); winExportFile.setClosable(true); winExportFile.setBorder("normal"); winExportFile.setStyle("position:absolute"); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/action/FileImportAction.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/action/FileImportAction.java index d3f3e6974c..278d00bf1e 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/action/FileImportAction.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/action/FileImportAction.java @@ -144,7 +144,7 @@ public class FileImportAction implements EventListener { winImportFile = new Window(); winImportFile.setTitle(Msg.getMsg(Env.getCtx(), "FileImport") + ": " + panel.getActiveGridTab().getName()); - ZKUpdateUtil.setWidth(winImportFile, "450px"); + ZKUpdateUtil.setWindowWidthX(winImportFile, 450); winImportFile.setClosable(true); winImportFile.setBorder("normal"); winImportFile.setStyle("position:absolute"); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/action/ReportAction.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/action/ReportAction.java index b41b7cd6f6..c501ff90fa 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/action/ReportAction.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/panel/action/ReportAction.java @@ -96,7 +96,7 @@ public class ReportAction implements EventListener if(winReport == null) { winReport = new Window(); - ZKUpdateUtil.setWidth(winReport, "450px"); + ZKUpdateUtil.setWindowWidthX(winReport, 450); winReport.setClosable(true); winReport.setBorder("normal"); winReport.setStyle("position:absolute"); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/part/WindowContainer.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/part/WindowContainer.java index 825c7291c5..f57945bc9d 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/part/WindowContainer.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/part/WindowContainer.java @@ -15,6 +15,7 @@ package org.adempiere.webui.part; import java.util.List; +import org.adempiere.webui.ClientInfo; import org.adempiere.webui.component.Menupopup; import org.adempiere.webui.component.Tab; import org.adempiere.webui.component.Tab.DecorateInfo; @@ -22,14 +23,18 @@ import org.adempiere.webui.component.Tabbox; import org.adempiere.webui.component.Tabpanel; import org.adempiere.webui.component.Tabpanels; import org.adempiere.webui.component.Tabs; +import org.adempiere.webui.component.ToolBar; +import org.adempiere.webui.component.ToolBarButton; import org.adempiere.webui.desktop.TabbedDesktop; import org.adempiere.webui.panel.IHelpContext; import org.adempiere.webui.session.SessionManager; +import org.adempiere.webui.theme.ThemeManager; import org.adempiere.webui.util.ZKUpdateUtil; import org.compiere.model.X_AD_CtxHelp; import org.compiere.util.Env; import org.compiere.util.Msg; import org.zkoss.zk.ui.Component; +import org.zkoss.zk.ui.Page; import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.event.Events; @@ -44,6 +49,8 @@ import org.zkoss.zul.Menuitem; */ public class WindowContainer extends AbstractUIPart implements EventListener { + private static final String ON_AFTER_TAB_CLOSE = "onAfterTabClose"; + private static final String ON_DEFER_SET_SELECTED_TAB = "onDeferSetSelectedTab"; public static final String ON_WINDOW_CONTAINER_SELECTION_CHANGED_EVENT = "onWindowContainerSelectionChanged"; @@ -52,7 +59,9 @@ public class WindowContainer extends AbstractUIPart implements EventListener { + updateMobileTabState(tabbox.getSelectedTab()); + updateTabListButton(); + }); Tabpanels tabpanels = new Tabpanels(); Tabs tabs = new Tabs(); @@ -105,10 +119,49 @@ public class WindowContainer extends AbstractUIPart implements EventListener setSelectedTab(tabbox.getTabpanel(0).getLinkedTab())); + toolbar.appendChild(homeButton); + + tabListBtn = new ToolBarButton(); + tabListBtn.setImage(ThemeManager.getThemeResource("images/expand-header.png")); + tabListBtn.setSclass("window-container-toolbar-btn"); + tabListBtn.addEventListener(Events.ON_CLICK, evt -> showTabList()); + tabListBtn.setVisible(false); + toolbar.appendChild(tabListBtn); + } + return tabbox; } - /** + private void showTabList() { + org.zkoss.zul.Tabs tabs = tabbox.getTabs(); + List list = tabs.getChildren(); + Menupopup popup = new Menupopup(); + for(int i = 1; i < list.size(); i++) { + Tab tab = (Tab) list.get(i); + Menuitem item = new Menuitem(tab.getLabel()); + item.setValue(Integer.toString(i)); + item.setTooltiptext(tab.getTooltiptext()); + popup.appendChild(item); + item.addEventListener(Events.ON_CLICK, evt -> { + Menuitem t = (Menuitem) evt.getTarget(); + String s = t.getValue(); + Integer ti = Integer.parseInt(s); + setSelectedTab(tabbox.getTabpanel(ti.intValue()).getLinkedTab()); + }); + } + popup.setPage(tabbox.getPage()); + popup.open(tabListBtn, "after_start"); + } + + /** * @deprecated keep for compatible, replace by {@link #addWindow(Component, String, boolean, DecorateInfo)} * @param comp * @param title @@ -189,7 +242,16 @@ public class WindowContainer extends AbstractUIPart implements EventListener 0) { + tabListBtn.setLabel(Integer.toString(cnt)); + tabListBtn.setVisible(true); + } else { + tabListBtn.setLabel(""); + tabListBtn.setVisible(false); + } + } + } + public void setTabTitle(String title, int windowNo) { setTabTitle(title, getTab(windowNo)); } @@ -392,9 +475,29 @@ public class WindowContainer extends AbstractUIPart implements EventListener tabs = tabbox.getTabs().getChildren(); + for(Component c: tabs) { + if (c instanceof Tab) { + Tab t = (Tab) c; + t.setVisible(t == tab); + t.getLinkedPanel().setVisible(t == tab); + } + } + tabbox.getTabs().invalidate(); + } + } + + private boolean isMobile() { + return ClientInfo.isMobile(); + } + + /** * * @return true if successfully close the active window */ @@ -440,6 +543,13 @@ public class WindowContainer extends AbstractUIPart implements EventListener desktopHeight + * @param comp + * @param heightInPixel Height in Pixel + */ + public static void setWindowHeightX(HtmlBasedComponent comp, int heightInPixel){ + int desktopHeight = ClientInfo.get().desktopHeight; + if (desktopHeight > 0 && desktopHeight < heightInPixel) { + setHeight(comp, "100%"); + } else { + setHeight(comp, heightInPixel+"px"); + } + } + + /** + * Set width of popup, window or dialog to widthInPixel. Set width to 100% if widthInPixel > desktopWidth + * @param comp + * @param widthInPixel + */ + public static void setWindowWidthX(HtmlBasedComponent comp, int widthInPixel){ + int desktopWidth = ClientInfo.get().desktopWidth; + if (desktopWidth > 0 && desktopWidth < widthInPixel) { + setWidth(comp, "100%"); + } else { + setWidth(comp, widthInPixel+"px"); + } + } } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/AboutWindow.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/AboutWindow.java index 2167a55ef7..758ef14e22 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/AboutWindow.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/AboutWindow.java @@ -108,7 +108,7 @@ public class AboutWindow extends Window implements EventListener { this.setPosition("center"); this.setTitle(ThemeManager.getBrowserTitle()); - this.setSclass("popup-dialog"); + this.setSclass("popup-dialog about-window"); this.setClosable(true); this.setMaximizable(true); this.setSizable(true); @@ -146,8 +146,18 @@ public class AboutWindow extends Window implements EventListener { southPane.appendChild(btnOk); this.setBorder("normal"); - ZKUpdateUtil.setWidth(this, "600px"); - ZKUpdateUtil.setHeight(this, "450px"); + if (!ThemeManager.isUseCSSForWindowSize()) + { + ZKUpdateUtil.setWindowWidthX(this, 600); + ZKUpdateUtil.setWindowHeightX(this, 450); + } + else + { + addCallback(AFTER_PAGE_ATTACHED, t-> { + ZKUpdateUtil.setCSSHeight(this); + ZKUpdateUtil.setCSSWidth(this); + }); + } this.setShadow(true); this.setAttribute(Window.MODE_KEY, Window.MODE_HIGHLIGHTED); } @@ -555,8 +565,8 @@ public class AboutWindow extends Window implements EventListener { w.setClosable(true); w.setMaximizable(true); w.setSizable(true); - ZKUpdateUtil.setWidth(w, "600px"); - ZKUpdateUtil.setHeight(w, "500px"); + ZKUpdateUtil.setWindowWidthX(w, 600); + ZKUpdateUtil.setWindowHeightX(w, 500); Textarea textbox = new Textarea(); textbox.setDynamicProperty("readonly", "true"); textbox.setStyle("width:99%; height: 99%; margin: auto; display: inline-block;"); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/CustomizeGridViewDialog.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/CustomizeGridViewDialog.java index d7dcec0f73..81eb1ef549 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/CustomizeGridViewDialog.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/CustomizeGridViewDialog.java @@ -7,6 +7,7 @@ import org.adempiere.webui.adwindow.GridView; import org.adempiere.webui.apps.AEnv; import org.adempiere.webui.component.Window; import org.adempiere.webui.panel.CustomizeGridViewPanel; +import org.adempiere.webui.theme.ThemeManager; import org.adempiere.webui.util.ZKUpdateUtil; import org.compiere.util.Env; import org.compiere.util.Msg; @@ -36,11 +37,18 @@ public class CustomizeGridViewDialog extends Window { private void initComponent(int windowNo, int AD_Tab_ID, int AD_User_ID, Map columnsWidth,ArrayList gridFieldIds) { customizePanel = new CustomizeGridViewPanel(windowNo, AD_Tab_ID, AD_User_ID, columnsWidth,gridFieldIds); - this.setStyle("position : absolute;"); - ZKUpdateUtil.setWidth(this, "600px"); - ZKUpdateUtil.setHeight(this, "500px"); + this.setStyle("position : relative;"); + if (!ThemeManager.isUseCSSForWindowSize()) { + ZKUpdateUtil.setWindowWidthX(this, 600); + ZKUpdateUtil.setWindowHeightX(this, 500); + } else { + addCallback(AFTER_PAGE_ATTACHED, t-> { + ZKUpdateUtil.setCSSHeight(this); + ZKUpdateUtil.setCSSWidth(this); + }); + } this.setBorder("normal"); - this.setSclass("popup-dialog"); + this.setSclass("popup-dialog customize-grid-view-dialog"); appendChild(customizePanel); customizePanel.createUI(); customizePanel.query(); @@ -71,6 +79,5 @@ public class CustomizeGridViewDialog extends Window { customizeWindow.setGridPanel(gridPanel); AEnv.showWindow(customizeWindow); return customizeWindow.isSaved(); - } // showProduct - + } // showProduct } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/FindWindow.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/FindWindow.java index 041308777a..efdabf830b 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/FindWindow.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/FindWindow.java @@ -38,6 +38,7 @@ import java.util.logging.Level; import java.util.regex.Pattern; import org.adempiere.webui.AdempiereWebUI; +import org.adempiere.webui.ClientInfo; import org.adempiere.webui.LayoutUtils; import org.adempiere.webui.component.Button; import org.adempiere.webui.component.Column; @@ -463,11 +464,12 @@ public class FindWindow extends Window implements EventListener, ValueCha ListHeader lstHAndOr = new ListHeader(); lstHAndOr.setLabel(Msg.getMsg(Env.getCtx(), "And/Or")); - ZKUpdateUtil.setWidth(lstHAndOr, "10%"); + ZKUpdateUtil.setWidth(lstHAndOr, "60px"); ListHeader lstHLeftBracket = new ListHeader(); lstHLeftBracket.setLabel("("); - ZKUpdateUtil.setWidth(lstHLeftBracket, "6%"); + lstHLeftBracket.setAlign("center"); + ZKUpdateUtil.setWidth(lstHLeftBracket, "50px"); ListHeader lstHColumn = new ListHeader(); lstHColumn.setLabel(Msg.translate(Env.getCtx(), "AD_Column_ID")); @@ -475,6 +477,7 @@ public class FindWindow extends Window implements EventListener, ValueCha ListHeader lstHOperator = new ListHeader(); lstHOperator.setLabel(Msg.getMsg(Env.getCtx(), "Operator")); + ZKUpdateUtil.setWidth(lstHOperator, "70px"); ListHeader lstHQueryValue = new ListHeader(); lstHQueryValue.setLabel(Msg.getMsg(Env.getCtx(), "QueryValue")); @@ -486,7 +489,14 @@ public class FindWindow extends Window implements EventListener, ValueCha ListHeader lstHRightBracket = new ListHeader(); lstHRightBracket.setLabel(")"); - ZKUpdateUtil.setWidth(lstHRightBracket, "6%"); + lstHRightBracket.setAlign("center"); + ZKUpdateUtil.setWidth(lstHRightBracket, "50px"); + + if (ClientInfo.maxWidth(ClientInfo.SMALL_WIDTH-1)) { + ZKUpdateUtil.setWidth(lstHColumn, "200px"); + ZKUpdateUtil.setWidth(lstHQueryValue, "200px"); + ZKUpdateUtil.setWidth(lstHQueryTo, "200px"); + } listhead.appendChild(lstHAndOr); listhead.appendChild(lstHLeftBracket); @@ -566,7 +576,10 @@ public class FindWindow extends Window implements EventListener, ValueCha fQueryName.addEventListener(Events.ON_SELECT, this); Label label = new Label(Msg.getMsg(Env.getCtx(), "SavedQuery")); - label.setStyle("vertical-align: middle;"); + if (ClientInfo.maxWidth(639)) + label.setStyle("vertical-align: middle;display: block; padding-left: 4px; padding-top: 4px;"); + else + label.setStyle("vertical-align: middle;"); div.appendChild(label); div.appendChild(fQueryName); div.appendChild(btnSave); @@ -580,7 +593,10 @@ public class FindWindow extends Window implements EventListener, ValueCha // adding history combo prepareHistoryCombo(); Label labelHistory = new Label(Msg.getMsg(Env.getCtx(), HISTORY_LABEL)); - labelHistory.setStyle("vertical-align: middle;"); + if (ClientInfo.maxWidth(639)) + labelHistory.setStyle("vertical-align: middle; display: block;padding-left: 4px; padding-top: 4px;"); + else + labelHistory.setStyle("vertical-align: middle;"); div.appendChild(labelHistory); div.appendChild(historyCombo); historyCombo.setStyle("margin-left: 3px; margin-right: 3px; position: relative; vertical-align: middle;"); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/InfoSchedule.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/InfoSchedule.java index 7c9f7b78aa..139725fbb1 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/InfoSchedule.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/InfoSchedule.java @@ -112,8 +112,8 @@ public class InfoSchedule extends Window implements EventListener if (createNew) { setAttribute(Window.MODE_KEY, Window.MODE_HIGHLIGHTED); - ZKUpdateUtil.setWidth(this, "700px"); - ZKUpdateUtil.setHeight(this, "600px"); + ZKUpdateUtil.setWindowWidthX(this, 700); + ZKUpdateUtil.setWindowHeightX(this, 600); this.setSizable(true); } else diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/SimplePDFViewer.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/SimplePDFViewer.java index 3605abc0f0..4e3cb35bfa 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/SimplePDFViewer.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/SimplePDFViewer.java @@ -14,13 +14,17 @@ package org.adempiere.webui.window; import java.io.InputStream; +import org.adempiere.webui.ClientInfo; import org.adempiere.webui.component.Window; -import org.adempiere.webui.session.SessionManager; import org.adempiere.webui.util.ZKUpdateUtil; import org.compiere.util.Env; import org.compiere.util.Msg; import org.zkoss.util.media.AMedia; +import org.zkoss.util.media.Media; +import org.zkoss.zk.ui.ext.render.DynamicMedia; import org.zkoss.zul.Iframe; +import org.zkoss.zul.impl.Utils; +import org.zkoss.zul.impl.XulElement; /** * @@ -33,28 +37,70 @@ public class SimplePDFViewer extends Window { * */ private static final long serialVersionUID = -6417954023873414350L; + private AMedia media; + private int mediaVersion = 0; public SimplePDFViewer(String title, InputStream pdfInput) { Iframe iframe = new Iframe(); iframe.setId("reportFrame"); - int height = Double.valueOf(SessionManager.getAppDesktop().getClientInfo().desktopHeight * 0.85).intValue(); + int height = 0; + if (ClientInfo.maxHeight((ClientInfo.SMALL_HEIGHT + ClientInfo.EXTRA_SMALL_HEIGHT)/2)) { + height = ClientInfo.get().desktopHeight; + } else { + height = Double.valueOf(ClientInfo.get().desktopHeight * 0.85).intValue(); + } ZKUpdateUtil.setHeight(this, height + "px"); - height = height - 30; ZKUpdateUtil.setHeight(iframe, height + "px"); ZKUpdateUtil.setWidth(iframe, "100%"); - AMedia media = new AMedia(getTitle(), "pdf", "application/pdf", pdfInput); - iframe.setContent(media); + media = new AMedia(getTitle(), "pdf", "application/pdf", pdfInput); + if (ClientInfo.isMobile()) { + if (getPage() != null) { + showMobileViewer(iframe); + } else { + addCallback(AFTER_PAGE_ATTACHED, t -> showMobileViewer(iframe)); + } + } else { + iframe.setContent(media); + } this.setBorder("normal"); this.appendChild(iframe); this.setClosable(true); + this.setMaximizable(true); if (title != null && title.trim().length() > 0) this.setTitle(title); else this.setTitle(Msg.translate(Env.getCtx(), "PDF")); - int width = Double.valueOf(SessionManager.getAppDesktop().getClientInfo().desktopWidth * 0.80).intValue(); + int width = 0; + if (ClientInfo.maxWidth(ClientInfo.SMALL_WIDTH-1)) { + width = ClientInfo.get().desktopWidth; + } else { + width = Double.valueOf(ClientInfo.get().desktopWidth * 0.80).intValue(); + } ZKUpdateUtil.setWidth(this, width + "px"); } + + protected void showMobileViewer(Iframe iframe) { + mediaVersion++; + String url = Utils.getDynamicMediaURI(this, mediaVersion, media.getName(), media.getFormat()); + String pdfJsUrl = "pdf.js/web/viewer.html?file="+url; + iframe.setSrc(pdfJsUrl); + } + + //-- ComponentCtrl --// + public Object getExtraCtrl() { + return new ExtraCtrl(); + } + /** A utility class to implement {@link #getExtraCtrl}. + * It is used only by component developers. + */ + protected class ExtraCtrl extends XulElement.ExtraCtrl + implements DynamicMedia { + //-- DynamicMedia --// + public Media getMedia(String pathInfo) { + return media; + } + } } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WAccountDialog.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WAccountDialog.java index cb4c3dbf55..92c49e520b 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WAccountDialog.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WAccountDialog.java @@ -24,6 +24,7 @@ import java.sql.SQLException; import java.util.logging.Level; import org.adempiere.util.Callback; +import org.adempiere.webui.ClientInfo; import org.adempiere.webui.adwindow.ADTabpanel; import org.adempiere.webui.apps.AEnv; import org.adempiere.webui.component.ConfirmPanel; @@ -72,6 +73,7 @@ import org.zkoss.zul.Hbox; import org.zkoss.zul.North; import org.zkoss.zul.South; import org.zkoss.zul.Vbox; +import org.zkoss.zul.Vlayout; /** * Dialog to enter Account Info @@ -87,7 +89,7 @@ public final class WAccountDialog extends Window private static final long serialVersionUID = 3041802296879719489L; private Callback m_callback; - + /** * Constructor * @param title title @@ -99,8 +101,19 @@ public final class WAccountDialog extends Window { super (); this.setTitle(title); - ZKUpdateUtil.setHeight(this, "500px"); - ZKUpdateUtil.setWidth(this, "750px"); + if (!ThemeManager.isUseCSSForWindowSize()) + { + ZKUpdateUtil.setWindowHeightX(this, 500); + ZKUpdateUtil.setWindowWidthX(this, 750); + } + else + { + addCallback(AFTER_PAGE_ATTACHED, t-> { + ZKUpdateUtil.setCSSHeight(this); + ZKUpdateUtil.setCSSWidth(this); + this.invalidate(); + }); + } if (log.isLoggable(Level.CONFIG)) log.config("C_AcctSchema_ID=" + C_AcctSchema_ID + ", C_ValidCombination_ID=" + mAccount.C_ValidCombination_ID); @@ -179,6 +192,8 @@ public final class WAccountDialog extends Window private Row m_row; private Rows m_rows; + private boolean m_smallWidth; + /** @@ -200,11 +215,11 @@ public final class WAccountDialog extends Window // Caption caption = new Caption(Msg.getMsg(Env.getCtx(),"Parameter")); parameterPanel.appendChild(caption); - ZKUpdateUtil.setHflex(parameterPanel, "95"); + ZKUpdateUtil.setHflex(parameterPanel, "min"); parameterPanel.setStyle("background-color: transparent;"); toolBar.setOrient("vertical"); - toolBar.setStyle("border: none; margin: 5px"); - ZKUpdateUtil.setHflex(toolBar, "5"); + toolBar.setStyle("border: none; padding: 5px"); + ZKUpdateUtil.setHflex(toolBar, "min"); bSave.setImage(ThemeManager.getThemeResource("images/Save24.png")); bSave.setTooltiptext(Msg.getMsg(Env.getCtx(),"AccountNewUpdate")); @@ -222,7 +237,6 @@ public final class WAccountDialog extends Window // northPanel.appendChild(parameterPanel); - ZKUpdateUtil.setWidth(parameterPanel, "95%"); northPanel.appendChild(toolBar); ZKUpdateUtil.setWidth(northPanel, "100%"); @@ -232,21 +246,26 @@ public final class WAccountDialog extends Window layout.setParent(this); ZKUpdateUtil.setHeight(layout, "100%"); ZKUpdateUtil.setWidth(layout, "100%"); - layout.setStyle("background-color: transparent;"); + layout.setStyle("background-color: transparent; position: relative;"); North nRegion = new North(); nRegion.setParent(layout); ZKUpdateUtil.setHflex(northPanel, "false"); - ZKUpdateUtil.setVflex(northPanel, "false"); + ZKUpdateUtil.setVflex(northPanel, "min"); + ZKUpdateUtil.setVflex(parameterPanel, "min"); nRegion.appendChild(northPanel); nRegion.setStyle("background-color: transparent; border: none"); northPanel.setStyle("background-color: transparent;"); + nRegion.setCollapsible(true); + nRegion.setSplittable(true); + nRegion.setAutoscroll(true); Center cRegion = new Center(); cRegion.setParent(layout); ZKUpdateUtil.setHflex(m_adTabPanel, "true"); ZKUpdateUtil.setVflex(m_adTabPanel, "true"); cRegion.appendChild(m_adTabPanel); + ZKUpdateUtil.setVflex(cRegion, "min"); South sRegion = new South(); sRegion.setParent(layout); @@ -256,6 +275,10 @@ public final class WAccountDialog extends Window div.appendChild(statusBar); sRegion.appendChild(div); sRegion.setStyle("background-color: transparent; border: none"); + ZKUpdateUtil.setVflex(sRegion, "min"); + ZKUpdateUtil.setVflex(div, "min"); + ZKUpdateUtil.setVflex(confirmPanel, "min"); + ZKUpdateUtil.setVflex(statusBar, "min"); confirmPanel.addActionListener(Events.ON_CLICK, this); @@ -263,6 +286,11 @@ public final class WAccountDialog extends Window this.setClosable(false); this.setSizable(true); + this.setSclass("account-dialog"); + + if (ClientInfo.isMobile()) { + ClientInfo.onClientInfo(this, this::onClientInfo); + } } // jbInit /** @@ -320,133 +348,7 @@ public final class WAccountDialog extends Window parameterLayout.setParent(parameterPanel); parameterLayout.setStyle("background-color: transparent; margin:none; border:none; padding:none;"); - m_rows = new Rows(); - m_rows.setParent(parameterLayout); - - // Alias - if (s_AcctSchema.isHasAlias()) - { - GridField alias = m_mTab.getField("Alias"); - f_Alias = WebEditorFactory.getEditor(alias, false); - addLine(alias, f_Alias, false); - } // Alias - - // Combination - GridField combination = m_mTab.getField("Combination"); - f_Combination = WebEditorFactory.getEditor(combination, false); - addLine(combination, f_Combination, false); - m_newRow = true; - - /** - * Create Fields in Element Order - */ - MAcctSchemaElement[] elements = s_AcctSchema.getAcctSchemaElements(); - for (int i = 0; i < elements.length; i++) - { - MAcctSchemaElement ase = elements[i]; - String type = ase.getElementType(); - boolean isMandatory = ase.isMandatory(); - // - if (type.equals(MAcctSchemaElement.ELEMENTTYPE_Organization)) - { - GridField field = m_mTab.getField("AD_Org_ID"); - f_AD_Org_ID = WebEditorFactory.getEditor(field, false); - addLine(field, f_AD_Org_ID, isMandatory); - } - else if (type.equals(MAcctSchemaElement.ELEMENTTYPE_Account)) - { - GridField field = m_mTab.getField("Account_ID"); - f_Account_ID = WebEditorFactory.getEditor(field, false); - // ((VLookup)f_Account_ID).setWidth(400); - addLine(field, f_Account_ID, isMandatory); - f_Account_ID.addValueChangeListener(this); - } - else if (type.equals(MAcctSchemaElement.ELEMENTTYPE_SubAccount)) - { - GridField field = m_mTab.getField("C_SubAcct_ID"); - f_SubAcct_ID = WebEditorFactory.getEditor(field, false); - // ((VLookup)f_SubAcct_ID).setWidth(400); - addLine(field, f_SubAcct_ID, isMandatory); - } - else if (type.equals(MAcctSchemaElement.ELEMENTTYPE_Product)) - { - GridField field = m_mTab.getField("M_Product_ID"); - f_M_Product_ID = WebEditorFactory.getEditor(field, false); - addLine(field, f_M_Product_ID, isMandatory); - } - else if (type.equals(MAcctSchemaElement.ELEMENTTYPE_BPartner)) - { - GridField field = m_mTab.getField("C_BPartner_ID"); - f_C_BPartner_ID = WebEditorFactory.getEditor(field, false); - addLine(field, f_C_BPartner_ID, isMandatory); - } - else if (type.equals(MAcctSchemaElement.ELEMENTTYPE_Campaign)) - { - GridField field = m_mTab.getField("C_Campaign_ID"); - f_C_Campaign_ID = WebEditorFactory.getEditor(field, false); - addLine(field, f_C_Campaign_ID, isMandatory); - } - else if (type.equals(MAcctSchemaElement.ELEMENTTYPE_LocationFrom)) - { - GridField field = m_mTab.getField("C_LocFrom_ID"); - f_C_LocFrom_ID = WebEditorFactory.getEditor(field, false); - addLine(field, f_C_LocFrom_ID, isMandatory); - } - else if (type.equals(MAcctSchemaElement.ELEMENTTYPE_LocationTo)) - { - GridField field = m_mTab.getField("C_LocTo_ID"); - f_C_LocTo_ID = WebEditorFactory.getEditor(field, false); - addLine(field, f_C_LocTo_ID, isMandatory); - } - else if (type.equals(MAcctSchemaElement.ELEMENTTYPE_Project)) - { - GridField field = m_mTab.getField("C_Project_ID"); - f_C_Project_ID = WebEditorFactory.getEditor(field, false); - addLine(field, f_C_Project_ID, isMandatory); - } - else if (type.equals(MAcctSchemaElement.ELEMENTTYPE_SalesRegion)) - { - GridField field = m_mTab.getField("C_SalesRegion_ID"); - f_C_SalesRegion_ID = WebEditorFactory.getEditor(field, false); - addLine(field, f_C_SalesRegion_ID, isMandatory); - } - else if (type.equals(MAcctSchemaElement.ELEMENTTYPE_OrgTrx)) - { - GridField field = m_mTab.getField("AD_OrgTrx_ID"); - f_AD_OrgTrx_ID = WebEditorFactory.getEditor(field, false); - addLine(field, f_AD_OrgTrx_ID, isMandatory); - } - else if (type.equals(MAcctSchemaElement.ELEMENTTYPE_Activity)) - { - GridField field = m_mTab.getField("C_Activity_ID"); - f_C_Activity_ID = WebEditorFactory.getEditor(field, false); - addLine(field, f_C_Activity_ID, isMandatory); - } - // User1 - else if (type.equals(MAcctSchemaElement.ELEMENTTYPE_UserElementList1)) - { - GridField field = m_mTab.getField("User1_ID"); - f_User1_ID = WebEditorFactory.getEditor(field, false); - addLine(field, f_User1_ID, isMandatory); - } - else if (type.equals(MAcctSchemaElement.ELEMENTTYPE_UserElementList2)) - { - GridField field = m_mTab.getField("User2_ID"); - f_User2_ID = WebEditorFactory.getEditor(field, false); - addLine(field, f_User2_ID, isMandatory); - } - } // Create Fields in Element Order - - // Add description - m_newRow = true; - Row row = new Row(); - f_Description.setStyle("font-decoration: italic;"); - Cell cell = new Cell(); - cell.setColspan(4); - cell.appendChild(f_Description); - row.appendChild(cell); - row.setStyle("background-color: transparent; padding: 10px"); - m_rows.appendChild(row); + layoutParameters(); // Finish m_query = new MQuery(); @@ -487,6 +389,154 @@ public final class WAccountDialog extends Window return true; } // initAccount + protected void layoutParameters() { + m_smallWidth = ClientInfo.maxWidth(ClientInfo.SMALL_WIDTH-1); + + m_rows = new Rows(); + m_rows.setParent(parameterLayout); + + // Alias + if (s_AcctSchema.isHasAlias()) + { + GridField alias = m_mTab.getField("Alias"); + if (f_Alias == null) + f_Alias = WebEditorFactory.getEditor(alias, false); + addLine(alias, f_Alias, false); + } // Alias + + // Combination + GridField combination = m_mTab.getField("Combination"); + if (f_Combination == null) + f_Combination = WebEditorFactory.getEditor(combination, false); + addLine(combination, f_Combination, false); + m_newRow = true; + + /** + * Create Fields in Element Order + */ + MAcctSchemaElement[] elements = s_AcctSchema.getAcctSchemaElements(); + for (int i = 0; i < elements.length; i++) + { + MAcctSchemaElement ase = elements[i]; + String type = ase.getElementType(); + boolean isMandatory = ase.isMandatory(); + // + if (type.equals(MAcctSchemaElement.ELEMENTTYPE_Organization)) + { + GridField field = m_mTab.getField("AD_Org_ID"); + if (f_AD_Org_ID == null) + f_AD_Org_ID = WebEditorFactory.getEditor(field, false); + addLine(field, f_AD_Org_ID, isMandatory); + } + else if (type.equals(MAcctSchemaElement.ELEMENTTYPE_Account)) + { + GridField field = m_mTab.getField("Account_ID"); + if (f_Account_ID == null) + { + f_Account_ID = WebEditorFactory.getEditor(field, false); + f_Account_ID.addValueChangeListener(this); + } + addLine(field, f_Account_ID, isMandatory); + } + else if (type.equals(MAcctSchemaElement.ELEMENTTYPE_SubAccount)) + { + GridField field = m_mTab.getField("C_SubAcct_ID"); + if (f_SubAcct_ID == null) + f_SubAcct_ID = WebEditorFactory.getEditor(field, false); + addLine(field, f_SubAcct_ID, isMandatory); + } + else if (type.equals(MAcctSchemaElement.ELEMENTTYPE_Product)) + { + GridField field = m_mTab.getField("M_Product_ID"); + if (f_M_Product_ID == null) + f_M_Product_ID = WebEditorFactory.getEditor(field, false); + addLine(field, f_M_Product_ID, isMandatory); + } + else if (type.equals(MAcctSchemaElement.ELEMENTTYPE_BPartner)) + { + GridField field = m_mTab.getField("C_BPartner_ID"); + if (f_C_BPartner_ID == null) + f_C_BPartner_ID = WebEditorFactory.getEditor(field, false); + addLine(field, f_C_BPartner_ID, isMandatory); + } + else if (type.equals(MAcctSchemaElement.ELEMENTTYPE_Campaign)) + { + GridField field = m_mTab.getField("C_Campaign_ID"); + if (f_C_Campaign_ID == null) + f_C_Campaign_ID = WebEditorFactory.getEditor(field, false); + addLine(field, f_C_Campaign_ID, isMandatory); + } + else if (type.equals(MAcctSchemaElement.ELEMENTTYPE_LocationFrom)) + { + GridField field = m_mTab.getField("C_LocFrom_ID"); + if (f_C_LocFrom_ID == null) + f_C_LocFrom_ID = WebEditorFactory.getEditor(field, false); + addLine(field, f_C_LocFrom_ID, isMandatory); + } + else if (type.equals(MAcctSchemaElement.ELEMENTTYPE_LocationTo)) + { + GridField field = m_mTab.getField("C_LocTo_ID"); + if (f_C_LocTo_ID == null) + f_C_LocTo_ID = WebEditorFactory.getEditor(field, false); + addLine(field, f_C_LocTo_ID, isMandatory); + } + else if (type.equals(MAcctSchemaElement.ELEMENTTYPE_Project)) + { + GridField field = m_mTab.getField("C_Project_ID"); + if (f_C_Project_ID == null) + f_C_Project_ID = WebEditorFactory.getEditor(field, false); + addLine(field, f_C_Project_ID, isMandatory); + } + else if (type.equals(MAcctSchemaElement.ELEMENTTYPE_SalesRegion)) + { + GridField field = m_mTab.getField("C_SalesRegion_ID"); + if (f_C_SalesRegion_ID == null) + f_C_SalesRegion_ID = WebEditorFactory.getEditor(field, false); + addLine(field, f_C_SalesRegion_ID, isMandatory); + } + else if (type.equals(MAcctSchemaElement.ELEMENTTYPE_OrgTrx)) + { + GridField field = m_mTab.getField("AD_OrgTrx_ID"); + if (f_AD_OrgTrx_ID == null) + f_AD_OrgTrx_ID = WebEditorFactory.getEditor(field, false); + addLine(field, f_AD_OrgTrx_ID, isMandatory); + } + else if (type.equals(MAcctSchemaElement.ELEMENTTYPE_Activity)) + { + GridField field = m_mTab.getField("C_Activity_ID"); + if (f_C_Activity_ID == null) + f_C_Activity_ID = WebEditorFactory.getEditor(field, false); + addLine(field, f_C_Activity_ID, isMandatory); + } + // User1 + else if (type.equals(MAcctSchemaElement.ELEMENTTYPE_UserElementList1)) + { + GridField field = m_mTab.getField("User1_ID"); + if (f_User1_ID == null) + f_User1_ID = WebEditorFactory.getEditor(field, false); + addLine(field, f_User1_ID, isMandatory); + } + else if (type.equals(MAcctSchemaElement.ELEMENTTYPE_UserElementList2)) + { + GridField field = m_mTab.getField("User2_ID"); + if (f_User2_ID == null) + f_User2_ID = WebEditorFactory.getEditor(field, false); + addLine(field, f_User2_ID, isMandatory); + } + } // Create Fields in Element Order + + // Add description + m_newRow = true; + Row row = new Row(); + f_Description.setStyle("font-decoration: italic;"); + Cell cell = new Cell(); + cell.setColspan(4); + cell.appendChild(f_Description); + row.appendChild(cell); + row.setStyle("background-color: transparent; padding: 10px"); + m_rows.appendChild(row); + } + /** * Add Editor to parameterPanel alernative right/left depending on m_newRow. * Field Value changes update Editors @@ -512,14 +562,27 @@ public final class WAccountDialog extends Window } // else // m_gbc.gridx = 2; - Div div = new Div(); - div.setStyle("text-align: right"); - div.appendChild(label); - m_row.appendChild(div); - - m_row.appendChild(editor.getComponent()); + if (ClientInfo.maxWidth(ClientInfo.SMALL_WIDTH-1)) + { + Vlayout vlayout = new Vlayout(); + vlayout.setHflex("1"); + vlayout.setSpacing("0px"); + vlayout.appendChild(label); + vlayout.appendChild(editor.getComponent()); + m_row.appendCellChild(vlayout, 2); + } + else + { + Div div = new Div(); + div.setStyle("text-align: right"); + div.appendChild(label); + m_row.appendChild(div); + + m_row.appendChild(editor.getComponent()); + } editor.fillHorizontal(); editor.dynamicDisplay(); + // m_newRow = !m_newRow; } // addLine @@ -1228,4 +1291,19 @@ public final class WAccountDialog extends Window } } } + + protected void onClientInfo() { + if (parameterLayout != null && parameterLayout.getRows() != null) { + boolean smallWidth = ClientInfo.maxWidth(ClientInfo.SMALL_WIDTH-1); + if (smallWidth != m_smallWidth) { + parameterLayout.getRows().detach(); + layoutParameters(); + if (ThemeManager.isUseCSSForWindowSize()) { + ZKUpdateUtil.setCSSHeight(this); + ZKUpdateUtil.setCSSWidth(this); + } + this.invalidate(); + } + } + } } // WAccountDialog diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WAssignmentDialog.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WAssignmentDialog.java index 11210b2e56..68c4392b36 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WAssignmentDialog.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WAssignmentDialog.java @@ -43,6 +43,7 @@ import org.adempiere.webui.component.Row; import org.adempiere.webui.component.Rows; import org.adempiere.webui.component.Textbox; import org.adempiere.webui.component.Window; +import org.adempiere.webui.theme.ThemeManager; import org.adempiere.webui.util.ZKUpdateUtil; import org.compiere.model.MResourceAssignment; import org.compiere.model.MRole; @@ -115,8 +116,11 @@ public class WAssignmentDialog extends Window implements EventListener log.log(Level.SEVERE, "", e); } setDisplay(); // from mAssignment - ZKUpdateUtil.setWidth(this, "600px"); + if (!ThemeManager.isUseCSSForWindowSize()) + ZKUpdateUtil.setWindowWidthX(this, 600); setSizable(true); + setMaximizable(true); + setSclass("assignment-dialog"); // } // VAssignmentDialog diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WChat.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WChat.java index e585648de1..b022081a6a 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WChat.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WChat.java @@ -23,6 +23,7 @@ import java.util.Map; import java.util.logging.Level; import org.adempiere.webui.AdempiereWebUI; +import org.adempiere.webui.ClientInfo; import org.adempiere.webui.LayoutUtils; import org.adempiere.webui.component.Button; import org.adempiere.webui.component.ConfirmPanel; @@ -30,6 +31,7 @@ import org.adempiere.webui.component.Label; import org.adempiere.webui.component.Textbox; import org.adempiere.webui.component.Window; import org.adempiere.webui.event.DialogEvents; +import org.adempiere.webui.theme.ThemeManager; import org.adempiere.webui.util.ZKUpdateUtil; import org.compiere.model.MChat; import org.compiere.model.MChatEntry; @@ -130,13 +132,15 @@ public class WChat extends Window implements EventListener, DialogEvents private Map entryMap = new HashMap(); private SimpleDateFormat m_format; + private String orientation; + /** * Static Init. * @throws Exception */ private void staticInit () throws Exception { - this.setSclass("popup-dialog"); + this.setSclass("popup-dialog chat-dialog"); this.setStyle("position: absolute"); this.setAttribute(AdempiereWebUI.WIDGET_INSTANCE_NAME, "chat"); this.appendChild(mainPanel); @@ -174,14 +178,45 @@ public class WChat extends Window implements EventListener, DialogEvents south.appendChild(confirmPanel); ZKUpdateUtil.setVflex(confirmPanel, "min"); - ZKUpdateUtil.setHeight(this, "88%"); - ZKUpdateUtil.setWidth(this, "500px"); + if (!ThemeManager.isUseCSSForWindowSize()) + { + ZKUpdateUtil.setHeight(this, "88%"); + ZKUpdateUtil.setWindowWidthX(this, 500); + } + else + { + addCallback(AFTER_PAGE_ATTACHED, t -> { + ZKUpdateUtil.setCSSHeight(this); + ZKUpdateUtil.setCSSWidth(this); + }); + } this.setMaximizable(true); this.setSizable(true); this.setBorder("normal"); this.setClosable(true); - } // staticInit - + + if (ClientInfo.isMobile()) + { + orientation = ClientInfo.get().orientation; + ClientInfo.onClientInfo(this, this::onClientInfo); + } + } + + protected void onClientInfo() + { + if (getPage() != null) + { + String newOrienation = ClientInfo.get().orientation; + if (!newOrienation.equals(orientation)) + { + orientation = newOrienation; + ZKUpdateUtil.setCSSHeight(this); + ZKUpdateUtil.setCSSWidth(this); + invalidate(); + } + } + } + /** * Load Chat */ @@ -359,5 +394,4 @@ public class WChat extends Window implements EventListener, DialogEvents public void onEvent(Event event) throws Exception { actionPerformed(event); } - -} // AChat +} // WChat diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WEMailDialog.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WEMailDialog.java index d765f3196a..276d742547 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WEMailDialog.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WEMailDialog.java @@ -33,6 +33,7 @@ import java.util.regex.Pattern; import javax.activation.DataSource; import org.adempiere.webui.AdempiereWebUI; +import org.adempiere.webui.ClientInfo; import org.adempiere.webui.component.AttachmentItem; import org.adempiere.webui.component.Button; import org.adempiere.webui.component.Checkbox; @@ -115,17 +116,23 @@ public class WEMailDialog extends Window implements EventListener, ValueC { super(); this.setTitle(title); - this.setSclass("popup-dialog"); + this.setSclass("popup-dialog email-dialog"); this.setClosable(true); this.setBorder("normal"); - ZKUpdateUtil.setWidth(this, "80%"); - ZKUpdateUtil.setHeight(this, "80%"); + if (!ThemeManager.isUseCSSForWindowSize()) + { + ZKUpdateUtil.setWidth(this, "80%"); + ZKUpdateUtil.setHeight(this, "80%"); + } this.setShadow(true); this.setMaximizable(true); this.setSizable(true); fMessage = new CKeditor(); - fMessage.setCustomConfigurationsPath("/js/ckeditor/config.js"); + if (ClientInfo.isMobile()) + fMessage.setCustomConfigurationsPath("/js/ckeditor/config-min.js"); + else + fMessage.setCustomConfigurationsPath("/js/ckeditor/config.js"); fMessage.setToolbar("MyToolbar"); Map lang = new HashMap(); lang.put("language", Language.getLoginLanguage().getAD_Language()); @@ -219,6 +226,11 @@ public class WEMailDialog extends Window implements EventListener, ValueC if (MUser.get(Env.getCtx()).isAddMailTextAutomatically()) { addMailText(); } + if (newpage != null && ThemeManager.isUseCSSForWindowSize()) { + ZKUpdateUtil.setCSSHeight(this); + ZKUpdateUtil.setCSSWidth(this); + this.invalidate(); + } } /** @@ -835,5 +847,4 @@ public class WEMailDialog extends Window implements EventListener, ValueC } } - } // WEMailDialog \ No newline at end of file diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WFieldRecordInfo.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WFieldRecordInfo.java index 0df30b63e3..f138924091 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WFieldRecordInfo.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WFieldRecordInfo.java @@ -79,8 +79,18 @@ public class WFieldRecordInfo extends Window implements EventListener super (); this.setTitle(title); this.setAttribute(Window.MODE_KEY, Window.MODE_HIGHLIGHTED); - ZKUpdateUtil.setWidth(this, "640px"); - ZKUpdateUtil.setHeight(this, "480px"); + if (!ThemeManager.isUseCSSForWindowSize()) + { + ZKUpdateUtil.setWindowWidthX(this, 640); + ZKUpdateUtil.setWindowHeightX(this, 480); + } + else + { + addCallback(AFTER_PAGE_ATTACHED, t-> { + ZKUpdateUtil.setCSSHeight(this); + ZKUpdateUtil.setCSSWidth(this); + }); + } this.setBorder("normal"); this.setSizable(true); this.setClosable(true); @@ -153,6 +163,7 @@ public class WFieldRecordInfo extends Window implements EventListener south.appendChild(confirmPanel); confirmPanel.addActionListener(Events.ON_CLICK, this); + setSclass("field-record-info-dialog"); } // init @@ -378,5 +389,4 @@ public class WFieldRecordInfo extends Window implements EventListener popupMenu.appendChild(changeLogItem); } - } // WFieldRecordInfo diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WFieldSuggestion.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WFieldSuggestion.java index 3ebad48a86..23117078ed 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WFieldSuggestion.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WFieldSuggestion.java @@ -11,6 +11,7 @@ import org.adempiere.webui.component.GridFactory; import org.adempiere.webui.component.Row; import org.adempiere.webui.component.Rows; import org.adempiere.webui.component.Window; +import org.adempiere.webui.util.ZKUpdateUtil; import org.compiere.model.MField; import org.compiere.model.MFieldSuggestion; import org.compiere.util.Env; @@ -119,11 +120,12 @@ public class WFieldSuggestion extends Window implements EventListener { this.setSclass("popup-dialog"); this.setClosable(true); this.setBorder("normal"); - this.setWidth("550px"); - this.setHeight("350px"); + ZKUpdateUtil.setWindowWidthX(this, 550); + ZKUpdateUtil.setWindowHeightX(this, 350); this.setShadow(true); this.setAttribute(Window.MODE_KEY, Window.MODE_HIGHLIGHTED); this.setSizable(true); + this.setMaximizable(true); } @Override diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WImageDialog.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WImageDialog.java index 86b6cd991c..724724834c 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WImageDialog.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WImageDialog.java @@ -20,6 +20,7 @@ import java.io.InputStream; import java.util.logging.Level; import org.adempiere.webui.AdempiereWebUI; +import org.adempiere.webui.ClientInfo; import org.adempiere.webui.LayoutUtils; import org.adempiere.webui.apps.AEnv; import org.adempiere.webui.component.Button; @@ -27,6 +28,7 @@ import org.adempiere.webui.component.ConfirmPanel; import org.adempiere.webui.component.Panel; import org.adempiere.webui.component.Textbox; import org.adempiere.webui.component.Window; +import org.adempiere.webui.theme.ThemeManager; import org.adempiere.webui.util.ZKUpdateUtil; import org.apache.commons.codec.binary.Base64; import org.compiere.model.MImage; @@ -130,10 +132,20 @@ public class WImageDialog extends Window implements EventListener */ void init() throws Exception { - this.setSclass("popup-dialog"); + this.setSclass("popup-dialog image-dialog"); this.setBorder("normal"); - ZKUpdateUtil.setWidth(this, "640px"); - ZKUpdateUtil.setHeight(this, "540px"); + if (!ThemeManager.isUseCSSForWindowSize()) + { + ZKUpdateUtil.setWindowWidthX(this, 640); + ZKUpdateUtil.setWindowHeightX(this, 540); + } + else + { + addCallback(AFTER_PAGE_ATTACHED, t-> { + ZKUpdateUtil.setCSSHeight(this); + ZKUpdateUtil.setCSSWidth(this); + }); + } this.setShadow(true); this.setAttribute(Window.MODE_KEY, Window.MODE_HIGHLIGHTED); this.setSizable(true); @@ -142,8 +154,14 @@ public class WImageDialog extends Window implements EventListener captureDiv = new Div(); this.appendChild(captureDiv); captureDiv.setStyle("position: absolute;"); - ZKUpdateUtil.setHeight(captureDiv, "480px"); - ZKUpdateUtil.setWidth(captureDiv, "640px"); + if (ClientInfo.maxHeight(539)) + ZKUpdateUtil.setHeight(captureDiv, (ClientInfo.get().desktopHeight-60)+ "px"); + else + ZKUpdateUtil.setHeight(captureDiv, "480px"); + if (ClientInfo.maxWidth(639)) + ZKUpdateUtil.setWidth(captureDiv, ClientInfo.get().desktopWidth + "px"); + else + ZKUpdateUtil.setWidth(captureDiv, "640px"); captureDiv.setVisible(false); captureDiv.addEventListener("onCaptureImage", this); cancelCaptureButton = new Button(Util.cleanAmp(Msg.getMsg(Env.getCtx(), "Cancel"))); @@ -364,5 +382,5 @@ public class WImageDialog extends Window implements EventListener */ public void setDefaultNameForCaptureImage(String defaultNameForCaptureImage) { this.defaultNameForCaptureImage = defaultNameForCaptureImage; - } + } } // WImageDialog diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WLocationDialog.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WLocationDialog.java index 728344debc..1aa37c7f8b 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WLocationDialog.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WLocationDialog.java @@ -28,6 +28,7 @@ import java.util.StringTokenizer; import java.util.logging.Level; import org.adempiere.util.Callback; +import org.adempiere.webui.ClientInfo; import org.adempiere.webui.LayoutUtils; import org.adempiere.webui.component.Button; import org.adempiere.webui.component.Checkbox; @@ -44,6 +45,7 @@ import org.adempiere.webui.component.Row; import org.adempiere.webui.component.Rows; import org.adempiere.webui.component.Textbox; import org.adempiere.webui.component.Window; +import org.adempiere.webui.theme.ThemeManager; import org.adempiere.webui.util.ZKUpdateUtil; import org.compiere.model.GridField; import org.compiere.model.MAddressValidation; @@ -204,10 +206,20 @@ public class WLocationDialog extends Window implements EventListener setRegion(); initLocation(); - // - ZKUpdateUtil.setWidth(this, "380px"); - ZKUpdateUtil.setHeight(this, "420px"); // required fixed height for ZK to auto adjust the position based on available space - this.setSclass("popup-dialog"); + // + if (!ThemeManager.isUseCSSForWindowSize()) + { + ZKUpdateUtil.setWindowWidthX(this, 380); + ZKUpdateUtil.setWindowHeightX(this, 420); // required fixed height for ZK to auto adjust the position based on available space + } + else + { + addCallback(AFTER_PAGE_ATTACHED, t -> { + ZKUpdateUtil.setCSSHeight(this); + ZKUpdateUtil.setCSSWidth(this); + }); + } + this.setSclass("popup-dialog location-dialog"); this.setClosable(true); this.setBorder("normal"); this.setShadow(true); @@ -316,6 +328,14 @@ public class WLocationDialog extends Window implements EventListener lstAddressValidation.setRows(0); mainPanel = GridFactory.newGridLayout(); + + if (ClientInfo.isMobile()) + { + if (ClientInfo.maxWidth(ClientInfo.EXTRA_SMALL_WIDTH) || ClientInfo.maxHeight(ClientInfo.SMALL_HEIGHT)) + { + confirmPanel.addButtonSclass("btn-medium small-image-btn"); + } + } } private void init() diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WLocatorDialog.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WLocatorDialog.java index 97068d39ef..dfb732b49f 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WLocatorDialog.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WLocatorDialog.java @@ -26,6 +26,7 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.util.logging.Level; +import org.adempiere.webui.ClientInfo; import org.adempiere.webui.LayoutUtils; import org.adempiere.webui.component.Checkbox; import org.adempiere.webui.component.Column; @@ -40,6 +41,7 @@ import org.adempiere.webui.component.Row; import org.adempiere.webui.component.Rows; import org.adempiere.webui.component.Textbox; import org.adempiere.webui.component.Window; +import org.adempiere.webui.theme.ThemeManager; import org.adempiere.webui.util.ZKUpdateUtil; import org.compiere.model.MLocator; import org.compiere.model.MLocatorLookup; @@ -273,14 +275,32 @@ public class WLocatorDialog extends Window implements EventListener southPane.appendChild(confirmPanel); this.setTitle(title); - this.setSclass("popup-dialog"); + this.setSclass("popup-dialog locator-dialog"); this.setClosable(true); this.setBorder("normal"); - ZKUpdateUtil.setWidth(this, "260px"); - ZKUpdateUtil.setHeight(this, "350px"); // required fixed height for ZK to auto adjust the position based on available space + if (!ThemeManager.isUseCSSForWindowSize()) + { + ZKUpdateUtil.setWindowWidthX(this, 260); + ZKUpdateUtil.setWindowHeightX(this, 350); // required fixed height for ZK to auto adjust the position based on available space + } + else + { + addCallback(AFTER_PAGE_ATTACHED, t -> { + ZKUpdateUtil.setCSSHeight(this); + ZKUpdateUtil.setCSSWidth(this); + }); + } this.setShadow(true); this.setAttribute(Window.MODE_KEY, Window.MODE_HIGHLIGHTED); this.setSizable(true); // Elaine 2009/02/02 - window set to resizable + + if (ClientInfo.isMobile()) + { + ClientInfo.onClientInfo(this, () -> { + ZKUpdateUtil.setCSSHeight(this); + ZKUpdateUtil.setCSSWidth(this); + }); + } } private void initLocator() diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WMediaDialog.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WMediaDialog.java index 85c97b0379..534f80532d 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WMediaDialog.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WMediaDialog.java @@ -105,7 +105,7 @@ public class WMediaDialog extends Window implements EventListener { log.log(Level.SEVERE, "", ex); } - } // WAttachment + } // WMediaDialog /** * Static setup. @@ -125,9 +125,19 @@ public class WMediaDialog extends Window implements EventListener void staticInit() throws Exception { - ZKUpdateUtil.setWidth(this, "500px"); - ZKUpdateUtil.setHeight(this, "500px"); + if (!ThemeManager.isUseCSSForWindowSize()) + { + ZKUpdateUtil.setWindowWidthX(this, 500); + ZKUpdateUtil.setWindowHeightX(this, 500); + } + else + { + addCallback("afterPageAttached", t -> afterPageAttached()); + } + this.setSclass("media-dialog"); this.setClosable(true); + this.setSizable(true); + this.setMaximizable(true); this.setBorder("normal"); this.appendChild(mainPanel); ZKUpdateUtil.setHeight(mainPanel, "100%"); @@ -184,9 +194,16 @@ public class WMediaDialog extends Window implements EventListener bCancel.addEventListener(Events.ON_CLICK, this); confirmPanel.appendChild(bOk); - confirmPanel.appendChild(bCancel); + confirmPanel.appendChild(bCancel); + confirmPanel.setStyle("float: right;"); } + private void afterPageAttached() { + ZKUpdateUtil.setCSSHeight(this); + ZKUpdateUtil.setCSSWidth(this); + + } + /** * Dispose */ @@ -352,4 +369,5 @@ public class WMediaDialog extends Window implements EventListener return m_data; } + } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WPAttributeDialog.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WPAttributeDialog.java index c0469b05bf..41c5fa89e8 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WPAttributeDialog.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WPAttributeDialog.java @@ -108,9 +108,9 @@ public class WPAttributeDialog extends Window implements EventListener { super (); this.setTitle(Msg.translate(Env.getCtx(), "M_AttributeSetInstance_ID")); - ZKUpdateUtil.setWidth(this, "500px"); - this.setSclass("popup-dialog"); -// ZKUpdateUtil.setHeight(this, "600px"); + if (!ThemeManager.isUseCSSForWindowSize()) + ZKUpdateUtil.setWindowWidthX(this, 500); + this.setSclass("popup-dialog pattribute-dialog"); this.setBorder("normal"); this.setShadow(true); this.setSizable(true); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WPAttributeInstance.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WPAttributeInstance.java index 49d2a0a928..7c80e93269 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WPAttributeInstance.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WPAttributeInstance.java @@ -27,6 +27,7 @@ import org.adempiere.webui.component.ConfirmPanel; import org.adempiere.webui.component.Panel; import org.adempiere.webui.component.WListbox; import org.adempiere.webui.component.Window; +import org.adempiere.webui.theme.ThemeManager; import org.adempiere.webui.util.ZKUpdateUtil; import org.compiere.minigrid.ColumnInfo; import org.compiere.minigrid.IDColumn; @@ -74,8 +75,19 @@ public class WPAttributeInstance extends Window implements EventListener this.setBorder("normal"); this.setSizable(true); this.setMaximizable(true); - ZKUpdateUtil.setWidth(this, "1000px"); - ZKUpdateUtil.setHeight(this, "550px"); + if (!ThemeManager.isUseCSSForWindowSize()) + { + ZKUpdateUtil.setWindowWidthX(this, 1000); + ZKUpdateUtil.setWindowHeightX(this, 550); + } + else + { + addCallback(AFTER_PAGE_ATTACHED, t-> { + ZKUpdateUtil.setCSSHeight(this); + ZKUpdateUtil.setCSSWidth(this); + }); + } + this.setSclass("pattribute-instance-dialog"); init (M_Warehouse_ID, M_Locator_ID, M_Product_ID, C_BPartner_ID); AEnv.showCenterScreen(this); @@ -385,6 +397,4 @@ public class WPAttributeInstance extends Window implements EventListener return m_M_Locator_ID; } // getM_Locator_ID - - } // PAttributeInstance \ No newline at end of file diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WPostIt.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WPostIt.java index 49521b5bae..99aafc3655 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WPostIt.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WPostIt.java @@ -12,6 +12,10 @@ *****************************************************************************/ package org.adempiere.webui.window; +import java.util.HashMap; +import java.util.Map; + +import org.adempiere.webui.ClientInfo; import org.adempiere.webui.component.ConfirmPanel; import org.adempiere.webui.component.Label; import org.adempiere.webui.component.Tab; @@ -24,6 +28,7 @@ import org.adempiere.webui.component.VerticalBox; import org.adempiere.webui.component.Window; import org.compiere.model.MPostIt; import org.compiere.util.Env; +import org.compiere.util.Language; import org.zkforge.ckez.CKeditor; import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.EventListener; @@ -83,11 +88,13 @@ public class WPostIt extends Window implements EventListener{ private void init() { setBorder("normal"); + setMaximizable(true); VerticalBox vbox = new VerticalBox(); appendChild(vbox); tabbox = new Tabbox(); + tabbox.setMaximalHeight(true); vbox.appendChild(tabbox); Tabs tabs = new Tabs(); tabbox.appendChild(tabs); @@ -103,8 +110,14 @@ public class WPostIt extends Window implements EventListener{ textBox.setCols(80); textBox.setRows(30); textBox.setEnabled(editable); - textBox.setWidth("700px"); - textBox.setHeight("500px"); + if (ClientInfo.minWidth(730)) + textBox.setWidth("700px"); + else + textBox.setWidth(ClientInfo.get().desktopWidth-30 + "px"); + if (ClientInfo.minHeight(700)) + textBox.setHeight("500px"); + else + textBox.setHeight(ClientInfo.get().desktopHeight-190 +"px"); tabPanel.appendChild(textBox); tab = new Tab("HTML"); @@ -115,9 +128,20 @@ public class WPostIt extends Window implements EventListener{ editor = new CKeditor(); tabPanel.appendChild(editor); - editor.setWidth("700px"); - editor.setHeight("500px"); + if (ClientInfo.minWidth(730)) + editor.setWidth("700px"); + else + editor.setWidth(ClientInfo.get().desktopWidth-30 + "px"); + editor.setVflex("1"); editor.setValue(note); + if (ClientInfo.isMobile()) + editor.setCustomConfigurationsPath("/js/ckeditor/config-min.js"); + else + editor.setCustomConfigurationsPath("/js/ckeditor/config.js"); + editor.setToolbar("MyToolbar"); + Map lang = new HashMap(); + lang.put("language", Language.getLoginLanguage().getAD_Language()); + editor.setConfig(lang); vbox.appendChild(new Separator()); createdBox = new Label(); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WPreference.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WPreference.java index 4e40742fcb..94ab9b2a06 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WPreference.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WPreference.java @@ -15,6 +15,7 @@ package org.adempiere.webui.window; import java.util.logging.Level; +import org.adempiere.webui.ClientInfo; import org.adempiere.webui.apps.AEnv; import org.adempiere.webui.component.ToolBar; import org.adempiere.webui.component.ToolBarButton; @@ -157,8 +158,16 @@ public class WPreference extends WQuickEntry implements EventListener { gadgets = new WGadgets(); gadgets.setClosable(true); gadgets.setSizable(true); - ZKUpdateUtil.setWidth(gadgets, "40%"); - ZKUpdateUtil.setHeight(gadgets, "60%"); + if (ClientInfo.maxWidth(ClientInfo.SMALL_WIDTH-1)) + ZKUpdateUtil.setWidth(gadgets, "90%"); + else if (ClientInfo.maxWidth(ClientInfo.MEDIUM_WIDTH-1)) + ZKUpdateUtil.setWidth(gadgets, "70%"); + else + ZKUpdateUtil.setWidth(gadgets, "50%"); + if (ClientInfo.maxHeight(ClientInfo.MEDIUM_HEIGHT-1)) + ZKUpdateUtil.setHeight(gadgets, "80%"); + else + ZKUpdateUtil.setHeight(gadgets, "60%"); gadgets.setTitle( Msg.translate(Env.getCtx(), "DashboardGadgets")); gadgets.setAttribute(Window.MODE_KEY, Mode.HIGHLIGHTED); AEnv.showWindow(gadgets); diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WRecordInfo.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WRecordInfo.java index 908286fc19..e9f4f96459 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WRecordInfo.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WRecordInfo.java @@ -32,6 +32,7 @@ import org.adempiere.webui.component.ConfirmPanel; import org.adempiere.webui.component.Listbox; import org.adempiere.webui.component.SimpleListModel; import org.adempiere.webui.component.Window; +import org.adempiere.webui.theme.ThemeManager; import org.adempiere.webui.util.ZKUpdateUtil; import org.compiere.model.DataStatusEvent; import org.compiere.model.GridTab; @@ -93,13 +94,24 @@ public class WRecordInfo extends Window implements EventListener { super (); this.setTitle(title); - ZKUpdateUtil.setWidth(this, "500px"); - ZKUpdateUtil.setHeight(this, "400px"); + if (!ThemeManager.isUseCSSForWindowSize()) + { + ZKUpdateUtil.setWindowWidthX(this, 500); + ZKUpdateUtil.setWindowHeightX(this, 400); + } + else + { + addCallback(AFTER_PAGE_ATTACHED, t-> { + ZKUpdateUtil.setCSSHeight(this); + ZKUpdateUtil.setCSSWidth(this); + }); + } this.setBorder("normal"); this.setSizable(true); this.setClosable(true); + this.setMaximizable(true); this.setWidgetAttribute(AdempiereWebUI.WIDGET_INSTANCE_NAME, "recordInfo"); - this.setSclass("popup-dialog"); + this.setSclass("popup-dialog record-info-dialog"); try { diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WTextEditorDialog.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WTextEditorDialog.java index 48176958a4..f8f4e7ef7c 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WTextEditorDialog.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WTextEditorDialog.java @@ -15,6 +15,7 @@ package org.adempiere.webui.window; import java.util.HashMap; import java.util.Map; +import org.adempiere.webui.ClientInfo; import org.adempiere.webui.component.ConfirmPanel; import org.adempiere.webui.component.Label; import org.adempiere.webui.component.Tab; @@ -24,6 +25,7 @@ import org.adempiere.webui.component.Tabpanels; import org.adempiere.webui.component.Tabs; import org.adempiere.webui.component.Textbox; import org.adempiere.webui.component.Window; +import org.adempiere.webui.theme.ThemeManager; import org.adempiere.webui.util.ZKUpdateUtil; import org.compiere.util.Language; import org.zkforge.ckez.CKeditor; @@ -84,11 +86,13 @@ public class WTextEditorDialog extends Window implements EventListener{ private void init() { setBorder("normal"); - ZKUpdateUtil.setHeight(this, "450px"); - ZKUpdateUtil.setWidth(this, "800px"); + if (ThemeManager.isUseCSSForWindowSize()) { + ZKUpdateUtil.setWindowHeightX(this, 450); + ZKUpdateUtil.setWindowWidthX(this, 800); + } setStyle("position: absolute;"); setSizable(false); - setSclass("popup-dialog"); + setSclass("popup-dialog text-editor-dialog"); Vlayout vbox = new Vlayout(); appendChild(vbox); @@ -165,9 +169,12 @@ public class WTextEditorDialog extends Window implements EventListener{ setMaximizable(true); } - private void createEditor(org.zkoss.zul.Tabpanel tabPanel) { + private void createEditor(org.zkoss.zul.Tabpanel tabPanel) { editor = new CKeditor(); - editor.setCustomConfigurationsPath("/js/ckeditor/config.js"); + if (ClientInfo.isMobile()) + editor.setCustomConfigurationsPath("/js/ckeditor/config-min.js"); + else + editor.setCustomConfigurationsPath("/js/ckeditor/config.js"); editor.setToolbar("MyToolbar"); Map lang = new HashMap(); lang.put("language", Language.getLoginLanguage().getAD_Language()); @@ -221,7 +228,7 @@ public class WTextEditorDialog extends Window implements EventListener{ } else if (event.getTarget() == editor) { updateStatus(editor.getValue().length()); } - } + } } private void updateStatus(int newLength) { diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkJRViewer.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkJRViewer.java index e7f6876717..f95bbdd4c9 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkJRViewer.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkJRViewer.java @@ -9,6 +9,7 @@ import java.util.logging.Level; import javax.activation.FileDataSource; import org.adempiere.exceptions.AdempiereException; +import org.adempiere.webui.ClientInfo; import org.adempiere.webui.LayoutUtils; import org.adempiere.webui.apps.AEnv; import org.adempiere.webui.component.Listbox; @@ -29,12 +30,14 @@ import org.compiere.util.Env; import org.compiere.util.Msg; import org.compiere.util.Util; import org.zkoss.util.media.AMedia; +import org.zkoss.util.media.Media; import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.Page; import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.event.Events; import org.zkoss.zk.ui.event.KeyEvent; +import org.zkoss.zk.ui.ext.render.DynamicMedia; import org.zkoss.zul.Borderlayout; import org.zkoss.zul.Center; import org.zkoss.zul.Iframe; @@ -43,6 +46,8 @@ import org.zkoss.zul.North; import org.zkoss.zul.Separator; import org.zkoss.zul.Tab; import org.zkoss.zul.Toolbar; +import org.zkoss.zul.impl.Utils; +import org.zkoss.zul.impl.XulElement; import net.sf.jasperreports.engine.DefaultJasperReportsContext; import net.sf.jasperreports.engine.JRException; @@ -85,7 +90,9 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl private KeyEvent prevKeyEvent; private String m_title; // local title - embedded windows clear the title - + + private int mediaVersion = 0; + public ZkJRViewer(JasperPrint jasperPrint, String title) { super(); this.setTitle(title); @@ -458,6 +465,19 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl } public void onRenderReport() { + if (ClientInfo.isMobile()) { + Listitem selected = previewType.getSelectedItem(); + String reportType=selected.getValue(); + if ( "PDF".equals( reportType ) ) { + mediaVersion++; + String url = Utils.getDynamicMediaURI(this, mediaVersion, media.getName(), media.getFormat()); + String pdfJsUrl = "pdf.js/web/viewer.html?file="+url; + iframe.setContent(null); + iframe.setSrc(pdfJsUrl); + return; + } + } + iframe.setSrc(null); iframe.setContent(media); } @@ -487,5 +507,20 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl m_WindowNo = -1; } } + + //-- ComponentCtrl --// + public Object getExtraCtrl() { + return new ExtraCtrl(); + } + /** A utility class to implement {@link #getExtraCtrl}. + * It is used only by component developers. + */ + protected class ExtraCtrl extends XulElement.ExtraCtrl + implements DynamicMedia { + //-- DynamicMedia --// + public Media getMedia(String pathInfo) { + return media; + } + } } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkReportViewer.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkReportViewer.java index d1a6f03d74..bc181177e8 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkReportViewer.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkReportViewer.java @@ -33,6 +33,7 @@ import javax.servlet.http.HttpServletRequest; import org.adempiere.exceptions.DBException; import org.adempiere.pdf.Document; import org.adempiere.util.ContextRunnable; +import org.adempiere.webui.ClientInfo; import org.adempiere.webui.LayoutUtils; import org.adempiere.webui.apps.AEnv; import org.adempiere.webui.apps.BusyDialog; @@ -105,16 +106,19 @@ import org.zkoss.zul.Center; import org.zkoss.zul.Div; import org.zkoss.zul.Filedownload; import org.zkoss.zul.Hbox; +import org.zkoss.zul.Hlayout; import org.zkoss.zul.Iframe; import org.zkoss.zul.Listitem; import org.zkoss.zul.Menuitem; import org.zkoss.zul.North; +import org.zkoss.zul.Popup; import org.zkoss.zul.Separator; import org.zkoss.zul.South; import org.zkoss.zul.Tab; import org.zkoss.zul.Toolbar; import org.zkoss.zul.Toolbarbutton; import org.zkoss.zul.Vbox; +import org.zkoss.zul.Vlayout; import org.zkoss.zul.impl.Utils; import org.zkoss.zul.impl.XulElement; @@ -201,6 +205,8 @@ public class ZkReportViewer extends Window implements EventListener, ITab private final static String ON_RENDER_REPORT_EVENT = "onRenderReport"; + private Popup toolbarPopup; + //private static final String REPORT = "org.idempiere.ui.report"; /** @@ -264,6 +270,7 @@ public class ZkReportViewer extends Window implements EventListener, ITab this.setStyle("width: 100%; height: 100%; position: absolute; border:none; padding:none; margin:none;"); ZKUpdateUtil.setHeight(toolBar, "32px"); + ZKUpdateUtil.setWidth(toolBar, "100%"); previewType.setMold("select"); @@ -277,6 +284,7 @@ public class ZkReportViewer extends Window implements EventListener, ITab toolBar.appendChild(previewType); previewType.addEventListener(Events.ON_SELECT, this); + toolBar.appendChild(new Separator("vertical")); int pTypeIndex = 0; @@ -307,27 +315,61 @@ public class ZkReportViewer extends Window implements EventListener, ITab previewType.setSelectedIndex(pTypeIndex); - labelDrill.setValue(Msg.getMsg(Env.getCtx(), "Drill") + ": "); - toolBar.appendChild(labelDrill); + Vlayout toolbarPopupLayout = null; + if (ClientInfo.maxWidth(ClientInfo.SMALL_WIDTH-1)) + { + toolbarPopup = new Popup(); + appendChild(toolbarPopup); + toolbarPopupLayout = new Vlayout(); + toolbarPopup.appendChild(toolbarPopupLayout); + } + labelDrill.setValue(Msg.getMsg(Env.getCtx(), "Drill") + ": "); comboDrill.setMold("select"); comboDrill.setTooltiptext(Msg.getMsg(Env.getCtx(), "Drill")); - toolBar.appendChild(comboDrill); + if (toolbarPopup != null) + { + Hlayout hl = new Hlayout(); + hl.setValign("middle"); + hl.appendChild(labelDrill); + hl.appendChild(comboDrill); + toolbarPopupLayout.appendChild(hl); + } + else + { + toolBar.appendChild(labelDrill); + toolBar.appendChild(comboDrill); + } - toolBar.appendChild(new Separator("vertical")); + if (toolbarPopup == null) + toolBar.appendChild(new Separator("vertical")); comboReport.setMold("select"); comboReport.setTooltiptext(Msg.translate(Env.getCtx(), "AD_PrintFormat_ID")); - toolBar.appendChild(comboReport); - toolBar.appendChild(new Separator("vertical")); + if (toolbarPopup != null) + { + toolbarPopupLayout.appendChild(comboReport); + } + else + { + toolBar.appendChild(comboReport); + toolBar.appendChild(new Separator("vertical")); + } MClient client = MClient.get(m_ctx); if (client.isMultiLingualDocument()){ try { wLanguage = AEnv.getListDocumentLanguage(client); wLanguage.getComponent().setTooltiptext(Msg.translate(Env.getCtx(), "AD_PrintFormat_ID")); - toolBar.appendChild(wLanguage.getComponent()); + if (toolbarPopup != null) + { + toolbarPopupLayout.appendChild(wLanguage.getComponent()); + } + else + { + toolBar.appendChild(wLanguage.getComponent()); + } wLanguage.setValue(m_reportEngine.getLanguageID()); wLanguage.getComponent().addEventListener(Events.ON_SELECT, this); } catch (Exception e) { @@ -335,42 +377,76 @@ public class ZkReportViewer extends Window implements EventListener, ITab } } - toolBar.appendChild(new Separator("vertical")); + if (toolbarPopup == null && client.isMultiLingualDocument()) + toolBar.appendChild(new Separator("vertical")); - summary.setText(Msg.getMsg(Env.getCtx(), "Summary")); - toolBar.appendChild(summary); + summary.setText(Msg.getMsg(Env.getCtx(), "Summary")); summary.setChecked(m_reportEngine.isSummary()); - toolBar.appendChild(new Separator("vertical")); + if (toolbarPopup != null) + { + toolbarPopupLayout.appendChild(summary); + } + else + { + toolBar.appendChild(summary); + toolBar.appendChild(new Separator("vertical")); + } bCustomize.setName("Customize"); bCustomize.setImage(ThemeManager.getThemeResource("images/Preference24.png")); bCustomize.setTooltiptext(Util.cleanAmp(Msg.getMsg(Env.getCtx(), "PrintCustomize"))); - toolBar.appendChild(bCustomize); + if (toolbarPopup != null) + { + toolbarPopupLayout.appendChild(bCustomize); + bCustomize.setLabel(bCustomize.getTooltiptext()); + } + else + toolBar.appendChild(bCustomize); bCustomize.addEventListener(Events.ON_CLICK, this); bFind.setName("Find"); bFind.setImage(ThemeManager.getThemeResource("images/Find24.png")); - bFind.setTooltiptext(Util.cleanAmp(Msg.getMsg(Env.getCtx(), "Find"))); - toolBar.appendChild(bFind); + bFind.setTooltiptext(Util.cleanAmp(Msg.getMsg(Env.getCtx(), "Find"))); bFind.addEventListener(Events.ON_CLICK, this); if (getAD_Tab_ID(m_reportEngine.getPrintFormat().getAD_Table_ID()) <= 0) { bFind.setVisible(false); // IDEMPIERE-1185 } - toolBar.appendChild(new Separator("vertical")); + if (toolbarPopup != null) + { + toolbarPopupLayout.appendChild(bFind); + bFind.setLabel(bFind.getTooltiptext()); + } + else + { + toolBar.appendChild(bFind); + toolBar.appendChild(new Separator("vertical")); + } bSendMail.setName("SendMail"); bSendMail.setImage(ThemeManager.getThemeResource("images/SendMail24.png")); bSendMail.setTooltiptext(Util.cleanAmp(Msg.getMsg(Env.getCtx(), "SendMail"))); - toolBar.appendChild(bSendMail); + if (toolbarPopup != null) + { + toolbarPopupLayout.appendChild(bSendMail); + bSendMail.setLabel(bSendMail.getTooltiptext()); + } + else + toolBar.appendChild(bSendMail); bSendMail.addEventListener(Events.ON_CLICK, this); bArchive.setName("Archive"); bArchive.setImage(ThemeManager.getThemeResource("images/Archive24.png")); bArchive.setTooltiptext(Util.cleanAmp(Msg.getMsg(Env.getCtx(), "Archive"))); - toolBar.appendChild(bArchive); + if (toolbarPopup != null) + { + toolbarPopupLayout.appendChild(bArchive); + bArchive.setLabel(bArchive.getTooltiptext()); + } + else + toolBar.appendChild(bArchive); bArchive.addEventListener(Events.ON_CLICK, this); if ( m_isCanExport ) @@ -378,23 +454,53 @@ public class ZkReportViewer extends Window implements EventListener, ITab bExport.setName("Export"); bExport.setImage(ThemeManager.getThemeResource("images/Export24.png")); bExport.setTooltiptext(Util.cleanAmp(Msg.getMsg(Env.getCtx(), "Export"))); - toolBar.appendChild(bExport); + if (toolbarPopup != null) + { + toolbarPopupLayout.appendChild(bExport); + bExport.setLabel(bExport.getTooltiptext()); + } + else + toolBar.appendChild(bExport); bExport.addEventListener(Events.ON_CLICK, this); } - toolBar.appendChild(new Separator("vertical")); + if (toolbarPopup == null) + toolBar.appendChild(new Separator("vertical")); bRefresh.setName("Refresh"); bRefresh.setImage(ThemeManager.getThemeResource("images/Refresh24.png")); bRefresh.setTooltiptext(Util.cleanAmp(Msg.getMsg(Env.getCtx(), "Refresh"))); - toolBar.appendChild(bRefresh); + if (toolbarPopup != null) + { + toolbarPopupLayout.appendChild(bRefresh); + bRefresh.setLabel(bRefresh.getTooltiptext()); + } + else + toolBar.appendChild(bRefresh); bRefresh.addEventListener(Events.ON_CLICK, this); bWizard.setImage(ThemeManager.getThemeResource("images/Wizard24.png")); bWizard.setTooltiptext(Util.cleanAmp(Msg.getMsg(Env.getCtx(), "PrintWizard"))); - toolBar.appendChild(bWizard); + if (toolbarPopup != null) + { + toolbarPopupLayout.appendChild(bWizard); + bWizard.setLabel(bWizard.getTooltiptext()); + } + else + toolBar.appendChild(bWizard); bWizard.addEventListener(Events.ON_CLICK, this); + if (toolbarPopup != null) + { + ToolBarButton more = new ToolBarButton(); + more.setImage(ThemeManager.getThemeResource("images/expand-header.png")); + more.setStyle("float: right;"); + toolBar.appendChild(more); + more.addEventListener(Events.ON_CLICK, evt -> { + toolbarPopup.open(more, "before_end"); + }); + } + North north = new North(); layout.appendChild(north); north.appendChild(toolBar); @@ -411,12 +517,12 @@ public class ZkReportViewer extends Window implements EventListener, ITab center.appendChild(iframe); South south = new South(); - ZKUpdateUtil.setHeight(south, "34px"); + ZKUpdateUtil.setHeight(south, "50px"); layout.appendChild(south); reportLink = new A(); reportLink.setTarget("_blank"); Div linkDiv = new Div(); - linkDiv.setStyle("width:100%; height: 30px; padding-top: 2px;"); + linkDiv.setStyle("width:100%; height: 40px; padding-top: 4px; padding-bottom: 4px;"); linkDiv.appendChild(reportLink); south.appendChild(linkDiv); //m_WindowNo @@ -523,13 +629,32 @@ public class ZkReportViewer extends Window implements EventListener, ITab } } mediaVersion++; - String url = Utils.getDynamicMediaURI(this, mediaVersion, media.getName(), media.getFormat()); - iframe.setContent(media); + String url = Utils.getDynamicMediaURI(this, mediaVersion, media.getName(), media.getFormat()); + String pdfJsUrl = "pdf.js/web/viewer.html?file="+url; HttpServletRequest request = (HttpServletRequest) Executions.getCurrent().getNativeRequest(); if (url.startsWith(request.getContextPath() + "/")) url = url.substring((request.getContextPath() + "/").length()); reportLink.setHref(url); - reportLink.setLabel(media.getName()); + reportLink.setLabel(media.getName()); + + if (ClientInfo.isMobile()) { + Listitem selected = previewType.getSelectedItem(); + if (selected == null || "PDF".equals(selected.getValue())) { + iframe.setSrc(pdfJsUrl); + } else if ("HTML".equals(previewType.getSelectedItem().getValue())) { + iframe.setSrc(null); + iframe.setContent(media); + } else { + iframe.setSrc(null); + iframe.setContent(null); + String script = "zk.Widget.$('#" + reportLink.getUuid()+"').$n().click();"; + Clients.evalJavaScript(script); + } + } else { + iframe.setSrc(null); + iframe.setContent(media); + } + revalidate(); } finally { hideBusyDialog(); @@ -718,6 +843,8 @@ public class ZkReportViewer extends Window implements EventListener, ITab ( m_reportEngine.getPrintFormat() == null || (m_reportEngine.getPrintFormat().getAD_Client_ID() == 0 && Env.getAD_Client_ID(Env.getCtx()) != 0) || m_reportEngine.getPrintFormat().isForm())); + + this.invalidate(); } // revalidate /** @@ -946,8 +1073,8 @@ public class ZkReportViewer extends Window implements EventListener, ITab { winExportFile = new Window(); winExportFile.setTitle(Msg.getMsg(Env.getCtx(), "Export") + ": " + getTitle()); - ZKUpdateUtil.setWidth(winExportFile, "450px"); - ZKUpdateUtil.setHeight(winExportFile, "150px"); + ZKUpdateUtil.setWindowWidthX(winExportFile, 450); + ZKUpdateUtil.setWindowHeightX(winExportFile, 150); winExportFile.setClosable(true); winExportFile.setBorder("normal"); winExportFile.setSclass("popup-dialog"); diff --git a/org.adempiere.ui.zk/WEB-INF/zk.xml b/org.adempiere.ui.zk/WEB-INF/zk.xml index 6501e80620..f024c7960e 100644 --- a/org.adempiere.ui.zk/WEB-INF/zk.xml +++ b/org.adempiere.ui.zk/WEB-INF/zk.xml @@ -109,6 +109,10 @@ org.zkoss.zk.ui.EventListener.duplicateIgnored true + + org.zkoss.zul.nativebar + true + org.zkoss.zk.ui.WebApp.name diff --git a/org.adempiere.ui.zk/build.properties b/org.adempiere.ui.zk/build.properties index 66bbf7a601..cbbdeb14c7 100644 --- a/org.adempiere.ui.zk/build.properties +++ b/org.adempiere.ui.zk/build.properties @@ -31,7 +31,8 @@ bin.includes = META-INF/,\ *.jsp,\ labelapplet.jar,\ OSGI-INF/jfgchartrenderer.xml,\ - WEB-INF/lib/daisydiff-min.jar + WEB-INF/lib/daisydiff-min.jar,\ + manifest.json src.includes = WEB-INF/tld/,\ WEB-INF/web.xml,\ WEB-INF/xsd/,\ diff --git a/org.adempiere.ui.zk/images/iD192.png b/org.adempiere.ui.zk/images/iD192.png new file mode 100644 index 0000000000000000000000000000000000000000..1950ab454bd06e7f489f0f46336daf154f3e35dc GIT binary patch literal 27641 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 sc@l{=9i+b9 + + + + + + + + + + +
+ +
+
+
+ + + +
+
+
+
+
+ + +
+
+ +
+ + + + +
+
+
+
+ +
+ +
+ +
+ +
+ + +
+
+ + + + + + + + + + +
+ + +
+
+
+ +
+ +
+ + + +
+
+
+
+
+
+
+
+
+
+ + + + + + + + +
+
+
+ + +
+ + + +
+
+ + + diff --git a/org.adempiere.ui.zk/pdf.js/web/viewer.js b/org.adempiere.ui.zk/pdf.js/web/viewer.js new file mode 100644 index 0000000000..71d8fb2cce --- /dev/null +++ b/org.adempiere.ui.zk/pdf.js/web/viewer.js @@ -0,0 +1,10446 @@ +/* Copyright 2017 Mozilla Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { +/******/ configurable: false, +/******/ enumerable: true, +/******/ get: getter +/******/ }); +/******/ } +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = 8); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.waitOnEventOrTimeout = exports.WaitOnType = exports.localized = exports.animationStarted = exports.normalizeWheelEventDelta = exports.binarySearchFirstItem = exports.watchScroll = exports.scrollIntoView = exports.getOutputScale = exports.approximateFraction = exports.roundToDivide = exports.getVisibleElements = exports.parseQueryString = exports.noContextMenuHandler = exports.getPDFFileNameFromURL = exports.ProgressBar = exports.EventBus = exports.NullL10n = exports.mozL10n = exports.RendererType = exports.PresentationModeState = exports.cloneObj = exports.isValidRotation = exports.VERTICAL_PADDING = exports.SCROLLBAR_PADDING = exports.MAX_AUTO_SCALE = exports.UNKNOWN_SCALE = exports.MAX_SCALE = exports.MIN_SCALE = exports.DEFAULT_SCALE = exports.DEFAULT_SCALE_VALUE = exports.CSS_UNITS = undefined; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +var _pdfjsLib = __webpack_require__(1); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var CSS_UNITS = 96.0 / 72.0; +var DEFAULT_SCALE_VALUE = 'auto'; +var DEFAULT_SCALE = 1.0; +var MIN_SCALE = 0.25; +var MAX_SCALE = 10.0; +var UNKNOWN_SCALE = 0; +var MAX_AUTO_SCALE = 1.25; +var SCROLLBAR_PADDING = 40; +var VERTICAL_PADDING = 5; +var PresentationModeState = { + UNKNOWN: 0, + NORMAL: 1, + CHANGING: 2, + FULLSCREEN: 3 +}; +var RendererType = { + CANVAS: 'canvas', + SVG: 'svg' +}; +function formatL10nValue(text, args) { + if (!args) { + return text; + } + return text.replace(/\{\{\s*(\w+)\s*\}\}/g, function (all, name) { + return name in args ? args[name] : '{{' + name + '}}'; + }); +} +var NullL10n = { + get: function get(property, args, fallback) { + return Promise.resolve(formatL10nValue(fallback, args)); + }, + translate: function translate(element) { + return Promise.resolve(); + } +}; +_pdfjsLib.PDFJS.disableFullscreen = _pdfjsLib.PDFJS.disableFullscreen === undefined ? false : _pdfjsLib.PDFJS.disableFullscreen; +_pdfjsLib.PDFJS.useOnlyCssZoom = _pdfjsLib.PDFJS.useOnlyCssZoom === undefined ? false : _pdfjsLib.PDFJS.useOnlyCssZoom; +_pdfjsLib.PDFJS.maxCanvasPixels = _pdfjsLib.PDFJS.maxCanvasPixels === undefined ? 16777216 : _pdfjsLib.PDFJS.maxCanvasPixels; +_pdfjsLib.PDFJS.disableHistory = _pdfjsLib.PDFJS.disableHistory === undefined ? false : _pdfjsLib.PDFJS.disableHistory; +_pdfjsLib.PDFJS.disableTextLayer = _pdfjsLib.PDFJS.disableTextLayer === undefined ? false : _pdfjsLib.PDFJS.disableTextLayer; +_pdfjsLib.PDFJS.ignoreCurrentPositionOnZoom = _pdfjsLib.PDFJS.ignoreCurrentPositionOnZoom === undefined ? false : _pdfjsLib.PDFJS.ignoreCurrentPositionOnZoom; +{ + _pdfjsLib.PDFJS.locale = _pdfjsLib.PDFJS.locale === undefined && typeof navigator !== 'undefined' ? navigator.language : _pdfjsLib.PDFJS.locale; +} +function getOutputScale(ctx) { + var devicePixelRatio = window.devicePixelRatio || 1; + var backingStoreRatio = ctx.webkitBackingStorePixelRatio || ctx.mozBackingStorePixelRatio || ctx.msBackingStorePixelRatio || ctx.oBackingStorePixelRatio || ctx.backingStorePixelRatio || 1; + var pixelRatio = devicePixelRatio / backingStoreRatio; + return { + sx: pixelRatio, + sy: pixelRatio, + scaled: pixelRatio !== 1 + }; +} +function scrollIntoView(element, spot) { + var skipOverflowHiddenElements = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + + var parent = element.offsetParent; + if (!parent) { + console.error('offsetParent is not set -- cannot scroll'); + return; + } + var offsetY = element.offsetTop + element.clientTop; + var offsetX = element.offsetLeft + element.clientLeft; + while (parent.clientHeight === parent.scrollHeight || skipOverflowHiddenElements && getComputedStyle(parent).overflow === 'hidden') { + if (parent.dataset._scaleY) { + offsetY /= parent.dataset._scaleY; + offsetX /= parent.dataset._scaleX; + } + offsetY += parent.offsetTop; + offsetX += parent.offsetLeft; + parent = parent.offsetParent; + if (!parent) { + return; + } + } + if (spot) { + if (spot.top !== undefined) { + offsetY += spot.top; + } + if (spot.left !== undefined) { + offsetX += spot.left; + parent.scrollLeft = offsetX; + } + } + parent.scrollTop = offsetY; +} +function watchScroll(viewAreaElement, callback) { + var debounceScroll = function debounceScroll(evt) { + if (rAF) { + return; + } + rAF = window.requestAnimationFrame(function viewAreaElementScrolled() { + rAF = null; + var currentY = viewAreaElement.scrollTop; + var lastY = state.lastY; + if (currentY !== lastY) { + state.down = currentY > lastY; + } + state.lastY = currentY; + callback(state); + }); + }; + var state = { + down: true, + lastY: viewAreaElement.scrollTop, + _eventHandler: debounceScroll + }; + var rAF = null; + viewAreaElement.addEventListener('scroll', debounceScroll, true); + return state; +} +function parseQueryString(query) { + var parts = query.split('&'); + var params = Object.create(null); + for (var i = 0, ii = parts.length; i < ii; ++i) { + var param = parts[i].split('='); + var key = param[0].toLowerCase(); + var value = param.length > 1 ? param[1] : null; + params[decodeURIComponent(key)] = decodeURIComponent(value); + } + return params; +} +function binarySearchFirstItem(items, condition) { + var minIndex = 0; + var maxIndex = items.length - 1; + if (items.length === 0 || !condition(items[maxIndex])) { + return items.length; + } + if (condition(items[minIndex])) { + return minIndex; + } + while (minIndex < maxIndex) { + var currentIndex = minIndex + maxIndex >> 1; + var currentItem = items[currentIndex]; + if (condition(currentItem)) { + maxIndex = currentIndex; + } else { + minIndex = currentIndex + 1; + } + } + return minIndex; +} +function approximateFraction(x) { + if (Math.floor(x) === x) { + return [x, 1]; + } + var xinv = 1 / x; + var limit = 8; + if (xinv > limit) { + return [1, limit]; + } else if (Math.floor(xinv) === xinv) { + return [1, xinv]; + } + var x_ = x > 1 ? xinv : x; + var a = 0, + b = 1, + c = 1, + d = 1; + while (true) { + var p = a + c, + q = b + d; + if (q > limit) { + break; + } + if (x_ <= p / q) { + c = p; + d = q; + } else { + a = p; + b = q; + } + } + var result = void 0; + if (x_ - a / b < c / d - x_) { + result = x_ === x ? [a, b] : [b, a]; + } else { + result = x_ === x ? [c, d] : [d, c]; + } + return result; +} +function roundToDivide(x, div) { + var r = x % div; + return r === 0 ? x : Math.round(x - r + div); +} +function getVisibleElements(scrollEl, views) { + var sortByVisibility = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + + var top = scrollEl.scrollTop, + bottom = top + scrollEl.clientHeight; + var left = scrollEl.scrollLeft, + right = left + scrollEl.clientWidth; + function isElementBottomBelowViewTop(view) { + var element = view.div; + var elementBottom = element.offsetTop + element.clientTop + element.clientHeight; + return elementBottom > top; + } + var visible = [], + view = void 0, + element = void 0; + var currentHeight = void 0, + viewHeight = void 0, + hiddenHeight = void 0, + percentHeight = void 0; + var currentWidth = void 0, + viewWidth = void 0; + var firstVisibleElementInd = views.length === 0 ? 0 : binarySearchFirstItem(views, isElementBottomBelowViewTop); + for (var i = firstVisibleElementInd, ii = views.length; i < ii; i++) { + view = views[i]; + element = view.div; + currentHeight = element.offsetTop + element.clientTop; + viewHeight = element.clientHeight; + if (currentHeight > bottom) { + break; + } + currentWidth = element.offsetLeft + element.clientLeft; + viewWidth = element.clientWidth; + if (currentWidth + viewWidth < left || currentWidth > right) { + continue; + } + hiddenHeight = Math.max(0, top - currentHeight) + Math.max(0, currentHeight + viewHeight - bottom); + percentHeight = (viewHeight - hiddenHeight) * 100 / viewHeight | 0; + visible.push({ + id: view.id, + x: currentWidth, + y: currentHeight, + view: view, + percent: percentHeight + }); + } + var first = visible[0]; + var last = visible[visible.length - 1]; + if (sortByVisibility) { + visible.sort(function (a, b) { + var pc = a.percent - b.percent; + if (Math.abs(pc) > 0.001) { + return -pc; + } + return a.id - b.id; + }); + } + return { + first: first, + last: last, + views: visible + }; +} +function noContextMenuHandler(evt) { + evt.preventDefault(); +} +function isDataSchema(url) { + var i = 0, + ii = url.length; + while (i < ii && url[i].trim() === '') { + i++; + } + return url.substr(i, 5).toLowerCase() === 'data:'; +} +function getPDFFileNameFromURL(url) { + var defaultFilename = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'document.pdf'; + + if (isDataSchema(url)) { + console.warn('getPDFFileNameFromURL: ' + 'ignoring "data:" URL for performance reasons.'); + return defaultFilename; + } + var reURI = /^(?:(?:[^:]+:)?\/\/[^\/]+)?([^?#]*)(\?[^#]*)?(#.*)?$/; + var reFilename = /[^\/?#=]+\.pdf\b(?!.*\.pdf\b)/i; + var splitURI = reURI.exec(url); + var suggestedFilename = reFilename.exec(splitURI[1]) || reFilename.exec(splitURI[2]) || reFilename.exec(splitURI[3]); + if (suggestedFilename) { + suggestedFilename = suggestedFilename[0]; + if (suggestedFilename.indexOf('%') !== -1) { + try { + suggestedFilename = reFilename.exec(decodeURIComponent(suggestedFilename))[0]; + } catch (ex) {} + } + } + return suggestedFilename || defaultFilename; +} +function normalizeWheelEventDelta(evt) { + var delta = Math.sqrt(evt.deltaX * evt.deltaX + evt.deltaY * evt.deltaY); + var angle = Math.atan2(evt.deltaY, evt.deltaX); + if (-0.25 * Math.PI < angle && angle < 0.75 * Math.PI) { + delta = -delta; + } + var MOUSE_DOM_DELTA_PIXEL_MODE = 0; + var MOUSE_DOM_DELTA_LINE_MODE = 1; + var MOUSE_PIXELS_PER_LINE = 30; + var MOUSE_LINES_PER_PAGE = 30; + if (evt.deltaMode === MOUSE_DOM_DELTA_PIXEL_MODE) { + delta /= MOUSE_PIXELS_PER_LINE * MOUSE_LINES_PER_PAGE; + } else if (evt.deltaMode === MOUSE_DOM_DELTA_LINE_MODE) { + delta /= MOUSE_LINES_PER_PAGE; + } + return delta; +} +function isValidRotation(angle) { + return Number.isInteger(angle) && angle % 90 === 0; +} +function cloneObj(obj) { + var result = Object.create(null); + for (var i in obj) { + if (Object.prototype.hasOwnProperty.call(obj, i)) { + result[i] = obj[i]; + } + } + return result; +} +var WaitOnType = { + EVENT: 'event', + TIMEOUT: 'timeout' +}; +function waitOnEventOrTimeout(_ref) { + var target = _ref.target, + name = _ref.name, + _ref$delay = _ref.delay, + delay = _ref$delay === undefined ? 0 : _ref$delay; + + if ((typeof target === 'undefined' ? 'undefined' : _typeof(target)) !== 'object' || !(name && typeof name === 'string') || !(Number.isInteger(delay) && delay >= 0)) { + return Promise.reject(new Error('waitOnEventOrTimeout - invalid paramaters.')); + } + var capability = (0, _pdfjsLib.createPromiseCapability)(); + function handler(type) { + if (target instanceof EventBus) { + target.off(name, eventHandler); + } else { + target.removeEventListener(name, eventHandler); + } + if (timeout) { + clearTimeout(timeout); + } + capability.resolve(type); + } + var eventHandler = handler.bind(null, WaitOnType.EVENT); + if (target instanceof EventBus) { + target.on(name, eventHandler); + } else { + target.addEventListener(name, eventHandler); + } + var timeoutHandler = handler.bind(null, WaitOnType.TIMEOUT); + var timeout = setTimeout(timeoutHandler, delay); + return capability.promise; +} +var animationStarted = new Promise(function (resolve) { + window.requestAnimationFrame(resolve); +}); +var mozL10n = void 0; +var localized = Promise.resolve(); + +var EventBus = function () { + function EventBus() { + _classCallCheck(this, EventBus); + + this._listeners = Object.create(null); + } + + _createClass(EventBus, [{ + key: 'on', + value: function on(eventName, listener) { + var eventListeners = this._listeners[eventName]; + if (!eventListeners) { + eventListeners = []; + this._listeners[eventName] = eventListeners; + } + eventListeners.push(listener); + } + }, { + key: 'off', + value: function off(eventName, listener) { + var eventListeners = this._listeners[eventName]; + var i = void 0; + if (!eventListeners || (i = eventListeners.indexOf(listener)) < 0) { + return; + } + eventListeners.splice(i, 1); + } + }, { + key: 'dispatch', + value: function dispatch(eventName) { + var eventListeners = this._listeners[eventName]; + if (!eventListeners || eventListeners.length === 0) { + return; + } + var args = Array.prototype.slice.call(arguments, 1); + eventListeners.slice(0).forEach(function (listener) { + listener.apply(null, args); + }); + } + }]); + + return EventBus; +}(); + +function clamp(v, min, max) { + return Math.min(Math.max(v, min), max); +} + +var ProgressBar = function () { + function ProgressBar(id) { + var _ref2 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, + height = _ref2.height, + width = _ref2.width, + units = _ref2.units; + + _classCallCheck(this, ProgressBar); + + this.visible = true; + this.div = document.querySelector(id + ' .progress'); + this.bar = this.div.parentNode; + this.height = height || 100; + this.width = width || 100; + this.units = units || '%'; + this.div.style.height = this.height + this.units; + this.percent = 0; + } + + _createClass(ProgressBar, [{ + key: '_updateBar', + value: function _updateBar() { + if (this._indeterminate) { + this.div.classList.add('indeterminate'); + this.div.style.width = this.width + this.units; + return; + } + this.div.classList.remove('indeterminate'); + var progressSize = this.width * this._percent / 100; + this.div.style.width = progressSize + this.units; + } + }, { + key: 'setWidth', + value: function setWidth(viewer) { + if (!viewer) { + return; + } + var container = viewer.parentNode; + var scrollbarWidth = container.offsetWidth - viewer.offsetWidth; + if (scrollbarWidth > 0) { + this.bar.setAttribute('style', 'width: calc(100% - ' + scrollbarWidth + 'px);'); + } + } + }, { + key: 'hide', + value: function hide() { + if (!this.visible) { + return; + } + this.visible = false; + this.bar.classList.add('hidden'); + document.body.classList.remove('loadingInProgress'); + } + }, { + key: 'show', + value: function show() { + if (this.visible) { + return; + } + this.visible = true; + document.body.classList.add('loadingInProgress'); + this.bar.classList.remove('hidden'); + } + }, { + key: 'percent', + get: function get() { + return this._percent; + }, + set: function set(val) { + this._indeterminate = isNaN(val); + this._percent = clamp(val, 0, 100); + this._updateBar(); + } + }]); + + return ProgressBar; +}(); + +exports.CSS_UNITS = CSS_UNITS; +exports.DEFAULT_SCALE_VALUE = DEFAULT_SCALE_VALUE; +exports.DEFAULT_SCALE = DEFAULT_SCALE; +exports.MIN_SCALE = MIN_SCALE; +exports.MAX_SCALE = MAX_SCALE; +exports.UNKNOWN_SCALE = UNKNOWN_SCALE; +exports.MAX_AUTO_SCALE = MAX_AUTO_SCALE; +exports.SCROLLBAR_PADDING = SCROLLBAR_PADDING; +exports.VERTICAL_PADDING = VERTICAL_PADDING; +exports.isValidRotation = isValidRotation; +exports.cloneObj = cloneObj; +exports.PresentationModeState = PresentationModeState; +exports.RendererType = RendererType; +exports.mozL10n = mozL10n; +exports.NullL10n = NullL10n; +exports.EventBus = EventBus; +exports.ProgressBar = ProgressBar; +exports.getPDFFileNameFromURL = getPDFFileNameFromURL; +exports.noContextMenuHandler = noContextMenuHandler; +exports.parseQueryString = parseQueryString; +exports.getVisibleElements = getVisibleElements; +exports.roundToDivide = roundToDivide; +exports.approximateFraction = approximateFraction; +exports.getOutputScale = getOutputScale; +exports.scrollIntoView = scrollIntoView; +exports.watchScroll = watchScroll; +exports.binarySearchFirstItem = binarySearchFirstItem; +exports.normalizeWheelEventDelta = normalizeWheelEventDelta; +exports.animationStarted = animationStarted; +exports.localized = localized; +exports.WaitOnType = WaitOnType; +exports.waitOnEventOrTimeout = waitOnEventOrTimeout; + +/***/ }), +/* 1 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var pdfjsLib; +if (typeof window !== 'undefined' && window['pdfjs-dist/build/pdf']) { + pdfjsLib = window['pdfjs-dist/build/pdf']; +} else { + pdfjsLib = require('../build/pdf.js'); +} +module.exports = pdfjsLib; + +/***/ }), +/* 2 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getGlobalEventBus = exports.attachDOMEventsToEventBus = undefined; + +var _ui_utils = __webpack_require__(0); + +function attachDOMEventsToEventBus(eventBus) { + eventBus.on('documentload', function () { + var event = document.createEvent('CustomEvent'); + event.initCustomEvent('documentload', true, true, {}); + window.dispatchEvent(event); + }); + eventBus.on('pagerendered', function (evt) { + var event = document.createEvent('CustomEvent'); + event.initCustomEvent('pagerendered', true, true, { + pageNumber: evt.pageNumber, + cssTransform: evt.cssTransform + }); + evt.source.div.dispatchEvent(event); + }); + eventBus.on('textlayerrendered', function (evt) { + var event = document.createEvent('CustomEvent'); + event.initCustomEvent('textlayerrendered', true, true, { pageNumber: evt.pageNumber }); + evt.source.textLayerDiv.dispatchEvent(event); + }); + eventBus.on('pagechange', function (evt) { + var event = document.createEvent('UIEvents'); + event.initUIEvent('pagechange', true, true, window, 0); + event.pageNumber = evt.pageNumber; + evt.source.container.dispatchEvent(event); + }); + eventBus.on('pagesinit', function (evt) { + var event = document.createEvent('CustomEvent'); + event.initCustomEvent('pagesinit', true, true, null); + evt.source.container.dispatchEvent(event); + }); + eventBus.on('pagesloaded', function (evt) { + var event = document.createEvent('CustomEvent'); + event.initCustomEvent('pagesloaded', true, true, { pagesCount: evt.pagesCount }); + evt.source.container.dispatchEvent(event); + }); + eventBus.on('scalechange', function (evt) { + var event = document.createEvent('UIEvents'); + event.initUIEvent('scalechange', true, true, window, 0); + event.scale = evt.scale; + event.presetValue = evt.presetValue; + evt.source.container.dispatchEvent(event); + }); + eventBus.on('updateviewarea', function (evt) { + var event = document.createEvent('UIEvents'); + event.initUIEvent('updateviewarea', true, true, window, 0); + event.location = evt.location; + evt.source.container.dispatchEvent(event); + }); + eventBus.on('find', function (evt) { + if (evt.source === window) { + return; + } + var event = document.createEvent('CustomEvent'); + event.initCustomEvent('find' + evt.type, true, true, { + query: evt.query, + phraseSearch: evt.phraseSearch, + caseSensitive: evt.caseSensitive, + highlightAll: evt.highlightAll, + findPrevious: evt.findPrevious + }); + window.dispatchEvent(event); + }); + eventBus.on('attachmentsloaded', function (evt) { + var event = document.createEvent('CustomEvent'); + event.initCustomEvent('attachmentsloaded', true, true, { attachmentsCount: evt.attachmentsCount }); + evt.source.container.dispatchEvent(event); + }); + eventBus.on('sidebarviewchanged', function (evt) { + var event = document.createEvent('CustomEvent'); + event.initCustomEvent('sidebarviewchanged', true, true, { view: evt.view }); + evt.source.outerContainer.dispatchEvent(event); + }); + eventBus.on('pagemode', function (evt) { + var event = document.createEvent('CustomEvent'); + event.initCustomEvent('pagemode', true, true, { mode: evt.mode }); + evt.source.pdfViewer.container.dispatchEvent(event); + }); + eventBus.on('namedaction', function (evt) { + var event = document.createEvent('CustomEvent'); + event.initCustomEvent('namedaction', true, true, { action: evt.action }); + evt.source.pdfViewer.container.dispatchEvent(event); + }); + eventBus.on('presentationmodechanged', function (evt) { + var event = document.createEvent('CustomEvent'); + event.initCustomEvent('presentationmodechanged', true, true, { + active: evt.active, + switchInProgress: evt.switchInProgress + }); + window.dispatchEvent(event); + }); + eventBus.on('outlineloaded', function (evt) { + var event = document.createEvent('CustomEvent'); + event.initCustomEvent('outlineloaded', true, true, { outlineCount: evt.outlineCount }); + evt.source.container.dispatchEvent(event); + }); +} +var globalEventBus = null; +function getGlobalEventBus() { + if (globalEventBus) { + return globalEventBus; + } + globalEventBus = new _ui_utils.EventBus(); + attachDOMEventsToEventBus(globalEventBus); + return globalEventBus; +} +exports.attachDOMEventsToEventBus = attachDOMEventsToEventBus; +exports.getGlobalEventBus = getGlobalEventBus; + +/***/ }), +/* 3 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var CLEANUP_TIMEOUT = 30000; +var RenderingStates = { + INITIAL: 0, + RUNNING: 1, + PAUSED: 2, + FINISHED: 3 +}; + +var PDFRenderingQueue = function () { + function PDFRenderingQueue() { + _classCallCheck(this, PDFRenderingQueue); + + this.pdfViewer = null; + this.pdfThumbnailViewer = null; + this.onIdle = null; + this.highestPriorityPage = null; + this.idleTimeout = null; + this.printing = false; + this.isThumbnailViewEnabled = false; + } + + _createClass(PDFRenderingQueue, [{ + key: "setViewer", + value: function setViewer(pdfViewer) { + this.pdfViewer = pdfViewer; + } + }, { + key: "setThumbnailViewer", + value: function setThumbnailViewer(pdfThumbnailViewer) { + this.pdfThumbnailViewer = pdfThumbnailViewer; + } + }, { + key: "isHighestPriority", + value: function isHighestPriority(view) { + return this.highestPriorityPage === view.renderingId; + } + }, { + key: "renderHighestPriority", + value: function renderHighestPriority(currentlyVisiblePages) { + if (this.idleTimeout) { + clearTimeout(this.idleTimeout); + this.idleTimeout = null; + } + if (this.pdfViewer.forceRendering(currentlyVisiblePages)) { + return; + } + if (this.pdfThumbnailViewer && this.isThumbnailViewEnabled) { + if (this.pdfThumbnailViewer.forceRendering()) { + return; + } + } + if (this.printing) { + return; + } + if (this.onIdle) { + this.idleTimeout = setTimeout(this.onIdle.bind(this), CLEANUP_TIMEOUT); + } + } + }, { + key: "getHighestPriority", + value: function getHighestPriority(visible, views, scrolledDown) { + var visibleViews = visible.views; + var numVisible = visibleViews.length; + if (numVisible === 0) { + return false; + } + for (var i = 0; i < numVisible; ++i) { + var view = visibleViews[i].view; + if (!this.isViewFinished(view)) { + return view; + } + } + if (scrolledDown) { + var nextPageIndex = visible.last.id; + if (views[nextPageIndex] && !this.isViewFinished(views[nextPageIndex])) { + return views[nextPageIndex]; + } + } else { + var previousPageIndex = visible.first.id - 2; + if (views[previousPageIndex] && !this.isViewFinished(views[previousPageIndex])) { + return views[previousPageIndex]; + } + } + return null; + } + }, { + key: "isViewFinished", + value: function isViewFinished(view) { + return view.renderingState === RenderingStates.FINISHED; + } + }, { + key: "renderView", + value: function renderView(view) { + var _this = this; + + switch (view.renderingState) { + case RenderingStates.FINISHED: + return false; + case RenderingStates.PAUSED: + this.highestPriorityPage = view.renderingId; + view.resume(); + break; + case RenderingStates.RUNNING: + this.highestPriorityPage = view.renderingId; + break; + case RenderingStates.INITIAL: + this.highestPriorityPage = view.renderingId; + var continueRendering = function continueRendering() { + _this.renderHighestPriority(); + }; + view.draw().then(continueRendering, continueRendering); + break; + } + return true; + } + }]); + + return PDFRenderingQueue; +}(); + +exports.RenderingStates = RenderingStates; +exports.PDFRenderingQueue = PDFRenderingQueue; + +/***/ }), +/* 4 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.PDFPrintServiceFactory = exports.DefaultExternalServices = exports.PDFViewerApplication = undefined; + +var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); + +var _ui_utils = __webpack_require__(0); + +var _pdfjsLib = __webpack_require__(1); + +var _pdf_cursor_tools = __webpack_require__(6); + +var _pdf_rendering_queue = __webpack_require__(3); + +var _pdf_sidebar = __webpack_require__(10); + +var _dom_events = __webpack_require__(2); + +var _overlay_manager = __webpack_require__(11); + +var _password_prompt = __webpack_require__(12); + +var _pdf_attachment_viewer = __webpack_require__(13); + +var _pdf_document_properties = __webpack_require__(14); + +var _pdf_find_bar = __webpack_require__(15); + +var _pdf_find_controller = __webpack_require__(7); + +var _pdf_history = __webpack_require__(16); + +var _pdf_link_service = __webpack_require__(5); + +var _pdf_outline_viewer = __webpack_require__(17); + +var _pdf_presentation_mode = __webpack_require__(18); + +var _pdf_thumbnail_viewer = __webpack_require__(19); + +var _pdf_viewer = __webpack_require__(21); + +var _secondary_toolbar = __webpack_require__(26); + +var _toolbar = __webpack_require__(27); + +var _view_history = __webpack_require__(28); + +var DEFAULT_SCALE_DELTA = 1.1; +var DISABLE_AUTO_FETCH_LOADING_BAR_TIMEOUT = 5000; +function configure(PDFJS) { + PDFJS.imageResourcesPath = './images/'; + PDFJS.workerSrc = '../build/pdf.worker.js'; + PDFJS.cMapUrl = '../web/cmaps/'; + PDFJS.cMapPacked = true; +} +var DefaultExternalServices = { + updateFindControlState: function updateFindControlState(data) {}, + initPassiveLoading: function initPassiveLoading(callbacks) {}, + fallback: function fallback(data, callback) {}, + reportTelemetry: function reportTelemetry(data) {}, + createDownloadManager: function createDownloadManager() { + throw new Error('Not implemented: createDownloadManager'); + }, + createPreferences: function createPreferences() { + throw new Error('Not implemented: createPreferences'); + }, + createL10n: function createL10n() { + throw new Error('Not implemented: createL10n'); + }, + + supportsIntegratedFind: false, + supportsDocumentFonts: true, + supportsDocumentColors: true, + supportedMouseWheelZoomModifierKeys: { + ctrlKey: true, + metaKey: true + } +}; +var PDFViewerApplication = { + initialBookmark: document.location.hash.substring(1), + initialized: false, + fellback: false, + appConfig: null, + pdfDocument: null, + pdfLoadingTask: null, + printService: null, + pdfViewer: null, + pdfThumbnailViewer: null, + pdfRenderingQueue: null, + pdfPresentationMode: null, + pdfDocumentProperties: null, + pdfLinkService: null, + pdfHistory: null, + pdfSidebar: null, + pdfOutlineViewer: null, + pdfAttachmentViewer: null, + pdfCursorTools: null, + store: null, + downloadManager: null, + overlayManager: null, + preferences: null, + toolbar: null, + secondaryToolbar: null, + eventBus: null, + l10n: null, + isInitialViewSet: false, + downloadComplete: false, + viewerPrefs: { + sidebarViewOnLoad: _pdf_sidebar.SidebarView.NONE, + pdfBugEnabled: false, + showPreviousViewOnLoad: true, + defaultZoomValue: '', + disablePageMode: false, + disablePageLabels: false, + renderer: 'canvas', + enhanceTextSelection: false, + renderInteractiveForms: false, + enablePrintAutoRotate: false + }, + isViewerEmbedded: window.parent !== window, + url: '', + baseUrl: '', + externalServices: DefaultExternalServices, + _boundEvents: {}, + initialize: function initialize(appConfig) { + var _this = this; + + this.preferences = this.externalServices.createPreferences(); + configure(_pdfjsLib.PDFJS); + this.appConfig = appConfig; + return this._readPreferences().then(function () { + return _this._initializeL10n(); + }).then(function () { + return _this._initializeViewerComponents(); + }).then(function () { + _this.bindEvents(); + _this.bindWindowEvents(); + var appContainer = appConfig.appContainer || document.documentElement; + _this.l10n.translate(appContainer).then(function () { + _this.eventBus.dispatch('localized'); + }); + if (_this.isViewerEmbedded && !_pdfjsLib.PDFJS.isExternalLinkTargetSet()) { + _pdfjsLib.PDFJS.externalLinkTarget = _pdfjsLib.PDFJS.LinkTarget.TOP; + } + _this.initialized = true; + }); + }, + _readPreferences: function _readPreferences() { + var preferences = this.preferences, + viewerPrefs = this.viewerPrefs; + + return Promise.all([preferences.get('enableWebGL').then(function resolved(value) { + _pdfjsLib.PDFJS.disableWebGL = !value; + }), preferences.get('sidebarViewOnLoad').then(function resolved(value) { + viewerPrefs['sidebarViewOnLoad'] = value; + }), preferences.get('pdfBugEnabled').then(function resolved(value) { + viewerPrefs['pdfBugEnabled'] = value; + }), preferences.get('showPreviousViewOnLoad').then(function resolved(value) { + viewerPrefs['showPreviousViewOnLoad'] = value; + }), preferences.get('defaultZoomValue').then(function resolved(value) { + viewerPrefs['defaultZoomValue'] = value; + }), preferences.get('enhanceTextSelection').then(function resolved(value) { + viewerPrefs['enhanceTextSelection'] = value; + }), preferences.get('disableTextLayer').then(function resolved(value) { + if (_pdfjsLib.PDFJS.disableTextLayer === true) { + return; + } + _pdfjsLib.PDFJS.disableTextLayer = value; + }), preferences.get('disableRange').then(function resolved(value) { + if (_pdfjsLib.PDFJS.disableRange === true) { + return; + } + _pdfjsLib.PDFJS.disableRange = value; + }), preferences.get('disableStream').then(function resolved(value) { + if (_pdfjsLib.PDFJS.disableStream === true) { + return; + } + _pdfjsLib.PDFJS.disableStream = value; + }), preferences.get('disableAutoFetch').then(function resolved(value) { + _pdfjsLib.PDFJS.disableAutoFetch = value; + }), preferences.get('disableFontFace').then(function resolved(value) { + if (_pdfjsLib.PDFJS.disableFontFace === true) { + return; + } + _pdfjsLib.PDFJS.disableFontFace = value; + }), preferences.get('useOnlyCssZoom').then(function resolved(value) { + _pdfjsLib.PDFJS.useOnlyCssZoom = value; + }), preferences.get('externalLinkTarget').then(function resolved(value) { + if (_pdfjsLib.PDFJS.isExternalLinkTargetSet()) { + return; + } + _pdfjsLib.PDFJS.externalLinkTarget = value; + }), preferences.get('renderer').then(function resolved(value) { + viewerPrefs['renderer'] = value; + }), preferences.get('renderInteractiveForms').then(function resolved(value) { + viewerPrefs['renderInteractiveForms'] = value; + }), preferences.get('disablePageMode').then(function resolved(value) { + viewerPrefs['disablePageMode'] = value; + }), preferences.get('disablePageLabels').then(function resolved(value) { + viewerPrefs['disablePageLabels'] = value; + }), preferences.get('enablePrintAutoRotate').then(function resolved(value) { + viewerPrefs['enablePrintAutoRotate'] = value; + })]).catch(function (reason) {}); + }, + _initializeL10n: function _initializeL10n() { + if (this.viewerPrefs['pdfBugEnabled']) { + var hash = document.location.hash.substring(1); + var hashParams = (0, _ui_utils.parseQueryString)(hash); + if ('locale' in hashParams) { + _pdfjsLib.PDFJS.locale = hashParams['locale']; + } + } + this.l10n = this.externalServices.createL10n(); + return this.l10n.getDirection().then(function (dir) { + document.getElementsByTagName('html')[0].dir = dir; + }); + }, + _initializeViewerComponents: function _initializeViewerComponents() { + var _this2 = this; + + var appConfig = this.appConfig; + return new Promise(function (resolve, reject) { + _this2.overlayManager = new _overlay_manager.OverlayManager(); + var eventBus = appConfig.eventBus || (0, _dom_events.getGlobalEventBus)(); + _this2.eventBus = eventBus; + var pdfRenderingQueue = new _pdf_rendering_queue.PDFRenderingQueue(); + pdfRenderingQueue.onIdle = _this2.cleanup.bind(_this2); + _this2.pdfRenderingQueue = pdfRenderingQueue; + var pdfLinkService = new _pdf_link_service.PDFLinkService({ eventBus: eventBus }); + _this2.pdfLinkService = pdfLinkService; + var downloadManager = _this2.externalServices.createDownloadManager(); + _this2.downloadManager = downloadManager; + var container = appConfig.mainContainer; + var viewer = appConfig.viewerContainer; + _this2.pdfViewer = new _pdf_viewer.PDFViewer({ + container: container, + viewer: viewer, + eventBus: eventBus, + renderingQueue: pdfRenderingQueue, + linkService: pdfLinkService, + downloadManager: downloadManager, + renderer: _this2.viewerPrefs['renderer'], + l10n: _this2.l10n, + enhanceTextSelection: _this2.viewerPrefs['enhanceTextSelection'], + renderInteractiveForms: _this2.viewerPrefs['renderInteractiveForms'], + enablePrintAutoRotate: _this2.viewerPrefs['enablePrintAutoRotate'] + }); + pdfRenderingQueue.setViewer(_this2.pdfViewer); + pdfLinkService.setViewer(_this2.pdfViewer); + var thumbnailContainer = appConfig.sidebar.thumbnailView; + _this2.pdfThumbnailViewer = new _pdf_thumbnail_viewer.PDFThumbnailViewer({ + container: thumbnailContainer, + renderingQueue: pdfRenderingQueue, + linkService: pdfLinkService, + l10n: _this2.l10n + }); + pdfRenderingQueue.setThumbnailViewer(_this2.pdfThumbnailViewer); + _this2.pdfHistory = new _pdf_history.PDFHistory({ + linkService: pdfLinkService, + eventBus: eventBus + }); + pdfLinkService.setHistory(_this2.pdfHistory); + _this2.findController = new _pdf_find_controller.PDFFindController({ pdfViewer: _this2.pdfViewer }); + _this2.findController.onUpdateResultsCount = function (matchCount) { + if (_this2.supportsIntegratedFind) { + return; + } + _this2.findBar.updateResultsCount(matchCount); + }; + _this2.findController.onUpdateState = function (state, previous, matchCount) { + if (_this2.supportsIntegratedFind) { + _this2.externalServices.updateFindControlState({ + result: state, + findPrevious: previous + }); + } else { + _this2.findBar.updateUIState(state, previous, matchCount); + } + }; + _this2.pdfViewer.setFindController(_this2.findController); + var findBarConfig = Object.create(appConfig.findBar); + findBarConfig.findController = _this2.findController; + findBarConfig.eventBus = eventBus; + _this2.findBar = new _pdf_find_bar.PDFFindBar(findBarConfig, _this2.l10n); + _this2.pdfDocumentProperties = new _pdf_document_properties.PDFDocumentProperties(appConfig.documentProperties, _this2.overlayManager, _this2.l10n); + _this2.pdfCursorTools = new _pdf_cursor_tools.PDFCursorTools({ + container: container, + eventBus: eventBus, + preferences: _this2.preferences + }); + _this2.toolbar = new _toolbar.Toolbar(appConfig.toolbar, container, eventBus, _this2.l10n); + _this2.secondaryToolbar = new _secondary_toolbar.SecondaryToolbar(appConfig.secondaryToolbar, container, eventBus); + if (_this2.supportsFullscreen) { + _this2.pdfPresentationMode = new _pdf_presentation_mode.PDFPresentationMode({ + container: container, + viewer: viewer, + pdfViewer: _this2.pdfViewer, + eventBus: eventBus, + contextMenuItems: appConfig.fullscreen + }); + } + _this2.passwordPrompt = new _password_prompt.PasswordPrompt(appConfig.passwordOverlay, _this2.overlayManager, _this2.l10n); + _this2.pdfOutlineViewer = new _pdf_outline_viewer.PDFOutlineViewer({ + container: appConfig.sidebar.outlineView, + eventBus: eventBus, + linkService: pdfLinkService + }); + _this2.pdfAttachmentViewer = new _pdf_attachment_viewer.PDFAttachmentViewer({ + container: appConfig.sidebar.attachmentsView, + eventBus: eventBus, + downloadManager: downloadManager + }); + var sidebarConfig = Object.create(appConfig.sidebar); + sidebarConfig.pdfViewer = _this2.pdfViewer; + sidebarConfig.pdfThumbnailViewer = _this2.pdfThumbnailViewer; + sidebarConfig.pdfOutlineViewer = _this2.pdfOutlineViewer; + sidebarConfig.eventBus = eventBus; + _this2.pdfSidebar = new _pdf_sidebar.PDFSidebar(sidebarConfig, _this2.l10n); + _this2.pdfSidebar.onToggled = _this2.forceRendering.bind(_this2); + resolve(undefined); + }); + }, + run: function run(config) { + this.initialize(config).then(webViewerInitialized); + }, + zoomIn: function zoomIn(ticks) { + var newScale = this.pdfViewer.currentScale; + do { + newScale = (newScale * DEFAULT_SCALE_DELTA).toFixed(2); + newScale = Math.ceil(newScale * 10) / 10; + newScale = Math.min(_ui_utils.MAX_SCALE, newScale); + } while (--ticks > 0 && newScale < _ui_utils.MAX_SCALE); + this.pdfViewer.currentScaleValue = newScale; + }, + zoomOut: function zoomOut(ticks) { + var newScale = this.pdfViewer.currentScale; + do { + newScale = (newScale / DEFAULT_SCALE_DELTA).toFixed(2); + newScale = Math.floor(newScale * 10) / 10; + newScale = Math.max(_ui_utils.MIN_SCALE, newScale); + } while (--ticks > 0 && newScale > _ui_utils.MIN_SCALE); + this.pdfViewer.currentScaleValue = newScale; + }, + + get pagesCount() { + return this.pdfDocument ? this.pdfDocument.numPages : 0; + }, + get pageRotation() { + return this.pdfViewer.pagesRotation; + }, + set page(val) { + this.pdfViewer.currentPageNumber = val; + }, + get page() { + return this.pdfViewer.currentPageNumber; + }, + get printing() { + return !!this.printService; + }, + get supportsPrinting() { + return PDFPrintServiceFactory.instance.supportsPrinting; + }, + get supportsFullscreen() { + var support = void 0; + var doc = document.documentElement; + support = !!(doc.requestFullscreen || doc.mozRequestFullScreen || doc.webkitRequestFullScreen || doc.msRequestFullscreen); + if (document.fullscreenEnabled === false || document.mozFullScreenEnabled === false || document.webkitFullscreenEnabled === false || document.msFullscreenEnabled === false) { + support = false; + } + if (support && _pdfjsLib.PDFJS.disableFullscreen === true) { + support = false; + } + return (0, _pdfjsLib.shadow)(this, 'supportsFullscreen', support); + }, + get supportsIntegratedFind() { + return this.externalServices.supportsIntegratedFind; + }, + get supportsDocumentFonts() { + return this.externalServices.supportsDocumentFonts; + }, + get supportsDocumentColors() { + return this.externalServices.supportsDocumentColors; + }, + get loadingBar() { + var bar = new _ui_utils.ProgressBar('#loadingBar'); + return (0, _pdfjsLib.shadow)(this, 'loadingBar', bar); + }, + get supportedMouseWheelZoomModifierKeys() { + return this.externalServices.supportedMouseWheelZoomModifierKeys; + }, + initPassiveLoading: function initPassiveLoading() { + throw new Error('Not implemented: initPassiveLoading'); + }, + setTitleUsingUrl: function setTitleUsingUrl(url) { + this.url = url; + this.baseUrl = url.split('#')[0]; + var title = (0, _ui_utils.getPDFFileNameFromURL)(url, ''); + if (!title) { + try { + title = decodeURIComponent((0, _pdfjsLib.getFilenameFromUrl)(url)) || url; + } catch (ex) { + title = url; + } + } + this.setTitle(title); + }, + setTitle: function setTitle(title) { + if (this.isViewerEmbedded) { + return; + } + document.title = title; + }, + close: function close() { + var errorWrapper = this.appConfig.errorWrapper.container; + errorWrapper.setAttribute('hidden', 'true'); + if (!this.pdfLoadingTask) { + return Promise.resolve(); + } + var promise = this.pdfLoadingTask.destroy(); + this.pdfLoadingTask = null; + if (this.pdfDocument) { + this.pdfDocument = null; + this.pdfThumbnailViewer.setDocument(null); + this.pdfViewer.setDocument(null); + this.pdfLinkService.setDocument(null, null); + this.pdfDocumentProperties.setDocument(null, null); + } + this.store = null; + this.isInitialViewSet = false; + this.downloadComplete = false; + this.pdfSidebar.reset(); + this.pdfOutlineViewer.reset(); + this.pdfAttachmentViewer.reset(); + this.findController.reset(); + this.findBar.reset(); + this.toolbar.reset(); + this.secondaryToolbar.reset(); + if (typeof PDFBug !== 'undefined') { + PDFBug.cleanup(); + } + return promise; + }, + open: function open(file, args) { + var _this3 = this; + + if (arguments.length > 2 || typeof args === 'number') { + return Promise.reject(new Error('Call of open() with obsolete signature.')); + } + if (this.pdfLoadingTask) { + return this.close().then(function () { + _this3.preferences.reload(); + return _this3.open(file, args); + }); + } + var parameters = Object.create(null); + if (typeof file === 'string') { + this.setTitleUsingUrl(file); + parameters.url = file; + } else if (file && 'byteLength' in file) { + parameters.data = file; + } else if (file.url && file.originalUrl) { + this.setTitleUsingUrl(file.originalUrl); + parameters.url = file.url; + } + if (args) { + for (var prop in args) { + if (!_pdfjsLib.PDFJS.pdfjsNext && prop === 'scale') { + console.error('Call of open() with obsolete "scale" argument, ' + 'please use the "defaultZoomValue" preference instead.'); + continue; + } else if (prop === 'length') { + this.pdfDocumentProperties.setFileSize(args[prop]); + } + parameters[prop] = args[prop]; + } + } + var loadingTask = (0, _pdfjsLib.getDocument)(parameters); + this.pdfLoadingTask = loadingTask; + loadingTask.onPassword = function (updateCallback, reason) { + _this3.passwordPrompt.setUpdateCallback(updateCallback, reason); + _this3.passwordPrompt.open(); + }; + loadingTask.onProgress = function (_ref) { + var loaded = _ref.loaded, + total = _ref.total; + + _this3.progress(loaded / total); + }; + loadingTask.onUnsupportedFeature = this.fallback.bind(this); + return loadingTask.promise.then(function (pdfDocument) { + _this3.load(pdfDocument); + }, function (exception) { + var message = exception && exception.message; + var loadingErrorMessage = void 0; + if (exception instanceof _pdfjsLib.InvalidPDFException) { + loadingErrorMessage = _this3.l10n.get('invalid_file_error', null, 'Invalid or corrupted PDF file.'); + } else if (exception instanceof _pdfjsLib.MissingPDFException) { + loadingErrorMessage = _this3.l10n.get('missing_file_error', null, 'Missing PDF file.'); + } else if (exception instanceof _pdfjsLib.UnexpectedResponseException) { + loadingErrorMessage = _this3.l10n.get('unexpected_response_error', null, 'Unexpected server response.'); + } else { + loadingErrorMessage = _this3.l10n.get('loading_error', null, 'An error occurred while loading the PDF.'); + } + return loadingErrorMessage.then(function (msg) { + _this3.error(msg, { message: message }); + throw new Error(msg); + }); + }); + }, + download: function download() { + var _this4 = this; + + function downloadByUrl() { + downloadManager.downloadUrl(url, filename); + } + var url = this.baseUrl; + var filename = (0, _ui_utils.getPDFFileNameFromURL)(this.url); + var downloadManager = this.downloadManager; + downloadManager.onerror = function (err) { + _this4.error('PDF failed to download: ' + err); + }; + if (!this.pdfDocument || !this.downloadComplete) { + downloadByUrl(); + return; + } + this.pdfDocument.getData().then(function (data) { + var blob = (0, _pdfjsLib.createBlob)(data, 'application/pdf'); + downloadManager.download(blob, url, filename); + }).catch(downloadByUrl); + }, + fallback: function fallback(featureId) {}, + error: function error(message, moreInfo) { + var moreInfoText = [this.l10n.get('error_version_info', { + version: _pdfjsLib.version || '?', + build: _pdfjsLib.build || '?' + }, 'PDF.js v{{version}} (build: {{build}})')]; + if (moreInfo) { + moreInfoText.push(this.l10n.get('error_message', { message: moreInfo.message }, 'Message: {{message}}')); + if (moreInfo.stack) { + moreInfoText.push(this.l10n.get('error_stack', { stack: moreInfo.stack }, 'Stack: {{stack}}')); + } else { + if (moreInfo.filename) { + moreInfoText.push(this.l10n.get('error_file', { file: moreInfo.filename }, 'File: {{file}}')); + } + if (moreInfo.lineNumber) { + moreInfoText.push(this.l10n.get('error_line', { line: moreInfo.lineNumber }, 'Line: {{line}}')); + } + } + } + var errorWrapperConfig = this.appConfig.errorWrapper; + var errorWrapper = errorWrapperConfig.container; + errorWrapper.removeAttribute('hidden'); + var errorMessage = errorWrapperConfig.errorMessage; + errorMessage.textContent = message; + var closeButton = errorWrapperConfig.closeButton; + closeButton.onclick = function () { + errorWrapper.setAttribute('hidden', 'true'); + }; + var errorMoreInfo = errorWrapperConfig.errorMoreInfo; + var moreInfoButton = errorWrapperConfig.moreInfoButton; + var lessInfoButton = errorWrapperConfig.lessInfoButton; + moreInfoButton.onclick = function () { + errorMoreInfo.removeAttribute('hidden'); + moreInfoButton.setAttribute('hidden', 'true'); + lessInfoButton.removeAttribute('hidden'); + errorMoreInfo.style.height = errorMoreInfo.scrollHeight + 'px'; + }; + lessInfoButton.onclick = function () { + errorMoreInfo.setAttribute('hidden', 'true'); + moreInfoButton.removeAttribute('hidden'); + lessInfoButton.setAttribute('hidden', 'true'); + }; + moreInfoButton.oncontextmenu = _ui_utils.noContextMenuHandler; + lessInfoButton.oncontextmenu = _ui_utils.noContextMenuHandler; + closeButton.oncontextmenu = _ui_utils.noContextMenuHandler; + moreInfoButton.removeAttribute('hidden'); + lessInfoButton.setAttribute('hidden', 'true'); + Promise.all(moreInfoText).then(function (parts) { + errorMoreInfo.value = parts.join('\n'); + }); + }, + progress: function progress(level) { + var _this5 = this; + + if (this.downloadComplete) { + return; + } + var percent = Math.round(level * 100); + if (percent > this.loadingBar.percent || isNaN(percent)) { + this.loadingBar.percent = percent; + if (_pdfjsLib.PDFJS.disableAutoFetch && percent) { + if (this.disableAutoFetchLoadingBarTimeout) { + clearTimeout(this.disableAutoFetchLoadingBarTimeout); + this.disableAutoFetchLoadingBarTimeout = null; + } + this.loadingBar.show(); + this.disableAutoFetchLoadingBarTimeout = setTimeout(function () { + _this5.loadingBar.hide(); + _this5.disableAutoFetchLoadingBarTimeout = null; + }, DISABLE_AUTO_FETCH_LOADING_BAR_TIMEOUT); + } + } + }, + load: function load(pdfDocument) { + var _this6 = this; + + this.pdfDocument = pdfDocument; + pdfDocument.getDownloadInfo().then(function () { + _this6.downloadComplete = true; + _this6.loadingBar.hide(); + firstPagePromise.then(function () { + _this6.eventBus.dispatch('documentload', { source: _this6 }); + }); + }); + var pageModePromise = pdfDocument.getPageMode().catch(function () {}); + this.toolbar.setPagesCount(pdfDocument.numPages, false); + this.secondaryToolbar.setPagesCount(pdfDocument.numPages); + var id = this.documentFingerprint = pdfDocument.fingerprint; + var store = this.store = new _view_history.ViewHistory(id); + var baseDocumentUrl = void 0; + baseDocumentUrl = null; + this.pdfLinkService.setDocument(pdfDocument, baseDocumentUrl); + this.pdfDocumentProperties.setDocument(pdfDocument, this.url); + var pdfViewer = this.pdfViewer; + pdfViewer.setDocument(pdfDocument); + var firstPagePromise = pdfViewer.firstPagePromise; + var pagesPromise = pdfViewer.pagesPromise; + var onePageRendered = pdfViewer.onePageRendered; + var pdfThumbnailViewer = this.pdfThumbnailViewer; + pdfThumbnailViewer.setDocument(pdfDocument); + firstPagePromise.then(function (pdfPage) { + _this6.loadingBar.setWidth(_this6.appConfig.viewerContainer); + if (!_pdfjsLib.PDFJS.disableHistory && !_this6.isViewerEmbedded) { + var resetHistory = !_this6.viewerPrefs['showPreviousViewOnLoad']; + _this6.pdfHistory.initialize(id, resetHistory); + if (_this6.pdfHistory.initialBookmark) { + _this6.initialBookmark = _this6.pdfHistory.initialBookmark; + _this6.initialRotation = _this6.pdfHistory.initialRotation; + } + } + var initialParams = { + bookmark: null, + hash: null + }; + var storePromise = store.getMultiple({ + exists: false, + page: '1', + zoom: _ui_utils.DEFAULT_SCALE_VALUE, + scrollLeft: '0', + scrollTop: '0', + rotation: null, + sidebarView: _pdf_sidebar.SidebarView.NONE + }).catch(function () {}); + Promise.all([storePromise, pageModePromise]).then(function (_ref2) { + var _ref3 = _slicedToArray(_ref2, 2), + _ref3$ = _ref3[0], + values = _ref3$ === undefined ? {} : _ref3$, + pageMode = _ref3[1]; + + var hash = _this6.viewerPrefs['defaultZoomValue'] ? 'zoom=' + _this6.viewerPrefs['defaultZoomValue'] : null; + var rotation = null; + var sidebarView = _this6.viewerPrefs['sidebarViewOnLoad']; + if (values.exists && _this6.viewerPrefs['showPreviousViewOnLoad']) { + hash = 'page=' + values.page + '&zoom=' + (_this6.viewerPrefs['defaultZoomValue'] || values.zoom) + ',' + values.scrollLeft + ',' + values.scrollTop; + rotation = parseInt(values.rotation, 10); + sidebarView = sidebarView || values.sidebarView | 0; + } + if (pageMode && !_this6.viewerPrefs['disablePageMode']) { + sidebarView = sidebarView || apiPageModeToSidebarView(pageMode); + } + return { + hash: hash, + rotation: rotation, + sidebarView: sidebarView + }; + }).then(function (_ref4) { + var hash = _ref4.hash, + rotation = _ref4.rotation, + sidebarView = _ref4.sidebarView; + + initialParams.bookmark = _this6.initialBookmark; + initialParams.hash = hash; + _this6.setInitialView(hash, { + rotation: rotation, + sidebarView: sidebarView + }); + if (!_this6.isViewerEmbedded) { + pdfViewer.focus(); + } + return pagesPromise; + }).then(function () { + if (!initialParams.bookmark && !initialParams.hash) { + return; + } + if (pdfViewer.hasEqualPageSizes) { + return; + } + _this6.initialBookmark = initialParams.bookmark; + pdfViewer.currentScaleValue = pdfViewer.currentScaleValue; + _this6.setInitialView(initialParams.hash); + }).then(function () { + pdfViewer.update(); + }); + }); + pdfDocument.getPageLabels().then(function (labels) { + if (!labels || _this6.viewerPrefs['disablePageLabels']) { + return; + } + var i = 0, + numLabels = labels.length; + if (numLabels !== _this6.pagesCount) { + console.error('The number of Page Labels does not match ' + 'the number of pages in the document.'); + return; + } + while (i < numLabels && labels[i] === (i + 1).toString()) { + i++; + } + if (i === numLabels) { + return; + } + pdfViewer.setPageLabels(labels); + pdfThumbnailViewer.setPageLabels(labels); + _this6.toolbar.setPagesCount(pdfDocument.numPages, true); + _this6.toolbar.setPageNumber(pdfViewer.currentPageNumber, pdfViewer.currentPageLabel); + }); + pagesPromise.then(function () { + if (!_this6.supportsPrinting) { + return; + } + pdfDocument.getJavaScript().then(function (javaScript) { + if (javaScript.length) { + console.warn('Warning: JavaScript is not supported'); + _this6.fallback(_pdfjsLib.UNSUPPORTED_FEATURES.javaScript); + } + var regex = /\bprint\s*\(/; + for (var i = 0, ii = javaScript.length; i < ii; i++) { + var js = javaScript[i]; + if (js && regex.test(js)) { + setTimeout(function () { + window.print(); + }); + return; + } + } + }); + }); + Promise.all([onePageRendered, _ui_utils.animationStarted]).then(function () { + pdfDocument.getOutline().then(function (outline) { + _this6.pdfOutlineViewer.render({ outline: outline }); + }); + pdfDocument.getAttachments().then(function (attachments) { + _this6.pdfAttachmentViewer.render({ attachments: attachments }); + }); + }); + pdfDocument.getMetadata().then(function (_ref5) { + var info = _ref5.info, + metadata = _ref5.metadata; + + _this6.documentInfo = info; + _this6.metadata = metadata; + console.log('PDF ' + pdfDocument.fingerprint + ' [' + info.PDFFormatVersion + ' ' + (info.Producer || '-').trim() + ' / ' + (info.Creator || '-').trim() + ']' + ' (PDF.js: ' + (_pdfjsLib.version || '-') + (!_pdfjsLib.PDFJS.disableWebGL ? ' [WebGL]' : '') + ')'); + var pdfTitle = void 0; + if (metadata && metadata.has('dc:title')) { + var title = metadata.get('dc:title'); + if (title !== 'Untitled') { + pdfTitle = title; + } + } + if (!pdfTitle && info && info['Title']) { + pdfTitle = info['Title']; + } + if (pdfTitle) { + _this6.setTitle(pdfTitle + ' - ' + document.title); + } + if (info.IsAcroFormPresent) { + console.warn('Warning: AcroForm/XFA is not supported'); + _this6.fallback(_pdfjsLib.UNSUPPORTED_FEATURES.forms); + } + }); + }, + setInitialView: function setInitialView(storedHash) { + var _this7 = this; + + var _ref6 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, + rotation = _ref6.rotation, + sidebarView = _ref6.sidebarView; + + var setRotation = function setRotation(angle) { + if ((0, _ui_utils.isValidRotation)(angle)) { + _this7.pdfViewer.pagesRotation = angle; + } + }; + this.isInitialViewSet = true; + this.pdfSidebar.setInitialView(sidebarView); + if (this.initialBookmark) { + setRotation(this.initialRotation); + delete this.initialRotation; + this.pdfLinkService.setHash(this.initialBookmark); + this.initialBookmark = null; + } else if (storedHash) { + setRotation(rotation); + this.pdfLinkService.setHash(storedHash); + } + this.toolbar.setPageNumber(this.pdfViewer.currentPageNumber, this.pdfViewer.currentPageLabel); + this.secondaryToolbar.setPageNumber(this.pdfViewer.currentPageNumber); + if (!this.pdfViewer.currentScaleValue) { + this.pdfViewer.currentScaleValue = _ui_utils.DEFAULT_SCALE_VALUE; + } + }, + cleanup: function cleanup() { + if (!this.pdfDocument) { + return; + } + this.pdfViewer.cleanup(); + this.pdfThumbnailViewer.cleanup(); + if (this.pdfViewer.renderer !== _ui_utils.RendererType.SVG) { + this.pdfDocument.cleanup(); + } + }, + forceRendering: function forceRendering() { + this.pdfRenderingQueue.printing = this.printing; + this.pdfRenderingQueue.isThumbnailViewEnabled = this.pdfSidebar.isThumbnailViewVisible; + this.pdfRenderingQueue.renderHighestPriority(); + }, + beforePrint: function beforePrint() { + var _this8 = this; + + if (this.printService) { + return; + } + if (!this.supportsPrinting) { + this.l10n.get('printing_not_supported', null, 'Warning: Printing is not fully supported by ' + 'this browser.').then(function (printMessage) { + _this8.error(printMessage); + }); + return; + } + if (!this.pdfViewer.pageViewsReady) { + this.l10n.get('printing_not_ready', null, 'Warning: The PDF is not fully loaded for printing.').then(function (notReadyMessage) { + window.alert(notReadyMessage); + }); + return; + } + var pagesOverview = this.pdfViewer.getPagesOverview(); + var printContainer = this.appConfig.printContainer; + var printService = PDFPrintServiceFactory.instance.createPrintService(this.pdfDocument, pagesOverview, printContainer, this.l10n); + this.printService = printService; + this.forceRendering(); + printService.layout(); + }, + + afterPrint: function pdfViewSetupAfterPrint() { + if (this.printService) { + this.printService.destroy(); + this.printService = null; + } + this.forceRendering(); + }, + rotatePages: function rotatePages(delta) { + if (!this.pdfDocument) { + return; + } + var newRotation = (this.pdfViewer.pagesRotation + 360 + delta) % 360; + this.pdfViewer.pagesRotation = newRotation; + }, + requestPresentationMode: function requestPresentationMode() { + if (!this.pdfPresentationMode) { + return; + } + this.pdfPresentationMode.request(); + }, + bindEvents: function bindEvents() { + var eventBus = this.eventBus, + _boundEvents = this._boundEvents; + + _boundEvents.beforePrint = this.beforePrint.bind(this); + _boundEvents.afterPrint = this.afterPrint.bind(this); + eventBus.on('resize', webViewerResize); + eventBus.on('hashchange', webViewerHashchange); + eventBus.on('beforeprint', _boundEvents.beforePrint); + eventBus.on('afterprint', _boundEvents.afterPrint); + eventBus.on('pagerendered', webViewerPageRendered); + eventBus.on('textlayerrendered', webViewerTextLayerRendered); + eventBus.on('updateviewarea', webViewerUpdateViewarea); + eventBus.on('pagechanging', webViewerPageChanging); + eventBus.on('scalechanging', webViewerScaleChanging); + eventBus.on('rotationchanging', webViewerRotationChanging); + eventBus.on('sidebarviewchanged', webViewerSidebarViewChanged); + eventBus.on('pagemode', webViewerPageMode); + eventBus.on('namedaction', webViewerNamedAction); + eventBus.on('presentationmodechanged', webViewerPresentationModeChanged); + eventBus.on('presentationmode', webViewerPresentationMode); + eventBus.on('openfile', webViewerOpenFile); + eventBus.on('print', webViewerPrint); + eventBus.on('download', webViewerDownload); + eventBus.on('firstpage', webViewerFirstPage); + eventBus.on('lastpage', webViewerLastPage); + eventBus.on('nextpage', webViewerNextPage); + eventBus.on('previouspage', webViewerPreviousPage); + eventBus.on('zoomin', webViewerZoomIn); + eventBus.on('zoomout', webViewerZoomOut); + eventBus.on('pagenumberchanged', webViewerPageNumberChanged); + eventBus.on('scalechanged', webViewerScaleChanged); + eventBus.on('rotatecw', webViewerRotateCw); + eventBus.on('rotateccw', webViewerRotateCcw); + eventBus.on('documentproperties', webViewerDocumentProperties); + eventBus.on('find', webViewerFind); + eventBus.on('findfromurlhash', webViewerFindFromUrlHash); + eventBus.on('fileinputchange', webViewerFileInputChange); + }, + bindWindowEvents: function bindWindowEvents() { + var eventBus = this.eventBus, + _boundEvents = this._boundEvents; + + _boundEvents.windowResize = function () { + eventBus.dispatch('resize'); + }; + _boundEvents.windowHashChange = function () { + eventBus.dispatch('hashchange', { hash: document.location.hash.substring(1) }); + }; + _boundEvents.windowBeforePrint = function () { + eventBus.dispatch('beforeprint'); + }; + _boundEvents.windowAfterPrint = function () { + eventBus.dispatch('afterprint'); + }; + window.addEventListener('wheel', webViewerWheel); + window.addEventListener('click', webViewerClick); + window.addEventListener('keydown', webViewerKeyDown); + window.addEventListener('resize', _boundEvents.windowResize); + window.addEventListener('hashchange', _boundEvents.windowHashChange); + window.addEventListener('beforeprint', _boundEvents.windowBeforePrint); + window.addEventListener('afterprint', _boundEvents.windowAfterPrint); + }, + unbindEvents: function unbindEvents() { + var eventBus = this.eventBus, + _boundEvents = this._boundEvents; + + eventBus.off('resize', webViewerResize); + eventBus.off('hashchange', webViewerHashchange); + eventBus.off('beforeprint', _boundEvents.beforePrint); + eventBus.off('afterprint', _boundEvents.afterPrint); + eventBus.off('pagerendered', webViewerPageRendered); + eventBus.off('textlayerrendered', webViewerTextLayerRendered); + eventBus.off('updateviewarea', webViewerUpdateViewarea); + eventBus.off('pagechanging', webViewerPageChanging); + eventBus.off('scalechanging', webViewerScaleChanging); + eventBus.off('rotationchanging', webViewerRotationChanging); + eventBus.off('sidebarviewchanged', webViewerSidebarViewChanged); + eventBus.off('pagemode', webViewerPageMode); + eventBus.off('namedaction', webViewerNamedAction); + eventBus.off('presentationmodechanged', webViewerPresentationModeChanged); + eventBus.off('presentationmode', webViewerPresentationMode); + eventBus.off('openfile', webViewerOpenFile); + eventBus.off('print', webViewerPrint); + eventBus.off('download', webViewerDownload); + eventBus.off('firstpage', webViewerFirstPage); + eventBus.off('lastpage', webViewerLastPage); + eventBus.off('nextpage', webViewerNextPage); + eventBus.off('previouspage', webViewerPreviousPage); + eventBus.off('zoomin', webViewerZoomIn); + eventBus.off('zoomout', webViewerZoomOut); + eventBus.off('pagenumberchanged', webViewerPageNumberChanged); + eventBus.off('scalechanged', webViewerScaleChanged); + eventBus.off('rotatecw', webViewerRotateCw); + eventBus.off('rotateccw', webViewerRotateCcw); + eventBus.off('documentproperties', webViewerDocumentProperties); + eventBus.off('find', webViewerFind); + eventBus.off('findfromurlhash', webViewerFindFromUrlHash); + eventBus.off('fileinputchange', webViewerFileInputChange); + _boundEvents.beforePrint = null; + _boundEvents.afterPrint = null; + }, + unbindWindowEvents: function unbindWindowEvents() { + var _boundEvents = this._boundEvents; + + window.removeEventListener('wheel', webViewerWheel); + window.removeEventListener('click', webViewerClick); + window.removeEventListener('keydown', webViewerKeyDown); + window.removeEventListener('resize', _boundEvents.windowResize); + window.removeEventListener('hashchange', _boundEvents.windowHashChange); + window.removeEventListener('beforeprint', _boundEvents.windowBeforePrint); + window.removeEventListener('afterprint', _boundEvents.windowAfterPrint); + _boundEvents.windowResize = null; + _boundEvents.windowHashChange = null; + _boundEvents.windowBeforePrint = null; + _boundEvents.windowAfterPrint = null; + } +}; +var validateFileURL = void 0; +{ + var HOSTED_VIEWER_ORIGINS = ['null', 'http://mozilla.github.io', 'https://mozilla.github.io']; + validateFileURL = function validateFileURL(file) { + if (file === undefined) { + return; + } + try { + var viewerOrigin = new URL(window.location.href).origin || 'null'; + if (HOSTED_VIEWER_ORIGINS.indexOf(viewerOrigin) >= 0) { + return; + } + var fileOrigin = new URL(file, window.location.href).origin; + if (fileOrigin !== viewerOrigin) { + throw new Error('file origin does not match viewer\'s'); + } + } catch (ex) { + var message = ex && ex.message; + PDFViewerApplication.l10n.get('loading_error', null, 'An error occurred while loading the PDF.').then(function (loadingErrorMessage) { + PDFViewerApplication.error(loadingErrorMessage, { message: message }); + }); + throw ex; + } + }; +} +function loadAndEnablePDFBug(enabledTabs) { + return new Promise(function (resolve, reject) { + var appConfig = PDFViewerApplication.appConfig; + var script = document.createElement('script'); + script.src = appConfig.debuggerScriptPath; + script.onload = function () { + PDFBug.enable(enabledTabs); + PDFBug.init({ + PDFJS: _pdfjsLib.PDFJS, + OPS: _pdfjsLib.OPS + }, appConfig.mainContainer); + resolve(); + }; + script.onerror = function () { + reject(new Error('Cannot load debugger at ' + script.src)); + }; + (document.getElementsByTagName('head')[0] || document.body).appendChild(script); + }); +} +function webViewerInitialized() { + var appConfig = PDFViewerApplication.appConfig; + var file = void 0; + var queryString = document.location.search.substring(1); + var params = (0, _ui_utils.parseQueryString)(queryString); + file = 'file' in params ? params.file : appConfig.defaultUrl; + validateFileURL(file); + var waitForBeforeOpening = []; + var fileInput = document.createElement('input'); + fileInput.id = appConfig.openFileInputName; + fileInput.className = 'fileInput'; + fileInput.setAttribute('type', 'file'); + fileInput.oncontextmenu = _ui_utils.noContextMenuHandler; + document.body.appendChild(fileInput); + if (!window.File || !window.FileReader || !window.FileList || !window.Blob) { + appConfig.toolbar.openFile.setAttribute('hidden', 'true'); + appConfig.secondaryToolbar.openFileButton.setAttribute('hidden', 'true'); + } else { + fileInput.value = null; + } + fileInput.addEventListener('change', function (evt) { + var files = evt.target.files; + if (!files || files.length === 0) { + return; + } + PDFViewerApplication.eventBus.dispatch('fileinputchange', { fileInput: evt.target }); + }); + if (PDFViewerApplication.viewerPrefs['pdfBugEnabled']) { + var hash = document.location.hash.substring(1); + var hashParams = (0, _ui_utils.parseQueryString)(hash); + if ('disableworker' in hashParams) { + _pdfjsLib.PDFJS.disableWorker = hashParams['disableworker'] === 'true'; + } + if ('disablerange' in hashParams) { + _pdfjsLib.PDFJS.disableRange = hashParams['disablerange'] === 'true'; + } + if ('disablestream' in hashParams) { + _pdfjsLib.PDFJS.disableStream = hashParams['disablestream'] === 'true'; + } + if ('disableautofetch' in hashParams) { + _pdfjsLib.PDFJS.disableAutoFetch = hashParams['disableautofetch'] === 'true'; + } + if ('disablefontface' in hashParams) { + _pdfjsLib.PDFJS.disableFontFace = hashParams['disablefontface'] === 'true'; + } + if ('disablehistory' in hashParams) { + _pdfjsLib.PDFJS.disableHistory = hashParams['disablehistory'] === 'true'; + } + if ('webgl' in hashParams) { + _pdfjsLib.PDFJS.disableWebGL = hashParams['webgl'] !== 'true'; + } + if ('useonlycsszoom' in hashParams) { + _pdfjsLib.PDFJS.useOnlyCssZoom = hashParams['useonlycsszoom'] === 'true'; + } + if ('verbosity' in hashParams) { + _pdfjsLib.PDFJS.verbosity = hashParams['verbosity'] | 0; + } + if ('ignorecurrentpositiononzoom' in hashParams) { + _pdfjsLib.PDFJS.ignoreCurrentPositionOnZoom = hashParams['ignorecurrentpositiononzoom'] === 'true'; + } + if ('textlayer' in hashParams) { + switch (hashParams['textlayer']) { + case 'off': + _pdfjsLib.PDFJS.disableTextLayer = true; + break; + case 'visible': + case 'shadow': + case 'hover': + var viewer = appConfig.viewerContainer; + viewer.classList.add('textLayer-' + hashParams['textlayer']); + break; + } + } + if ('pdfbug' in hashParams) { + _pdfjsLib.PDFJS.pdfBug = true; + var pdfBug = hashParams['pdfbug']; + var enabled = pdfBug.split(','); + waitForBeforeOpening.push(loadAndEnablePDFBug(enabled)); + } + } + if (!PDFViewerApplication.supportsPrinting) { + appConfig.toolbar.print.classList.add('hidden'); + appConfig.secondaryToolbar.printButton.classList.add('hidden'); + } + if (!PDFViewerApplication.supportsFullscreen) { + appConfig.toolbar.presentationModeButton.classList.add('hidden'); + appConfig.secondaryToolbar.presentationModeButton.classList.add('hidden'); + } + if (PDFViewerApplication.supportsIntegratedFind) { + appConfig.toolbar.viewFind.classList.add('hidden'); + } + appConfig.sidebar.mainContainer.addEventListener('transitionend', function (evt) { + if (evt.target === this) { + PDFViewerApplication.eventBus.dispatch('resize'); + } + }, true); + appConfig.sidebar.toggleButton.addEventListener('click', function () { + PDFViewerApplication.pdfSidebar.toggle(); + }); + Promise.all(waitForBeforeOpening).then(function () { + webViewerOpenFileViaURL(file); + }).catch(function (reason) { + PDFViewerApplication.l10n.get('loading_error', null, 'An error occurred while opening.').then(function (msg) { + PDFViewerApplication.error(msg, reason); + }); + }); +} +var webViewerOpenFileViaURL = void 0; +{ + webViewerOpenFileViaURL = function webViewerOpenFileViaURL(file) { + if (file && file.lastIndexOf('file:', 0) === 0) { + PDFViewerApplication.setTitleUsingUrl(file); + var xhr = new XMLHttpRequest(); + xhr.onload = function () { + PDFViewerApplication.open(new Uint8Array(xhr.response)); + }; + try { + xhr.open('GET', file); + xhr.responseType = 'arraybuffer'; + xhr.send(); + } catch (ex) { + PDFViewerApplication.l10n.get('loading_error', null, 'An error occurred while loading the PDF.').then(function (msg) { + PDFViewerApplication.error(msg, ex); + }); + } + return; + } + if (file) { + PDFViewerApplication.open(file); + } + }; +} +function webViewerPageRendered(evt) { + var pageNumber = evt.pageNumber; + var pageIndex = pageNumber - 1; + var pageView = PDFViewerApplication.pdfViewer.getPageView(pageIndex); + if (pageNumber === PDFViewerApplication.page) { + PDFViewerApplication.toolbar.updateLoadingIndicatorState(false); + } + if (!pageView) { + return; + } + if (PDFViewerApplication.pdfSidebar.isThumbnailViewVisible) { + var thumbnailView = PDFViewerApplication.pdfThumbnailViewer.getThumbnail(pageIndex); + thumbnailView.setImage(pageView); + } + if (_pdfjsLib.PDFJS.pdfBug && Stats.enabled && pageView.stats) { + Stats.add(pageNumber, pageView.stats); + } + if (pageView.error) { + PDFViewerApplication.l10n.get('rendering_error', null, 'An error occurred while rendering the page.').then(function (msg) { + PDFViewerApplication.error(msg, pageView.error); + }); + } +} +function webViewerTextLayerRendered(evt) {} +function webViewerPageMode(evt) { + var mode = evt.mode, + view = void 0; + switch (mode) { + case 'thumbs': + view = _pdf_sidebar.SidebarView.THUMBS; + break; + case 'bookmarks': + case 'outline': + view = _pdf_sidebar.SidebarView.OUTLINE; + break; + case 'attachments': + view = _pdf_sidebar.SidebarView.ATTACHMENTS; + break; + case 'none': + view = _pdf_sidebar.SidebarView.NONE; + break; + default: + console.error('Invalid "pagemode" hash parameter: ' + mode); + return; + } + PDFViewerApplication.pdfSidebar.switchView(view, true); +} +function webViewerNamedAction(evt) { + var action = evt.action; + switch (action) { + case 'GoToPage': + PDFViewerApplication.appConfig.toolbar.pageNumber.select(); + break; + case 'Find': + if (!PDFViewerApplication.supportsIntegratedFind) { + PDFViewerApplication.findBar.toggle(); + } + break; + } +} +function webViewerPresentationModeChanged(evt) { + var active = evt.active, + switchInProgress = evt.switchInProgress; + + PDFViewerApplication.pdfViewer.presentationModeState = switchInProgress ? _ui_utils.PresentationModeState.CHANGING : active ? _ui_utils.PresentationModeState.FULLSCREEN : _ui_utils.PresentationModeState.NORMAL; +} +function webViewerSidebarViewChanged(evt) { + PDFViewerApplication.pdfRenderingQueue.isThumbnailViewEnabled = PDFViewerApplication.pdfSidebar.isThumbnailViewVisible; + var store = PDFViewerApplication.store; + if (store && PDFViewerApplication.isInitialViewSet) { + store.set('sidebarView', evt.view).catch(function () {}); + } +} +function webViewerUpdateViewarea(evt) { + var location = evt.location, + store = PDFViewerApplication.store; + if (store && PDFViewerApplication.isInitialViewSet) { + store.setMultiple({ + 'exists': true, + 'page': location.pageNumber, + 'zoom': location.scale, + 'scrollLeft': location.left, + 'scrollTop': location.top, + 'rotation': location.rotation + }).catch(function () {}); + } + var href = PDFViewerApplication.pdfLinkService.getAnchorUrl(location.pdfOpenParams); + PDFViewerApplication.appConfig.toolbar.viewBookmark.href = href; + PDFViewerApplication.appConfig.secondaryToolbar.viewBookmarkButton.href = href; + var currentPage = PDFViewerApplication.pdfViewer.getPageView(PDFViewerApplication.page - 1); + var loading = currentPage.renderingState !== _pdf_rendering_queue.RenderingStates.FINISHED; + PDFViewerApplication.toolbar.updateLoadingIndicatorState(loading); +} +function webViewerResize() { + var pdfDocument = PDFViewerApplication.pdfDocument, + pdfViewer = PDFViewerApplication.pdfViewer; + + if (!pdfDocument) { + return; + } + var currentScaleValue = pdfViewer.currentScaleValue; + if (currentScaleValue === 'auto' || currentScaleValue === 'page-fit' || currentScaleValue === 'page-width') { + pdfViewer.currentScaleValue = currentScaleValue; + } + pdfViewer.update(); +} +function webViewerHashchange(evt) { + var hash = evt.hash; + if (!hash) { + return; + } + if (!PDFViewerApplication.isInitialViewSet) { + PDFViewerApplication.initialBookmark = hash; + } else if (!PDFViewerApplication.pdfHistory.popStateInProgress) { + PDFViewerApplication.pdfLinkService.setHash(hash); + } +} +var webViewerFileInputChange = void 0; +{ + webViewerFileInputChange = function webViewerFileInputChange(evt) { + var file = evt.fileInput.files[0]; + if (!_pdfjsLib.PDFJS.disableCreateObjectURL && URL.createObjectURL) { + PDFViewerApplication.open(URL.createObjectURL(file)); + } else { + var fileReader = new FileReader(); + fileReader.onload = function webViewerChangeFileReaderOnload(evt) { + var buffer = evt.target.result; + PDFViewerApplication.open(new Uint8Array(buffer)); + }; + fileReader.readAsArrayBuffer(file); + } + PDFViewerApplication.setTitleUsingUrl(file.name); + var appConfig = PDFViewerApplication.appConfig; + appConfig.toolbar.viewBookmark.setAttribute('hidden', 'true'); + appConfig.secondaryToolbar.viewBookmarkButton.setAttribute('hidden', 'true'); + appConfig.toolbar.download.setAttribute('hidden', 'true'); + appConfig.secondaryToolbar.downloadButton.setAttribute('hidden', 'true'); + }; +} +function webViewerPresentationMode() { + PDFViewerApplication.requestPresentationMode(); +} +function webViewerOpenFile() { + var openFileInputName = PDFViewerApplication.appConfig.openFileInputName; + document.getElementById(openFileInputName).click(); +} +function webViewerPrint() { + window.print(); +} +function webViewerDownload() { + PDFViewerApplication.download(); +} +function webViewerFirstPage() { + if (PDFViewerApplication.pdfDocument) { + PDFViewerApplication.page = 1; + } +} +function webViewerLastPage() { + if (PDFViewerApplication.pdfDocument) { + PDFViewerApplication.page = PDFViewerApplication.pagesCount; + } +} +function webViewerNextPage() { + PDFViewerApplication.page++; +} +function webViewerPreviousPage() { + PDFViewerApplication.page--; +} +function webViewerZoomIn() { + PDFViewerApplication.zoomIn(); +} +function webViewerZoomOut() { + PDFViewerApplication.zoomOut(); +} +function webViewerPageNumberChanged(evt) { + var pdfViewer = PDFViewerApplication.pdfViewer; + pdfViewer.currentPageLabel = evt.value; + if (evt.value !== pdfViewer.currentPageNumber.toString() && evt.value !== pdfViewer.currentPageLabel) { + PDFViewerApplication.toolbar.setPageNumber(pdfViewer.currentPageNumber, pdfViewer.currentPageLabel); + } +} +function webViewerScaleChanged(evt) { + PDFViewerApplication.pdfViewer.currentScaleValue = evt.value; +} +function webViewerRotateCw() { + PDFViewerApplication.rotatePages(90); +} +function webViewerRotateCcw() { + PDFViewerApplication.rotatePages(-90); +} +function webViewerDocumentProperties() { + PDFViewerApplication.pdfDocumentProperties.open(); +} +function webViewerFind(evt) { + PDFViewerApplication.findController.executeCommand('find' + evt.type, { + query: evt.query, + phraseSearch: evt.phraseSearch, + caseSensitive: evt.caseSensitive, + highlightAll: evt.highlightAll, + findPrevious: evt.findPrevious + }); +} +function webViewerFindFromUrlHash(evt) { + PDFViewerApplication.findController.executeCommand('find', { + query: evt.query, + phraseSearch: evt.phraseSearch, + caseSensitive: false, + highlightAll: true, + findPrevious: false + }); +} +function webViewerScaleChanging(evt) { + PDFViewerApplication.toolbar.setPageScale(evt.presetValue, evt.scale); + PDFViewerApplication.pdfViewer.update(); +} +function webViewerRotationChanging(evt) { + PDFViewerApplication.pdfThumbnailViewer.pagesRotation = evt.pagesRotation; + PDFViewerApplication.forceRendering(); + PDFViewerApplication.pdfViewer.currentPageNumber = evt.pageNumber; +} +function webViewerPageChanging(evt) { + var page = evt.pageNumber; + PDFViewerApplication.toolbar.setPageNumber(page, evt.pageLabel || null); + PDFViewerApplication.secondaryToolbar.setPageNumber(page); + if (PDFViewerApplication.pdfSidebar.isThumbnailViewVisible) { + PDFViewerApplication.pdfThumbnailViewer.scrollThumbnailIntoView(page); + } + if (_pdfjsLib.PDFJS.pdfBug && Stats.enabled) { + var pageView = PDFViewerApplication.pdfViewer.getPageView(page - 1); + if (pageView.stats) { + Stats.add(page, pageView.stats); + } + } +} +var zoomDisabled = false, + zoomDisabledTimeout = void 0; +function webViewerWheel(evt) { + var pdfViewer = PDFViewerApplication.pdfViewer; + if (pdfViewer.isInPresentationMode) { + return; + } + if (evt.ctrlKey || evt.metaKey) { + var support = PDFViewerApplication.supportedMouseWheelZoomModifierKeys; + if (evt.ctrlKey && !support.ctrlKey || evt.metaKey && !support.metaKey) { + return; + } + evt.preventDefault(); + if (zoomDisabled) { + return; + } + var previousScale = pdfViewer.currentScale; + var delta = (0, _ui_utils.normalizeWheelEventDelta)(evt); + var MOUSE_WHEEL_DELTA_PER_PAGE_SCALE = 3.0; + var ticks = delta * MOUSE_WHEEL_DELTA_PER_PAGE_SCALE; + if (ticks < 0) { + PDFViewerApplication.zoomOut(-ticks); + } else { + PDFViewerApplication.zoomIn(ticks); + } + var currentScale = pdfViewer.currentScale; + if (previousScale !== currentScale) { + var scaleCorrectionFactor = currentScale / previousScale - 1; + var rect = pdfViewer.container.getBoundingClientRect(); + var dx = evt.clientX - rect.left; + var dy = evt.clientY - rect.top; + pdfViewer.container.scrollLeft += dx * scaleCorrectionFactor; + pdfViewer.container.scrollTop += dy * scaleCorrectionFactor; + } + } else { + zoomDisabled = true; + clearTimeout(zoomDisabledTimeout); + zoomDisabledTimeout = setTimeout(function () { + zoomDisabled = false; + }, 1000); + } +} +function webViewerClick(evt) { + if (!PDFViewerApplication.secondaryToolbar.isOpen) { + return; + } + var appConfig = PDFViewerApplication.appConfig; + if (PDFViewerApplication.pdfViewer.containsElement(evt.target) || appConfig.toolbar.container.contains(evt.target) && evt.target !== appConfig.secondaryToolbar.toggleButton) { + PDFViewerApplication.secondaryToolbar.close(); + } +} +function webViewerKeyDown(evt) { + if (PDFViewerApplication.overlayManager.active) { + return; + } + var handled = false, + ensureViewerFocused = false; + var cmd = (evt.ctrlKey ? 1 : 0) | (evt.altKey ? 2 : 0) | (evt.shiftKey ? 4 : 0) | (evt.metaKey ? 8 : 0); + var pdfViewer = PDFViewerApplication.pdfViewer; + var isViewerInPresentationMode = pdfViewer && pdfViewer.isInPresentationMode; + if (cmd === 1 || cmd === 8 || cmd === 5 || cmd === 12) { + switch (evt.keyCode) { + case 70: + if (!PDFViewerApplication.supportsIntegratedFind) { + PDFViewerApplication.findBar.open(); + handled = true; + } + break; + case 71: + if (!PDFViewerApplication.supportsIntegratedFind) { + var findState = PDFViewerApplication.findController.state; + if (findState) { + PDFViewerApplication.findController.executeCommand('findagain', { + query: findState.query, + phraseSearch: findState.phraseSearch, + caseSensitive: findState.caseSensitive, + highlightAll: findState.highlightAll, + findPrevious: cmd === 5 || cmd === 12 + }); + } + handled = true; + } + break; + case 61: + case 107: + case 187: + case 171: + if (!isViewerInPresentationMode) { + PDFViewerApplication.zoomIn(); + } + handled = true; + break; + case 173: + case 109: + case 189: + if (!isViewerInPresentationMode) { + PDFViewerApplication.zoomOut(); + } + handled = true; + break; + case 48: + case 96: + if (!isViewerInPresentationMode) { + setTimeout(function () { + pdfViewer.currentScaleValue = _ui_utils.DEFAULT_SCALE_VALUE; + }); + handled = false; + } + break; + case 38: + if (isViewerInPresentationMode || PDFViewerApplication.page > 1) { + PDFViewerApplication.page = 1; + handled = true; + ensureViewerFocused = true; + } + break; + case 40: + if (isViewerInPresentationMode || PDFViewerApplication.page < PDFViewerApplication.pagesCount) { + PDFViewerApplication.page = PDFViewerApplication.pagesCount; + handled = true; + ensureViewerFocused = true; + } + break; + } + } + if (cmd === 1 || cmd === 8) { + switch (evt.keyCode) { + case 83: + PDFViewerApplication.download(); + handled = true; + break; + } + } + if (cmd === 3 || cmd === 10) { + switch (evt.keyCode) { + case 80: + PDFViewerApplication.requestPresentationMode(); + handled = true; + break; + case 71: + PDFViewerApplication.appConfig.toolbar.pageNumber.select(); + handled = true; + break; + } + } + if (handled) { + if (ensureViewerFocused && !isViewerInPresentationMode) { + pdfViewer.focus(); + } + evt.preventDefault(); + return; + } + var curElement = document.activeElement || document.querySelector(':focus'); + var curElementTagName = curElement && curElement.tagName.toUpperCase(); + if (curElementTagName === 'INPUT' || curElementTagName === 'TEXTAREA' || curElementTagName === 'SELECT') { + if (evt.keyCode !== 27) { + return; + } + } + if (cmd === 0) { + switch (evt.keyCode) { + case 38: + case 33: + case 8: + if (!isViewerInPresentationMode && pdfViewer.currentScaleValue !== 'page-fit') { + break; + } + case 37: + if (pdfViewer.isHorizontalScrollbarEnabled) { + break; + } + case 75: + case 80: + if (PDFViewerApplication.page > 1) { + PDFViewerApplication.page--; + } + handled = true; + break; + case 27: + if (PDFViewerApplication.secondaryToolbar.isOpen) { + PDFViewerApplication.secondaryToolbar.close(); + handled = true; + } + if (!PDFViewerApplication.supportsIntegratedFind && PDFViewerApplication.findBar.opened) { + PDFViewerApplication.findBar.close(); + handled = true; + } + break; + case 40: + case 34: + case 32: + if (!isViewerInPresentationMode && pdfViewer.currentScaleValue !== 'page-fit') { + break; + } + case 39: + if (pdfViewer.isHorizontalScrollbarEnabled) { + break; + } + case 74: + case 78: + if (PDFViewerApplication.page < PDFViewerApplication.pagesCount) { + PDFViewerApplication.page++; + } + handled = true; + break; + case 36: + if (isViewerInPresentationMode || PDFViewerApplication.page > 1) { + PDFViewerApplication.page = 1; + handled = true; + ensureViewerFocused = true; + } + break; + case 35: + if (isViewerInPresentationMode || PDFViewerApplication.page < PDFViewerApplication.pagesCount) { + PDFViewerApplication.page = PDFViewerApplication.pagesCount; + handled = true; + ensureViewerFocused = true; + } + break; + case 83: + PDFViewerApplication.pdfCursorTools.switchTool(_pdf_cursor_tools.CursorTool.SELECT); + break; + case 72: + PDFViewerApplication.pdfCursorTools.switchTool(_pdf_cursor_tools.CursorTool.HAND); + break; + case 82: + PDFViewerApplication.rotatePages(90); + break; + } + } + if (cmd === 4) { + switch (evt.keyCode) { + case 32: + if (!isViewerInPresentationMode && pdfViewer.currentScaleValue !== 'page-fit') { + break; + } + if (PDFViewerApplication.page > 1) { + PDFViewerApplication.page--; + } + handled = true; + break; + case 82: + PDFViewerApplication.rotatePages(-90); + break; + } + } + if (!handled && !isViewerInPresentationMode) { + if (evt.keyCode >= 33 && evt.keyCode <= 40 || evt.keyCode === 32 && curElementTagName !== 'BUTTON') { + ensureViewerFocused = true; + } + } + if (ensureViewerFocused && !pdfViewer.containsElement(curElement)) { + pdfViewer.focus(); + } + if (handled) { + evt.preventDefault(); + } +} +function apiPageModeToSidebarView(mode) { + switch (mode) { + case 'UseNone': + return _pdf_sidebar.SidebarView.NONE; + case 'UseThumbs': + return _pdf_sidebar.SidebarView.THUMBS; + case 'UseOutlines': + return _pdf_sidebar.SidebarView.OUTLINE; + case 'UseAttachments': + return _pdf_sidebar.SidebarView.ATTACHMENTS; + case 'UseOC': + } + return _pdf_sidebar.SidebarView.NONE; +} +var PDFPrintServiceFactory = { + instance: { + supportsPrinting: false, + createPrintService: function createPrintService() { + throw new Error('Not implemented: createPrintService'); + } + } +}; +exports.PDFViewerApplication = PDFViewerApplication; +exports.DefaultExternalServices = DefaultExternalServices; +exports.PDFPrintServiceFactory = PDFPrintServiceFactory; + +/***/ }), +/* 5 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.SimpleLinkService = exports.PDFLinkService = undefined; + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _dom_events = __webpack_require__(2); + +var _ui_utils = __webpack_require__(0); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var PDFLinkService = function () { + function PDFLinkService() { + var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, + eventBus = _ref.eventBus; + + _classCallCheck(this, PDFLinkService); + + this.eventBus = eventBus || (0, _dom_events.getGlobalEventBus)(); + this.baseUrl = null; + this.pdfDocument = null; + this.pdfViewer = null; + this.pdfHistory = null; + this._pagesRefCache = null; + } + + _createClass(PDFLinkService, [{ + key: 'setDocument', + value: function setDocument(pdfDocument, baseUrl) { + this.baseUrl = baseUrl; + this.pdfDocument = pdfDocument; + this._pagesRefCache = Object.create(null); + } + }, { + key: 'setViewer', + value: function setViewer(pdfViewer) { + this.pdfViewer = pdfViewer; + } + }, { + key: 'setHistory', + value: function setHistory(pdfHistory) { + this.pdfHistory = pdfHistory; + } + }, { + key: 'navigateTo', + value: function navigateTo(dest) { + var _this = this; + + var goToDestination = function goToDestination(_ref2) { + var namedDest = _ref2.namedDest, + explicitDest = _ref2.explicitDest; + + var destRef = explicitDest[0], + pageNumber = void 0; + if (destRef instanceof Object) { + pageNumber = _this._cachedPageNumber(destRef); + if (pageNumber === null) { + _this.pdfDocument.getPageIndex(destRef).then(function (pageIndex) { + _this.cachePageRef(pageIndex + 1, destRef); + goToDestination({ + namedDest: namedDest, + explicitDest: explicitDest + }); + }).catch(function () { + console.error('PDFLinkService.navigateTo: "' + destRef + '" is not ' + ('a valid page reference, for dest="' + dest + '".')); + }); + return; + } + } else if (Number.isInteger(destRef)) { + pageNumber = destRef + 1; + } else { + console.error('PDFLinkService.navigateTo: "' + destRef + '" is not ' + ('a valid destination reference, for dest="' + dest + '".')); + return; + } + if (!pageNumber || pageNumber < 1 || pageNumber > _this.pagesCount) { + console.error('PDFLinkService.navigateTo: "' + pageNumber + '" is not ' + ('a valid page number, for dest="' + dest + '".')); + return; + } + if (_this.pdfHistory) { + _this.pdfHistory.pushCurrentPosition(); + _this.pdfHistory.push({ + namedDest: namedDest, + explicitDest: explicitDest, + pageNumber: pageNumber + }); + } + _this.pdfViewer.scrollPageIntoView({ + pageNumber: pageNumber, + destArray: explicitDest + }); + }; + new Promise(function (resolve, reject) { + if (typeof dest === 'string') { + _this.pdfDocument.getDestination(dest).then(function (destArray) { + resolve({ + namedDest: dest, + explicitDest: destArray + }); + }); + return; + } + resolve({ + namedDest: '', + explicitDest: dest + }); + }).then(function (data) { + if (!(data.explicitDest instanceof Array)) { + console.error('PDFLinkService.navigateTo: "' + data.explicitDest + '" is' + (' not a valid destination array, for dest="' + dest + '".')); + return; + } + goToDestination(data); + }); + } + }, { + key: 'getDestinationHash', + value: function getDestinationHash(dest) { + if (typeof dest === 'string') { + return this.getAnchorUrl('#' + escape(dest)); + } + if (dest instanceof Array) { + var str = JSON.stringify(dest); + return this.getAnchorUrl('#' + escape(str)); + } + return this.getAnchorUrl(''); + } + }, { + key: 'getAnchorUrl', + value: function getAnchorUrl(anchor) { + return (this.baseUrl || '') + anchor; + } + }, { + key: 'setHash', + value: function setHash(hash) { + var pageNumber = void 0, + dest = void 0; + if (hash.indexOf('=') >= 0) { + var params = (0, _ui_utils.parseQueryString)(hash); + if ('search' in params) { + this.eventBus.dispatch('findfromurlhash', { + source: this, + query: params['search'].replace(/"/g, ''), + phraseSearch: params['phrase'] === 'true' + }); + } + if ('nameddest' in params) { + this.navigateTo(params.nameddest); + return; + } + if ('page' in params) { + pageNumber = params.page | 0 || 1; + } + if ('zoom' in params) { + var zoomArgs = params.zoom.split(','); + var zoomArg = zoomArgs[0]; + var zoomArgNumber = parseFloat(zoomArg); + if (zoomArg.indexOf('Fit') === -1) { + dest = [null, { name: 'XYZ' }, zoomArgs.length > 1 ? zoomArgs[1] | 0 : null, zoomArgs.length > 2 ? zoomArgs[2] | 0 : null, zoomArgNumber ? zoomArgNumber / 100 : zoomArg]; + } else { + if (zoomArg === 'Fit' || zoomArg === 'FitB') { + dest = [null, { name: zoomArg }]; + } else if (zoomArg === 'FitH' || zoomArg === 'FitBH' || zoomArg === 'FitV' || zoomArg === 'FitBV') { + dest = [null, { name: zoomArg }, zoomArgs.length > 1 ? zoomArgs[1] | 0 : null]; + } else if (zoomArg === 'FitR') { + if (zoomArgs.length !== 5) { + console.error('PDFLinkService.setHash: Not enough parameters for "FitR".'); + } else { + dest = [null, { name: zoomArg }, zoomArgs[1] | 0, zoomArgs[2] | 0, zoomArgs[3] | 0, zoomArgs[4] | 0]; + } + } else { + console.error('PDFLinkService.setHash: "' + zoomArg + '" is not ' + 'a valid zoom value.'); + } + } + } + if (dest) { + this.pdfViewer.scrollPageIntoView({ + pageNumber: pageNumber || this.page, + destArray: dest, + allowNegativeOffset: true + }); + } else if (pageNumber) { + this.page = pageNumber; + } + if ('pagemode' in params) { + this.eventBus.dispatch('pagemode', { + source: this, + mode: params.pagemode + }); + } + } else { + if (/^\d+$/.test(hash) && hash <= this.pagesCount) { + console.warn('PDFLinkService_setHash: specifying a page number ' + 'directly after the hash symbol (#) is deprecated, ' + ('please use the "#page=' + hash + '" form instead.')); + this.page = hash | 0; + } + dest = unescape(hash); + try { + dest = JSON.parse(dest); + if (!(dest instanceof Array)) { + dest = dest.toString(); + } + } catch (ex) {} + if (typeof dest === 'string' || isValidExplicitDestination(dest)) { + this.navigateTo(dest); + return; + } + console.error('PDFLinkService.setHash: "' + unescape(hash) + '" is not ' + 'a valid destination.'); + } + } + }, { + key: 'executeNamedAction', + value: function executeNamedAction(action) { + switch (action) { + case 'GoBack': + if (this.pdfHistory) { + this.pdfHistory.back(); + } + break; + case 'GoForward': + if (this.pdfHistory) { + this.pdfHistory.forward(); + } + break; + case 'NextPage': + if (this.page < this.pagesCount) { + this.page++; + } + break; + case 'PrevPage': + if (this.page > 1) { + this.page--; + } + break; + case 'LastPage': + this.page = this.pagesCount; + break; + case 'FirstPage': + this.page = 1; + break; + default: + break; + } + this.eventBus.dispatch('namedaction', { + source: this, + action: action + }); + } + }, { + key: 'onFileAttachmentAnnotation', + value: function onFileAttachmentAnnotation(_ref3) { + var id = _ref3.id, + filename = _ref3.filename, + content = _ref3.content; + + this.eventBus.dispatch('fileattachmentannotation', { + source: this, + id: id, + filename: filename, + content: content + }); + } + }, { + key: 'cachePageRef', + value: function cachePageRef(pageNum, pageRef) { + var refStr = pageRef.num + ' ' + pageRef.gen + ' R'; + this._pagesRefCache[refStr] = pageNum; + } + }, { + key: '_cachedPageNumber', + value: function _cachedPageNumber(pageRef) { + var refStr = pageRef.num + ' ' + pageRef.gen + ' R'; + return this._pagesRefCache && this._pagesRefCache[refStr] || null; + } + }, { + key: 'pagesCount', + get: function get() { + return this.pdfDocument ? this.pdfDocument.numPages : 0; + } + }, { + key: 'page', + get: function get() { + return this.pdfViewer.currentPageNumber; + }, + set: function set(value) { + this.pdfViewer.currentPageNumber = value; + } + }, { + key: 'rotation', + get: function get() { + return this.pdfViewer.pagesRotation; + }, + set: function set(value) { + this.pdfViewer.pagesRotation = value; + } + }]); + + return PDFLinkService; +}(); + +function isValidExplicitDestination(dest) { + if (!(dest instanceof Array)) { + return false; + } + var destLength = dest.length, + allowNull = true; + if (destLength < 2) { + return false; + } + var page = dest[0]; + if (!((typeof page === 'undefined' ? 'undefined' : _typeof(page)) === 'object' && Number.isInteger(page.num) && Number.isInteger(page.gen)) && !(Number.isInteger(page) && page >= 0)) { + return false; + } + var zoom = dest[1]; + if (!((typeof zoom === 'undefined' ? 'undefined' : _typeof(zoom)) === 'object' && typeof zoom.name === 'string')) { + return false; + } + switch (zoom.name) { + case 'XYZ': + if (destLength !== 5) { + return false; + } + break; + case 'Fit': + case 'FitB': + return destLength === 2; + case 'FitH': + case 'FitBH': + case 'FitV': + case 'FitBV': + if (destLength !== 3) { + return false; + } + break; + case 'FitR': + if (destLength !== 6) { + return false; + } + allowNull = false; + break; + default: + return false; + } + for (var i = 2; i < destLength; i++) { + var param = dest[i]; + if (!(typeof param === 'number' || allowNull && param === null)) { + return false; + } + } + return true; +} + +var SimpleLinkService = function () { + function SimpleLinkService() { + _classCallCheck(this, SimpleLinkService); + } + + _createClass(SimpleLinkService, [{ + key: 'navigateTo', + value: function navigateTo(dest) {} + }, { + key: 'getDestinationHash', + value: function getDestinationHash(dest) { + return '#'; + } + }, { + key: 'getAnchorUrl', + value: function getAnchorUrl(hash) { + return '#'; + } + }, { + key: 'setHash', + value: function setHash(hash) {} + }, { + key: 'executeNamedAction', + value: function executeNamedAction(action) {} + }, { + key: 'onFileAttachmentAnnotation', + value: function onFileAttachmentAnnotation(_ref4) { + var id = _ref4.id, + filename = _ref4.filename, + content = _ref4.content; + } + }, { + key: 'cachePageRef', + value: function cachePageRef(pageNum, pageRef) {} + }, { + key: 'page', + get: function get() { + return 0; + }, + set: function set(value) {} + }, { + key: 'rotation', + get: function get() { + return 0; + }, + set: function set(value) {} + }]); + + return SimpleLinkService; +}(); + +exports.PDFLinkService = PDFLinkService; +exports.SimpleLinkService = SimpleLinkService; + +/***/ }), +/* 6 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.PDFCursorTools = exports.CursorTool = undefined; + +var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _grab_to_pan = __webpack_require__(9); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var CursorTool = { + SELECT: 0, + HAND: 1, + ZOOM: 2 +}; + +var PDFCursorTools = function () { + function PDFCursorTools(_ref) { + var _this = this; + + var container = _ref.container, + eventBus = _ref.eventBus, + preferences = _ref.preferences; + + _classCallCheck(this, PDFCursorTools); + + this.container = container; + this.eventBus = eventBus; + this.active = CursorTool.SELECT; + this.activeBeforePresentationMode = null; + this.handTool = new _grab_to_pan.GrabToPan({ element: this.container }); + this._addEventListeners(); + Promise.all([preferences.get('cursorToolOnLoad'), preferences.get('enableHandToolOnLoad')]).then(function (_ref2) { + var _ref3 = _slicedToArray(_ref2, 2), + cursorToolPref = _ref3[0], + handToolPref = _ref3[1]; + + if (handToolPref === true) { + preferences.set('enableHandToolOnLoad', false); + if (cursorToolPref === CursorTool.SELECT) { + cursorToolPref = CursorTool.HAND; + preferences.set('cursorToolOnLoad', cursorToolPref).catch(function () {}); + } + } + _this.switchTool(cursorToolPref); + }).catch(function () {}); + } + + _createClass(PDFCursorTools, [{ + key: 'switchTool', + value: function switchTool(tool) { + var _this2 = this; + + if (this.activeBeforePresentationMode !== null) { + return; + } + if (tool === this.active) { + return; + } + var disableActiveTool = function disableActiveTool() { + switch (_this2.active) { + case CursorTool.SELECT: + break; + case CursorTool.HAND: + _this2.handTool.deactivate(); + break; + case CursorTool.ZOOM: + } + }; + switch (tool) { + case CursorTool.SELECT: + disableActiveTool(); + break; + case CursorTool.HAND: + disableActiveTool(); + this.handTool.activate(); + break; + case CursorTool.ZOOM: + default: + console.error('switchTool: "' + tool + '" is an unsupported value.'); + return; + } + this.active = tool; + this._dispatchEvent(); + } + }, { + key: '_dispatchEvent', + value: function _dispatchEvent() { + this.eventBus.dispatch('cursortoolchanged', { + source: this, + tool: this.active + }); + } + }, { + key: '_addEventListeners', + value: function _addEventListeners() { + var _this3 = this; + + this.eventBus.on('switchcursortool', function (evt) { + _this3.switchTool(evt.tool); + }); + this.eventBus.on('presentationmodechanged', function (evt) { + if (evt.switchInProgress) { + return; + } + var previouslyActive = void 0; + if (evt.active) { + previouslyActive = _this3.active; + _this3.switchTool(CursorTool.SELECT); + _this3.activeBeforePresentationMode = previouslyActive; + } else { + previouslyActive = _this3.activeBeforePresentationMode; + _this3.activeBeforePresentationMode = null; + _this3.switchTool(previouslyActive); + } + }); + } + }, { + key: 'activeTool', + get: function get() { + return this.active; + } + }]); + + return PDFCursorTools; +}(); + +exports.CursorTool = CursorTool; +exports.PDFCursorTools = PDFCursorTools; + +/***/ }), +/* 7 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.PDFFindController = exports.FindState = undefined; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _pdfjsLib = __webpack_require__(1); + +var _ui_utils = __webpack_require__(0); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var FindState = { + FOUND: 0, + NOT_FOUND: 1, + WRAPPED: 2, + PENDING: 3 +}; +var FIND_SCROLL_OFFSET_TOP = -50; +var FIND_SCROLL_OFFSET_LEFT = -400; +var FIND_TIMEOUT = 250; +var CHARACTERS_TO_NORMALIZE = { + '\u2018': '\'', + '\u2019': '\'', + '\u201A': '\'', + '\u201B': '\'', + '\u201C': '"', + '\u201D': '"', + '\u201E': '"', + '\u201F': '"', + '\xBC': '1/4', + '\xBD': '1/2', + '\xBE': '3/4' +}; + +var PDFFindController = function () { + function PDFFindController(_ref) { + var pdfViewer = _ref.pdfViewer; + + _classCallCheck(this, PDFFindController); + + this.pdfViewer = pdfViewer; + this.onUpdateResultsCount = null; + this.onUpdateState = null; + this.reset(); + var replace = Object.keys(CHARACTERS_TO_NORMALIZE).join(''); + this.normalizationRegex = new RegExp('[' + replace + ']', 'g'); + } + + _createClass(PDFFindController, [{ + key: 'reset', + value: function reset() { + var _this = this; + + this.startedTextExtraction = false; + this.extractTextPromises = []; + this.pendingFindMatches = Object.create(null); + this.active = false; + this.pageContents = []; + this.pageMatches = []; + this.pageMatchesLength = null; + this.matchCount = 0; + this.selected = { + pageIdx: -1, + matchIdx: -1 + }; + this.offset = { + pageIdx: null, + matchIdx: null + }; + this.pagesToSearch = null; + this.resumePageIdx = null; + this.state = null; + this.dirtyMatch = false; + this.findTimeout = null; + this._firstPagePromise = new Promise(function (resolve) { + _this.resolveFirstPage = resolve; + }); + } + }, { + key: 'normalize', + value: function normalize(text) { + return text.replace(this.normalizationRegex, function (ch) { + return CHARACTERS_TO_NORMALIZE[ch]; + }); + } + }, { + key: '_prepareMatches', + value: function _prepareMatches(matchesWithLength, matches, matchesLength) { + function isSubTerm(matchesWithLength, currentIndex) { + var currentElem = matchesWithLength[currentIndex]; + var nextElem = matchesWithLength[currentIndex + 1]; + if (currentIndex < matchesWithLength.length - 1 && currentElem.match === nextElem.match) { + currentElem.skipped = true; + return true; + } + for (var i = currentIndex - 1; i >= 0; i--) { + var prevElem = matchesWithLength[i]; + if (prevElem.skipped) { + continue; + } + if (prevElem.match + prevElem.matchLength < currentElem.match) { + break; + } + if (prevElem.match + prevElem.matchLength >= currentElem.match + currentElem.matchLength) { + currentElem.skipped = true; + return true; + } + } + return false; + } + matchesWithLength.sort(function (a, b) { + return a.match === b.match ? a.matchLength - b.matchLength : a.match - b.match; + }); + for (var i = 0, len = matchesWithLength.length; i < len; i++) { + if (isSubTerm(matchesWithLength, i)) { + continue; + } + matches.push(matchesWithLength[i].match); + matchesLength.push(matchesWithLength[i].matchLength); + } + } + }, { + key: 'calcFindPhraseMatch', + value: function calcFindPhraseMatch(query, pageIndex, pageContent) { + var matches = []; + var queryLen = query.length; + var matchIdx = -queryLen; + while (true) { + matchIdx = pageContent.indexOf(query, matchIdx + queryLen); + if (matchIdx === -1) { + break; + } + matches.push(matchIdx); + } + this.pageMatches[pageIndex] = matches; + } + }, { + key: 'calcFindWordMatch', + value: function calcFindWordMatch(query, pageIndex, pageContent) { + var matchesWithLength = []; + var queryArray = query.match(/\S+/g); + for (var i = 0, len = queryArray.length; i < len; i++) { + var subquery = queryArray[i]; + var subqueryLen = subquery.length; + var matchIdx = -subqueryLen; + while (true) { + matchIdx = pageContent.indexOf(subquery, matchIdx + subqueryLen); + if (matchIdx === -1) { + break; + } + matchesWithLength.push({ + match: matchIdx, + matchLength: subqueryLen, + skipped: false + }); + } + } + if (!this.pageMatchesLength) { + this.pageMatchesLength = []; + } + this.pageMatchesLength[pageIndex] = []; + this.pageMatches[pageIndex] = []; + this._prepareMatches(matchesWithLength, this.pageMatches[pageIndex], this.pageMatchesLength[pageIndex]); + } + }, { + key: 'calcFindMatch', + value: function calcFindMatch(pageIndex) { + var pageContent = this.normalize(this.pageContents[pageIndex]); + var query = this.normalize(this.state.query); + var caseSensitive = this.state.caseSensitive; + var phraseSearch = this.state.phraseSearch; + var queryLen = query.length; + if (queryLen === 0) { + return; + } + if (!caseSensitive) { + pageContent = pageContent.toLowerCase(); + query = query.toLowerCase(); + } + if (phraseSearch) { + this.calcFindPhraseMatch(query, pageIndex, pageContent); + } else { + this.calcFindWordMatch(query, pageIndex, pageContent); + } + this.updatePage(pageIndex); + if (this.resumePageIdx === pageIndex) { + this.resumePageIdx = null; + this.nextPageMatch(); + } + if (this.pageMatches[pageIndex].length > 0) { + this.matchCount += this.pageMatches[pageIndex].length; + this.updateUIResultsCount(); + } + } + }, { + key: 'extractText', + value: function extractText() { + var _this2 = this; + + if (this.startedTextExtraction) { + return; + } + this.startedTextExtraction = true; + this.pageContents.length = 0; + var promise = Promise.resolve(); + + var _loop = function _loop(i, ii) { + var extractTextCapability = (0, _pdfjsLib.createPromiseCapability)(); + _this2.extractTextPromises[i] = extractTextCapability.promise; + promise = promise.then(function () { + return _this2.pdfViewer.getPageTextContent(i).then(function (textContent) { + var textItems = textContent.items; + var strBuf = []; + for (var j = 0, jj = textItems.length; j < jj; j++) { + strBuf.push(textItems[j].str); + } + _this2.pageContents[i] = strBuf.join(''); + extractTextCapability.resolve(i); + }, function (reason) { + console.error('Unable to get page ' + (i + 1) + ' text content', reason); + _this2.pageContents[i] = ''; + extractTextCapability.resolve(i); + }); + }); + }; + + for (var i = 0, ii = this.pdfViewer.pagesCount; i < ii; i++) { + _loop(i, ii); + } + } + }, { + key: 'executeCommand', + value: function executeCommand(cmd, state) { + var _this3 = this; + + if (this.state === null || cmd !== 'findagain') { + this.dirtyMatch = true; + } + this.state = state; + this.updateUIState(FindState.PENDING); + this._firstPagePromise.then(function () { + _this3.extractText(); + clearTimeout(_this3.findTimeout); + if (cmd === 'find') { + _this3.findTimeout = setTimeout(_this3.nextMatch.bind(_this3), FIND_TIMEOUT); + } else { + _this3.nextMatch(); + } + }); + } + }, { + key: 'updatePage', + value: function updatePage(index) { + if (this.selected.pageIdx === index) { + this.pdfViewer.currentPageNumber = index + 1; + } + var page = this.pdfViewer.getPageView(index); + if (page.textLayer) { + page.textLayer.updateMatches(); + } + } + }, { + key: 'nextMatch', + value: function nextMatch() { + var _this4 = this; + + var previous = this.state.findPrevious; + var currentPageIndex = this.pdfViewer.currentPageNumber - 1; + var numPages = this.pdfViewer.pagesCount; + this.active = true; + if (this.dirtyMatch) { + this.dirtyMatch = false; + this.selected.pageIdx = this.selected.matchIdx = -1; + this.offset.pageIdx = currentPageIndex; + this.offset.matchIdx = null; + this.hadMatch = false; + this.resumePageIdx = null; + this.pageMatches = []; + this.matchCount = 0; + this.pageMatchesLength = null; + for (var i = 0; i < numPages; i++) { + this.updatePage(i); + if (!(i in this.pendingFindMatches)) { + this.pendingFindMatches[i] = true; + this.extractTextPromises[i].then(function (pageIdx) { + delete _this4.pendingFindMatches[pageIdx]; + _this4.calcFindMatch(pageIdx); + }); + } + } + } + if (this.state.query === '') { + this.updateUIState(FindState.FOUND); + return; + } + if (this.resumePageIdx) { + return; + } + var offset = this.offset; + this.pagesToSearch = numPages; + if (offset.matchIdx !== null) { + var numPageMatches = this.pageMatches[offset.pageIdx].length; + if (!previous && offset.matchIdx + 1 < numPageMatches || previous && offset.matchIdx > 0) { + this.hadMatch = true; + offset.matchIdx = previous ? offset.matchIdx - 1 : offset.matchIdx + 1; + this.updateMatch(true); + return; + } + this.advanceOffsetPage(previous); + } + this.nextPageMatch(); + } + }, { + key: 'matchesReady', + value: function matchesReady(matches) { + var offset = this.offset; + var numMatches = matches.length; + var previous = this.state.findPrevious; + if (numMatches) { + this.hadMatch = true; + offset.matchIdx = previous ? numMatches - 1 : 0; + this.updateMatch(true); + return true; + } + this.advanceOffsetPage(previous); + if (offset.wrapped) { + offset.matchIdx = null; + if (this.pagesToSearch < 0) { + this.updateMatch(false); + return true; + } + } + return false; + } + }, { + key: 'updateMatchPosition', + value: function updateMatchPosition(pageIndex, matchIndex, elements, beginIdx) { + if (this.selected.matchIdx === matchIndex && this.selected.pageIdx === pageIndex) { + var spot = { + top: FIND_SCROLL_OFFSET_TOP, + left: FIND_SCROLL_OFFSET_LEFT + }; + (0, _ui_utils.scrollIntoView)(elements[beginIdx], spot, true); + } + } + }, { + key: 'nextPageMatch', + value: function nextPageMatch() { + if (this.resumePageIdx !== null) { + console.error('There can only be one pending page.'); + } + var matches = null; + do { + var pageIdx = this.offset.pageIdx; + matches = this.pageMatches[pageIdx]; + if (!matches) { + this.resumePageIdx = pageIdx; + break; + } + } while (!this.matchesReady(matches)); + } + }, { + key: 'advanceOffsetPage', + value: function advanceOffsetPage(previous) { + var offset = this.offset; + var numPages = this.extractTextPromises.length; + offset.pageIdx = previous ? offset.pageIdx - 1 : offset.pageIdx + 1; + offset.matchIdx = null; + this.pagesToSearch--; + if (offset.pageIdx >= numPages || offset.pageIdx < 0) { + offset.pageIdx = previous ? numPages - 1 : 0; + offset.wrapped = true; + } + } + }, { + key: 'updateMatch', + value: function updateMatch() { + var found = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + + var state = FindState.NOT_FOUND; + var wrapped = this.offset.wrapped; + this.offset.wrapped = false; + if (found) { + var previousPage = this.selected.pageIdx; + this.selected.pageIdx = this.offset.pageIdx; + this.selected.matchIdx = this.offset.matchIdx; + state = wrapped ? FindState.WRAPPED : FindState.FOUND; + if (previousPage !== -1 && previousPage !== this.selected.pageIdx) { + this.updatePage(previousPage); + } + } + this.updateUIState(state, this.state.findPrevious); + if (this.selected.pageIdx !== -1) { + this.updatePage(this.selected.pageIdx); + } + } + }, { + key: 'updateUIResultsCount', + value: function updateUIResultsCount() { + if (this.onUpdateResultsCount) { + this.onUpdateResultsCount(this.matchCount); + } + } + }, { + key: 'updateUIState', + value: function updateUIState(state, previous) { + if (this.onUpdateState) { + this.onUpdateState(state, previous, this.matchCount); + } + } + }]); + + return PDFFindController; +}(); + +exports.FindState = FindState; +exports.PDFFindController = PDFFindController; + +/***/ }), +/* 8 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var DEFAULT_URL = 'compressed.tracemonkey-pldi-09.pdf'; +; +var pdfjsWebApp = void 0; +{ + pdfjsWebApp = __webpack_require__(4); +} +; +{ + __webpack_require__(29); +} +; +{ + __webpack_require__(34); +} +function getViewerConfiguration() { + return { + appContainer: document.body, + mainContainer: document.getElementById('viewerContainer'), + viewerContainer: document.getElementById('viewer'), + eventBus: null, + toolbar: { + container: document.getElementById('toolbarViewer'), + numPages: document.getElementById('numPages'), + pageNumber: document.getElementById('pageNumber'), + scaleSelectContainer: document.getElementById('scaleSelectContainer'), + scaleSelect: document.getElementById('scaleSelect'), + customScaleOption: document.getElementById('customScaleOption'), + previous: document.getElementById('previous'), + next: document.getElementById('next'), + zoomIn: document.getElementById('zoomIn'), + zoomOut: document.getElementById('zoomOut'), + viewFind: document.getElementById('viewFind'), + openFile: document.getElementById('openFile'), + print: document.getElementById('print'), + presentationModeButton: document.getElementById('presentationMode'), + download: document.getElementById('download'), + viewBookmark: document.getElementById('viewBookmark') + }, + secondaryToolbar: { + toolbar: document.getElementById('secondaryToolbar'), + toggleButton: document.getElementById('secondaryToolbarToggle'), + toolbarButtonContainer: document.getElementById('secondaryToolbarButtonContainer'), + presentationModeButton: document.getElementById('secondaryPresentationMode'), + openFileButton: document.getElementById('secondaryOpenFile'), + printButton: document.getElementById('secondaryPrint'), + downloadButton: document.getElementById('secondaryDownload'), + viewBookmarkButton: document.getElementById('secondaryViewBookmark'), + firstPageButton: document.getElementById('firstPage'), + lastPageButton: document.getElementById('lastPage'), + pageRotateCwButton: document.getElementById('pageRotateCw'), + pageRotateCcwButton: document.getElementById('pageRotateCcw'), + cursorSelectToolButton: document.getElementById('cursorSelectTool'), + cursorHandToolButton: document.getElementById('cursorHandTool'), + documentPropertiesButton: document.getElementById('documentProperties') + }, + fullscreen: { + contextFirstPage: document.getElementById('contextFirstPage'), + contextLastPage: document.getElementById('contextLastPage'), + contextPageRotateCw: document.getElementById('contextPageRotateCw'), + contextPageRotateCcw: document.getElementById('contextPageRotateCcw') + }, + sidebar: { + mainContainer: document.getElementById('mainContainer'), + outerContainer: document.getElementById('outerContainer'), + toggleButton: document.getElementById('sidebarToggle'), + thumbnailButton: document.getElementById('viewThumbnail'), + outlineButton: document.getElementById('viewOutline'), + attachmentsButton: document.getElementById('viewAttachments'), + thumbnailView: document.getElementById('thumbnailView'), + outlineView: document.getElementById('outlineView'), + attachmentsView: document.getElementById('attachmentsView') + }, + findBar: { + bar: document.getElementById('findbar'), + toggleButton: document.getElementById('viewFind'), + findField: document.getElementById('findInput'), + highlightAllCheckbox: document.getElementById('findHighlightAll'), + caseSensitiveCheckbox: document.getElementById('findMatchCase'), + findMsg: document.getElementById('findMsg'), + findResultsCount: document.getElementById('findResultsCount'), + findStatusIcon: document.getElementById('findStatusIcon'), + findPreviousButton: document.getElementById('findPrevious'), + findNextButton: document.getElementById('findNext') + }, + passwordOverlay: { + overlayName: 'passwordOverlay', + container: document.getElementById('passwordOverlay'), + label: document.getElementById('passwordText'), + input: document.getElementById('password'), + submitButton: document.getElementById('passwordSubmit'), + cancelButton: document.getElementById('passwordCancel') + }, + documentProperties: { + overlayName: 'documentPropertiesOverlay', + container: document.getElementById('documentPropertiesOverlay'), + closeButton: document.getElementById('documentPropertiesClose'), + fields: { + 'fileName': document.getElementById('fileNameField'), + 'fileSize': document.getElementById('fileSizeField'), + 'title': document.getElementById('titleField'), + 'author': document.getElementById('authorField'), + 'subject': document.getElementById('subjectField'), + 'keywords': document.getElementById('keywordsField'), + 'creationDate': document.getElementById('creationDateField'), + 'modificationDate': document.getElementById('modificationDateField'), + 'creator': document.getElementById('creatorField'), + 'producer': document.getElementById('producerField'), + 'version': document.getElementById('versionField'), + 'pageCount': document.getElementById('pageCountField') + } + }, + errorWrapper: { + container: document.getElementById('errorWrapper'), + errorMessage: document.getElementById('errorMessage'), + closeButton: document.getElementById('errorClose'), + errorMoreInfo: document.getElementById('errorMoreInfo'), + moreInfoButton: document.getElementById('errorShowMore'), + lessInfoButton: document.getElementById('errorShowLess') + }, + printContainer: document.getElementById('printContainer'), + openFileInputName: 'fileInput', + debuggerScriptPath: './debugger.js', + defaultUrl: DEFAULT_URL + }; +} +function webViewerLoad() { + var config = getViewerConfiguration(); + window.PDFViewerApplication = pdfjsWebApp.PDFViewerApplication; + pdfjsWebApp.PDFViewerApplication.run(config); +} +if (document.readyState === 'interactive' || document.readyState === 'complete') { + webViewerLoad(); +} else { + document.addEventListener('DOMContentLoaded', webViewerLoad, true); +} + +/***/ }), +/* 9 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +function GrabToPan(options) { + this.element = options.element; + this.document = options.element.ownerDocument; + if (typeof options.ignoreTarget === 'function') { + this.ignoreTarget = options.ignoreTarget; + } + this.onActiveChanged = options.onActiveChanged; + this.activate = this.activate.bind(this); + this.deactivate = this.deactivate.bind(this); + this.toggle = this.toggle.bind(this); + this._onmousedown = this._onmousedown.bind(this); + this._onmousemove = this._onmousemove.bind(this); + this._endPan = this._endPan.bind(this); + var overlay = this.overlay = document.createElement('div'); + overlay.className = 'grab-to-pan-grabbing'; +} +GrabToPan.prototype = { + CSS_CLASS_GRAB: 'grab-to-pan-grab', + activate: function GrabToPan_activate() { + if (!this.active) { + this.active = true; + this.element.addEventListener('mousedown', this._onmousedown, true); + this.element.classList.add(this.CSS_CLASS_GRAB); + if (this.onActiveChanged) { + this.onActiveChanged(true); + } + } + }, + deactivate: function GrabToPan_deactivate() { + if (this.active) { + this.active = false; + this.element.removeEventListener('mousedown', this._onmousedown, true); + this._endPan(); + this.element.classList.remove(this.CSS_CLASS_GRAB); + if (this.onActiveChanged) { + this.onActiveChanged(false); + } + } + }, + toggle: function GrabToPan_toggle() { + if (this.active) { + this.deactivate(); + } else { + this.activate(); + } + }, + ignoreTarget: function GrabToPan_ignoreTarget(node) { + return node[matchesSelector]('a[href], a[href] *, input, textarea, button, button *, select, option'); + }, + _onmousedown: function GrabToPan__onmousedown(event) { + if (event.button !== 0 || this.ignoreTarget(event.target)) { + return; + } + if (event.originalTarget) { + try { + event.originalTarget.tagName; + } catch (e) { + return; + } + } + this.scrollLeftStart = this.element.scrollLeft; + this.scrollTopStart = this.element.scrollTop; + this.clientXStart = event.clientX; + this.clientYStart = event.clientY; + this.document.addEventListener('mousemove', this._onmousemove, true); + this.document.addEventListener('mouseup', this._endPan, true); + this.element.addEventListener('scroll', this._endPan, true); + event.preventDefault(); + event.stopPropagation(); + var focusedElement = document.activeElement; + if (focusedElement && !focusedElement.contains(event.target)) { + focusedElement.blur(); + } + }, + _onmousemove: function GrabToPan__onmousemove(event) { + this.element.removeEventListener('scroll', this._endPan, true); + if (isLeftMouseReleased(event)) { + this._endPan(); + return; + } + var xDiff = event.clientX - this.clientXStart; + var yDiff = event.clientY - this.clientYStart; + var scrollTop = this.scrollTopStart - yDiff; + var scrollLeft = this.scrollLeftStart - xDiff; + if (this.element.scrollTo) { + this.element.scrollTo({ + top: scrollTop, + left: scrollLeft, + behavior: 'instant' + }); + } else { + this.element.scrollTop = scrollTop; + this.element.scrollLeft = scrollLeft; + } + if (!this.overlay.parentNode) { + document.body.appendChild(this.overlay); + } + }, + _endPan: function GrabToPan__endPan() { + this.element.removeEventListener('scroll', this._endPan, true); + this.document.removeEventListener('mousemove', this._onmousemove, true); + this.document.removeEventListener('mouseup', this._endPan, true); + this.overlay.remove(); + } +}; +var matchesSelector; +['webkitM', 'mozM', 'msM', 'oM', 'm'].some(function (prefix) { + var name = prefix + 'atches'; + if (name in document.documentElement) { + matchesSelector = name; + } + name += 'Selector'; + if (name in document.documentElement) { + matchesSelector = name; + } + return matchesSelector; +}); +var isNotIEorIsIE10plus = !document.documentMode || document.documentMode > 9; +var chrome = window.chrome; +var isChrome15OrOpera15plus = chrome && (chrome.webstore || chrome.app); +var isSafari6plus = /Apple/.test(navigator.vendor) && /Version\/([6-9]\d*|[1-5]\d+)/.test(navigator.userAgent); +function isLeftMouseReleased(event) { + if ('buttons' in event && isNotIEorIsIE10plus) { + return !(event.buttons & 1); + } + if (isChrome15OrOpera15plus || isSafari6plus) { + return event.which === 0; + } +} +exports.GrabToPan = GrabToPan; + +/***/ }), +/* 10 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.PDFSidebar = exports.SidebarView = undefined; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _ui_utils = __webpack_require__(0); + +var _pdf_rendering_queue = __webpack_require__(3); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var UI_NOTIFICATION_CLASS = 'pdfSidebarNotification'; +var SidebarView = { + NONE: 0, + THUMBS: 1, + OUTLINE: 2, + ATTACHMENTS: 3 +}; + +var PDFSidebar = function () { + function PDFSidebar(options) { + var l10n = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _ui_utils.NullL10n; + + _classCallCheck(this, PDFSidebar); + + this.isOpen = false; + this.active = SidebarView.THUMBS; + this.isInitialViewSet = false; + this.onToggled = null; + this.pdfViewer = options.pdfViewer; + this.pdfThumbnailViewer = options.pdfThumbnailViewer; + this.pdfOutlineViewer = options.pdfOutlineViewer; + this.mainContainer = options.mainContainer; + this.outerContainer = options.outerContainer; + this.eventBus = options.eventBus; + this.toggleButton = options.toggleButton; + this.thumbnailButton = options.thumbnailButton; + this.outlineButton = options.outlineButton; + this.attachmentsButton = options.attachmentsButton; + this.thumbnailView = options.thumbnailView; + this.outlineView = options.outlineView; + this.attachmentsView = options.attachmentsView; + this.disableNotification = options.disableNotification || false; + this.l10n = l10n; + this._addEventListeners(); + } + + _createClass(PDFSidebar, [{ + key: 'reset', + value: function reset() { + this.isInitialViewSet = false; + this._hideUINotification(null); + this.switchView(SidebarView.THUMBS); + this.outlineButton.disabled = false; + this.attachmentsButton.disabled = false; + } + }, { + key: 'setInitialView', + value: function setInitialView() { + var view = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : SidebarView.NONE; + + if (this.isInitialViewSet) { + return; + } + this.isInitialViewSet = true; + if (this.isOpen && view === SidebarView.NONE) { + this._dispatchEvent(); + return; + } + var isViewPreserved = view === this.visibleView; + this.switchView(view, true); + if (isViewPreserved) { + this._dispatchEvent(); + } + } + }, { + key: 'switchView', + value: function switchView(view) { + var forceOpen = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + if (view === SidebarView.NONE) { + this.close(); + return; + } + var isViewChanged = view !== this.active; + var shouldForceRendering = false; + switch (view) { + case SidebarView.THUMBS: + this.thumbnailButton.classList.add('toggled'); + this.outlineButton.classList.remove('toggled'); + this.attachmentsButton.classList.remove('toggled'); + this.thumbnailView.classList.remove('hidden'); + this.outlineView.classList.add('hidden'); + this.attachmentsView.classList.add('hidden'); + if (this.isOpen && isViewChanged) { + this._updateThumbnailViewer(); + shouldForceRendering = true; + } + break; + case SidebarView.OUTLINE: + if (this.outlineButton.disabled) { + return; + } + this.thumbnailButton.classList.remove('toggled'); + this.outlineButton.classList.add('toggled'); + this.attachmentsButton.classList.remove('toggled'); + this.thumbnailView.classList.add('hidden'); + this.outlineView.classList.remove('hidden'); + this.attachmentsView.classList.add('hidden'); + break; + case SidebarView.ATTACHMENTS: + if (this.attachmentsButton.disabled) { + return; + } + this.thumbnailButton.classList.remove('toggled'); + this.outlineButton.classList.remove('toggled'); + this.attachmentsButton.classList.add('toggled'); + this.thumbnailView.classList.add('hidden'); + this.outlineView.classList.add('hidden'); + this.attachmentsView.classList.remove('hidden'); + break; + default: + console.error('PDFSidebar_switchView: "' + view + '" is an unsupported value.'); + return; + } + this.active = view | 0; + if (forceOpen && !this.isOpen) { + this.open(); + return; + } + if (shouldForceRendering) { + this._forceRendering(); + } + if (isViewChanged) { + this._dispatchEvent(); + } + this._hideUINotification(this.active); + } + }, { + key: 'open', + value: function open() { + if (this.isOpen) { + return; + } + this.isOpen = true; + this.toggleButton.classList.add('toggled'); + this.outerContainer.classList.add('sidebarMoving'); + this.outerContainer.classList.add('sidebarOpen'); + if (this.active === SidebarView.THUMBS) { + this._updateThumbnailViewer(); + } + this._forceRendering(); + this._dispatchEvent(); + this._hideUINotification(this.active); + } + }, { + key: 'close', + value: function close() { + if (!this.isOpen) { + return; + } + this.isOpen = false; + this.toggleButton.classList.remove('toggled'); + this.outerContainer.classList.add('sidebarMoving'); + this.outerContainer.classList.remove('sidebarOpen'); + this._forceRendering(); + this._dispatchEvent(); + } + }, { + key: 'toggle', + value: function toggle() { + if (this.isOpen) { + this.close(); + } else { + this.open(); + } + } + }, { + key: '_dispatchEvent', + value: function _dispatchEvent() { + this.eventBus.dispatch('sidebarviewchanged', { + source: this, + view: this.visibleView + }); + } + }, { + key: '_forceRendering', + value: function _forceRendering() { + if (this.onToggled) { + this.onToggled(); + } else { + this.pdfViewer.forceRendering(); + this.pdfThumbnailViewer.forceRendering(); + } + } + }, { + key: '_updateThumbnailViewer', + value: function _updateThumbnailViewer() { + var pdfViewer = this.pdfViewer, + pdfThumbnailViewer = this.pdfThumbnailViewer; + + var pagesCount = pdfViewer.pagesCount; + for (var pageIndex = 0; pageIndex < pagesCount; pageIndex++) { + var pageView = pdfViewer.getPageView(pageIndex); + if (pageView && pageView.renderingState === _pdf_rendering_queue.RenderingStates.FINISHED) { + var thumbnailView = pdfThumbnailViewer.getThumbnail(pageIndex); + thumbnailView.setImage(pageView); + } + } + pdfThumbnailViewer.scrollThumbnailIntoView(pdfViewer.currentPageNumber); + } + }, { + key: '_showUINotification', + value: function _showUINotification(view) { + var _this = this; + + if (this.disableNotification) { + return; + } + this.l10n.get('toggle_sidebar_notification.title', null, 'Toggle Sidebar (document contains outline/attachments)').then(function (msg) { + _this.toggleButton.title = msg; + }); + if (!this.isOpen) { + this.toggleButton.classList.add(UI_NOTIFICATION_CLASS); + } else if (view === this.active) { + return; + } + switch (view) { + case SidebarView.OUTLINE: + this.outlineButton.classList.add(UI_NOTIFICATION_CLASS); + break; + case SidebarView.ATTACHMENTS: + this.attachmentsButton.classList.add(UI_NOTIFICATION_CLASS); + break; + } + } + }, { + key: '_hideUINotification', + value: function _hideUINotification(view) { + var _this2 = this; + + if (this.disableNotification) { + return; + } + var removeNotification = function removeNotification(view) { + switch (view) { + case SidebarView.OUTLINE: + _this2.outlineButton.classList.remove(UI_NOTIFICATION_CLASS); + break; + case SidebarView.ATTACHMENTS: + _this2.attachmentsButton.classList.remove(UI_NOTIFICATION_CLASS); + break; + } + }; + if (!this.isOpen && view !== null) { + return; + } + this.toggleButton.classList.remove(UI_NOTIFICATION_CLASS); + if (view !== null) { + removeNotification(view); + return; + } + for (view in SidebarView) { + removeNotification(SidebarView[view]); + } + this.l10n.get('toggle_sidebar.title', null, 'Toggle Sidebar').then(function (msg) { + _this2.toggleButton.title = msg; + }); + } + }, { + key: '_addEventListeners', + value: function _addEventListeners() { + var _this3 = this; + + this.mainContainer.addEventListener('transitionend', function (evt) { + if (evt.target === _this3.mainContainer) { + _this3.outerContainer.classList.remove('sidebarMoving'); + } + }); + this.thumbnailButton.addEventListener('click', function () { + _this3.switchView(SidebarView.THUMBS); + }); + this.outlineButton.addEventListener('click', function () { + _this3.switchView(SidebarView.OUTLINE); + }); + this.outlineButton.addEventListener('dblclick', function () { + _this3.pdfOutlineViewer.toggleOutlineTree(); + }); + this.attachmentsButton.addEventListener('click', function () { + _this3.switchView(SidebarView.ATTACHMENTS); + }); + this.eventBus.on('outlineloaded', function (evt) { + var outlineCount = evt.outlineCount; + _this3.outlineButton.disabled = !outlineCount; + if (outlineCount) { + _this3._showUINotification(SidebarView.OUTLINE); + } else if (_this3.active === SidebarView.OUTLINE) { + _this3.switchView(SidebarView.THUMBS); + } + }); + this.eventBus.on('attachmentsloaded', function (evt) { + if (evt.attachmentsCount) { + _this3.attachmentsButton.disabled = false; + _this3._showUINotification(SidebarView.ATTACHMENTS); + return; + } + Promise.resolve().then(function () { + if (_this3.attachmentsView.hasChildNodes()) { + return; + } + _this3.attachmentsButton.disabled = true; + if (_this3.active === SidebarView.ATTACHMENTS) { + _this3.switchView(SidebarView.THUMBS); + } + }); + }); + this.eventBus.on('presentationmodechanged', function (evt) { + if (!evt.active && !evt.switchInProgress && _this3.isThumbnailViewVisible) { + _this3._updateThumbnailViewer(); + } + }); + } + }, { + key: 'visibleView', + get: function get() { + return this.isOpen ? this.active : SidebarView.NONE; + } + }, { + key: 'isThumbnailViewVisible', + get: function get() { + return this.isOpen && this.active === SidebarView.THUMBS; + } + }, { + key: 'isOutlineViewVisible', + get: function get() { + return this.isOpen && this.active === SidebarView.OUTLINE; + } + }, { + key: 'isAttachmentsViewVisible', + get: function get() { + return this.isOpen && this.active === SidebarView.ATTACHMENTS; + } + }]); + + return PDFSidebar; +}(); + +exports.SidebarView = SidebarView; +exports.PDFSidebar = PDFSidebar; + +/***/ }), +/* 11 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var OverlayManager = function () { + function OverlayManager() { + _classCallCheck(this, OverlayManager); + + this._overlays = {}; + this._active = null; + this._keyDownBound = this._keyDown.bind(this); + } + + _createClass(OverlayManager, [{ + key: 'register', + value: function register(name, element) { + var _this = this; + + var callerCloseMethod = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; + var canForceClose = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; + + return new Promise(function (resolve) { + var container = void 0; + if (!name || !element || !(container = element.parentNode)) { + throw new Error('Not enough parameters.'); + } else if (_this._overlays[name]) { + throw new Error('The overlay is already registered.'); + } + _this._overlays[name] = { + element: element, + container: container, + callerCloseMethod: callerCloseMethod, + canForceClose: canForceClose + }; + resolve(); + }); + } + }, { + key: 'unregister', + value: function unregister(name) { + var _this2 = this; + + return new Promise(function (resolve) { + if (!_this2._overlays[name]) { + throw new Error('The overlay does not exist.'); + } else if (_this2._active === name) { + throw new Error('The overlay cannot be removed while it is active.'); + } + delete _this2._overlays[name]; + resolve(); + }); + } + }, { + key: 'open', + value: function open(name) { + var _this3 = this; + + return new Promise(function (resolve) { + if (!_this3._overlays[name]) { + throw new Error('The overlay does not exist.'); + } else if (_this3._active) { + if (_this3._overlays[name].canForceClose) { + _this3._closeThroughCaller(); + } else if (_this3._active === name) { + throw new Error('The overlay is already active.'); + } else { + throw new Error('Another overlay is currently active.'); + } + } + _this3._active = name; + _this3._overlays[_this3._active].element.classList.remove('hidden'); + _this3._overlays[_this3._active].container.classList.remove('hidden'); + window.addEventListener('keydown', _this3._keyDownBound); + resolve(); + }); + } + }, { + key: 'close', + value: function close(name) { + var _this4 = this; + + return new Promise(function (resolve) { + if (!_this4._overlays[name]) { + throw new Error('The overlay does not exist.'); + } else if (!_this4._active) { + throw new Error('The overlay is currently not active.'); + } else if (_this4._active !== name) { + throw new Error('Another overlay is currently active.'); + } + _this4._overlays[_this4._active].container.classList.add('hidden'); + _this4._overlays[_this4._active].element.classList.add('hidden'); + _this4._active = null; + window.removeEventListener('keydown', _this4._keyDownBound); + resolve(); + }); + } + }, { + key: '_keyDown', + value: function _keyDown(evt) { + if (this._active && evt.keyCode === 27) { + this._closeThroughCaller(); + evt.preventDefault(); + } + } + }, { + key: '_closeThroughCaller', + value: function _closeThroughCaller() { + if (this._overlays[this._active].callerCloseMethod) { + this._overlays[this._active].callerCloseMethod(); + } + if (this._active) { + this.close(this._active); + } + } + }, { + key: 'active', + get: function get() { + return this._active; + } + }]); + + return OverlayManager; +}(); + +exports.OverlayManager = OverlayManager; + +/***/ }), +/* 12 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.PasswordPrompt = undefined; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _ui_utils = __webpack_require__(0); + +var _pdfjsLib = __webpack_require__(1); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var PasswordPrompt = function () { + function PasswordPrompt(options, overlayManager) { + var _this = this; + + var l10n = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : _ui_utils.NullL10n; + + _classCallCheck(this, PasswordPrompt); + + this.overlayName = options.overlayName; + this.container = options.container; + this.label = options.label; + this.input = options.input; + this.submitButton = options.submitButton; + this.cancelButton = options.cancelButton; + this.overlayManager = overlayManager; + this.l10n = l10n; + this.updateCallback = null; + this.reason = null; + this.submitButton.addEventListener('click', this.verify.bind(this)); + this.cancelButton.addEventListener('click', this.close.bind(this)); + this.input.addEventListener('keydown', function (e) { + if (e.keyCode === 13) { + _this.verify(); + } + }); + this.overlayManager.register(this.overlayName, this.container, this.close.bind(this), true); + } + + _createClass(PasswordPrompt, [{ + key: 'open', + value: function open() { + var _this2 = this; + + this.overlayManager.open(this.overlayName).then(function () { + _this2.input.focus(); + var promptString = void 0; + if (_this2.reason === _pdfjsLib.PasswordResponses.INCORRECT_PASSWORD) { + promptString = _this2.l10n.get('password_invalid', null, 'Invalid password. Please try again.'); + } else { + promptString = _this2.l10n.get('password_label', null, 'Enter the password to open this PDF file.'); + } + promptString.then(function (msg) { + _this2.label.textContent = msg; + }); + }); + } + }, { + key: 'close', + value: function close() { + var _this3 = this; + + this.overlayManager.close(this.overlayName).then(function () { + _this3.input.value = ''; + }); + } + }, { + key: 'verify', + value: function verify() { + var password = this.input.value; + if (password && password.length > 0) { + this.close(); + return this.updateCallback(password); + } + } + }, { + key: 'setUpdateCallback', + value: function setUpdateCallback(updateCallback, reason) { + this.updateCallback = updateCallback; + this.reason = reason; + } + }]); + + return PasswordPrompt; +}(); + +exports.PasswordPrompt = PasswordPrompt; + +/***/ }), +/* 13 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.PDFAttachmentViewer = undefined; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _pdfjsLib = __webpack_require__(1); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var PDFAttachmentViewer = function () { + function PDFAttachmentViewer(_ref) { + var container = _ref.container, + eventBus = _ref.eventBus, + downloadManager = _ref.downloadManager; + + _classCallCheck(this, PDFAttachmentViewer); + + this.container = container; + this.eventBus = eventBus; + this.downloadManager = downloadManager; + this.reset(); + this.eventBus.on('fileattachmentannotation', this._appendAttachment.bind(this)); + } + + _createClass(PDFAttachmentViewer, [{ + key: 'reset', + value: function reset() { + var keepRenderedCapability = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + + this.attachments = null; + this.container.textContent = ''; + if (!keepRenderedCapability) { + this._renderedCapability = (0, _pdfjsLib.createPromiseCapability)(); + } + } + }, { + key: '_dispatchEvent', + value: function _dispatchEvent(attachmentsCount) { + this._renderedCapability.resolve(); + this.eventBus.dispatch('attachmentsloaded', { + source: this, + attachmentsCount: attachmentsCount + }); + } + }, { + key: '_bindPdfLink', + value: function _bindPdfLink(button, content, filename) { + if (_pdfjsLib.PDFJS.disableCreateObjectURL) { + throw new Error('bindPdfLink: ' + 'Unsupported "PDFJS.disableCreateObjectURL" value.'); + } + var blobUrl = void 0; + button.onclick = function () { + if (!blobUrl) { + blobUrl = (0, _pdfjsLib.createObjectURL)(content, 'application/pdf'); + } + var viewerUrl = void 0; + viewerUrl = '?file=' + encodeURIComponent(blobUrl + '#' + filename); + window.open(viewerUrl); + return false; + }; + } + }, { + key: '_bindLink', + value: function _bindLink(button, content, filename) { + var _this = this; + + button.onclick = function () { + _this.downloadManager.downloadData(content, filename, ''); + return false; + }; + } + }, { + key: 'render', + value: function render(_ref2) { + var attachments = _ref2.attachments, + _ref2$keepRenderedCap = _ref2.keepRenderedCapability, + keepRenderedCapability = _ref2$keepRenderedCap === undefined ? false : _ref2$keepRenderedCap; + + var attachmentsCount = 0; + if (this.attachments) { + this.reset(keepRenderedCapability === true); + } + this.attachments = attachments || null; + if (!attachments) { + this._dispatchEvent(attachmentsCount); + return; + } + var names = Object.keys(attachments).sort(function (a, b) { + return a.toLowerCase().localeCompare(b.toLowerCase()); + }); + attachmentsCount = names.length; + for (var i = 0; i < attachmentsCount; i++) { + var item = attachments[names[i]]; + var filename = (0, _pdfjsLib.removeNullCharacters)((0, _pdfjsLib.getFilenameFromUrl)(item.filename)); + var div = document.createElement('div'); + div.className = 'attachmentsItem'; + var button = document.createElement('button'); + button.textContent = filename; + if (/\.pdf$/i.test(filename) && !_pdfjsLib.PDFJS.disableCreateObjectURL) { + this._bindPdfLink(button, item.content, filename); + } else { + this._bindLink(button, item.content, filename); + } + div.appendChild(button); + this.container.appendChild(div); + } + this._dispatchEvent(attachmentsCount); + } + }, { + key: '_appendAttachment', + value: function _appendAttachment(_ref3) { + var _this2 = this; + + var id = _ref3.id, + filename = _ref3.filename, + content = _ref3.content; + + this._renderedCapability.promise.then(function () { + var attachments = _this2.attachments; + if (!attachments) { + attachments = Object.create(null); + } else { + for (var name in attachments) { + if (id === name) { + return; + } + } + } + attachments[id] = { + filename: filename, + content: content + }; + _this2.render({ + attachments: attachments, + keepRenderedCapability: true + }); + }); + } + }]); + + return PDFAttachmentViewer; +}(); + +exports.PDFAttachmentViewer = PDFAttachmentViewer; + +/***/ }), +/* 14 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.PDFDocumentProperties = undefined; + +var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _ui_utils = __webpack_require__(0); + +var _pdfjsLib = __webpack_require__(1); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var DEFAULT_FIELD_CONTENT = '-'; + +var PDFDocumentProperties = function () { + function PDFDocumentProperties(_ref, overlayManager) { + var overlayName = _ref.overlayName, + fields = _ref.fields, + container = _ref.container, + closeButton = _ref.closeButton; + var l10n = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : _ui_utils.NullL10n; + + _classCallCheck(this, PDFDocumentProperties); + + this.overlayName = overlayName; + this.fields = fields; + this.container = container; + this.overlayManager = overlayManager; + this.l10n = l10n; + this._reset(); + if (closeButton) { + closeButton.addEventListener('click', this.close.bind(this)); + } + this.overlayManager.register(this.overlayName, this.container, this.close.bind(this)); + } + + _createClass(PDFDocumentProperties, [{ + key: 'open', + value: function open() { + var _this = this; + + var freezeFieldData = function freezeFieldData(data) { + Object.defineProperty(_this, 'fieldData', { + value: Object.freeze(data), + writable: false, + enumerable: true, + configurable: true + }); + }; + Promise.all([this.overlayManager.open(this.overlayName), this._dataAvailableCapability.promise]).then(function () { + if (_this.fieldData) { + _this._updateUI(); + return; + } + _this.pdfDocument.getMetadata().then(function (_ref2) { + var info = _ref2.info, + metadata = _ref2.metadata; + + return Promise.all([info, metadata, _this._parseFileSize(_this.maybeFileSize), _this._parseDate(info.CreationDate), _this._parseDate(info.ModDate)]); + }).then(function (_ref3) { + var _ref4 = _slicedToArray(_ref3, 5), + info = _ref4[0], + metadata = _ref4[1], + fileSize = _ref4[2], + creationDate = _ref4[3], + modificationDate = _ref4[4]; + + freezeFieldData({ + 'fileName': (0, _ui_utils.getPDFFileNameFromURL)(_this.url), + 'fileSize': fileSize, + 'title': info.Title, + 'author': info.Author, + 'subject': info.Subject, + 'keywords': info.Keywords, + 'creationDate': creationDate, + 'modificationDate': modificationDate, + 'creator': info.Creator, + 'producer': info.Producer, + 'version': info.PDFFormatVersion, + 'pageCount': _this.pdfDocument.numPages + }); + _this._updateUI(); + return _this.pdfDocument.getDownloadInfo(); + }).then(function (_ref5) { + var length = _ref5.length; + + return _this._parseFileSize(length); + }).then(function (fileSize) { + var data = (0, _ui_utils.cloneObj)(_this.fieldData); + data['fileSize'] = fileSize; + freezeFieldData(data); + _this._updateUI(); + }); + }); + } + }, { + key: 'close', + value: function close() { + this.overlayManager.close(this.overlayName); + } + }, { + key: 'setDocument', + value: function setDocument(pdfDocument, url) { + if (this.pdfDocument) { + this._reset(); + this._updateUI(true); + } + if (!pdfDocument) { + return; + } + this.pdfDocument = pdfDocument; + this.url = url; + this._dataAvailableCapability.resolve(); + } + }, { + key: 'setFileSize', + value: function setFileSize(fileSize) { + if (typeof fileSize === 'number' && fileSize > 0) { + this.maybeFileSize = fileSize; + } + } + }, { + key: '_reset', + value: function _reset() { + this.pdfDocument = null; + this.url = null; + this.maybeFileSize = 0; + delete this.fieldData; + this._dataAvailableCapability = (0, _pdfjsLib.createPromiseCapability)(); + } + }, { + key: '_updateUI', + value: function _updateUI() { + var reset = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + + if (reset || !this.fieldData) { + for (var id in this.fields) { + this.fields[id].textContent = DEFAULT_FIELD_CONTENT; + } + return; + } + if (this.overlayManager.active !== this.overlayName) { + return; + } + for (var _id in this.fields) { + var content = this.fieldData[_id]; + this.fields[_id].textContent = content || content === 0 ? content : DEFAULT_FIELD_CONTENT; + } + } + }, { + key: '_parseFileSize', + value: function _parseFileSize() { + var fileSize = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; + + var kb = fileSize / 1024; + if (!kb) { + return Promise.resolve(undefined); + } else if (kb < 1024) { + return this.l10n.get('document_properties_kb', { + size_kb: (+kb.toPrecision(3)).toLocaleString(), + size_b: fileSize.toLocaleString() + }, '{{size_kb}} KB ({{size_b}} bytes)'); + } + return this.l10n.get('document_properties_mb', { + size_mb: (+(kb / 1024).toPrecision(3)).toLocaleString(), + size_b: fileSize.toLocaleString() + }, '{{size_mb}} MB ({{size_b}} bytes)'); + } + }, { + key: '_parseDate', + value: function _parseDate(inputDate) { + if (!inputDate) { + return; + } + var dateToParse = inputDate; + if (dateToParse.substring(0, 2) === 'D:') { + dateToParse = dateToParse.substring(2); + } + var year = parseInt(dateToParse.substring(0, 4), 10); + var month = parseInt(dateToParse.substring(4, 6), 10) - 1; + var day = parseInt(dateToParse.substring(6, 8), 10); + var hours = parseInt(dateToParse.substring(8, 10), 10); + var minutes = parseInt(dateToParse.substring(10, 12), 10); + var seconds = parseInt(dateToParse.substring(12, 14), 10); + var utRel = dateToParse.substring(14, 15); + var offsetHours = parseInt(dateToParse.substring(15, 17), 10); + var offsetMinutes = parseInt(dateToParse.substring(18, 20), 10); + if (utRel === '-') { + hours += offsetHours; + minutes += offsetMinutes; + } else if (utRel === '+') { + hours -= offsetHours; + minutes -= offsetMinutes; + } + var date = new Date(Date.UTC(year, month, day, hours, minutes, seconds)); + var dateString = date.toLocaleDateString(); + var timeString = date.toLocaleTimeString(); + return this.l10n.get('document_properties_date_string', { + date: dateString, + time: timeString + }, '{{date}}, {{time}}'); + } + }]); + + return PDFDocumentProperties; +}(); + +exports.PDFDocumentProperties = PDFDocumentProperties; + +/***/ }), +/* 15 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.PDFFindBar = undefined; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _pdf_find_controller = __webpack_require__(7); + +var _ui_utils = __webpack_require__(0); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var PDFFindBar = function () { + function PDFFindBar(options) { + var _this = this; + + var l10n = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _ui_utils.NullL10n; + + _classCallCheck(this, PDFFindBar); + + this.opened = false; + this.bar = options.bar || null; + this.toggleButton = options.toggleButton || null; + this.findField = options.findField || null; + this.highlightAll = options.highlightAllCheckbox || null; + this.caseSensitive = options.caseSensitiveCheckbox || null; + this.findMsg = options.findMsg || null; + this.findResultsCount = options.findResultsCount || null; + this.findStatusIcon = options.findStatusIcon || null; + this.findPreviousButton = options.findPreviousButton || null; + this.findNextButton = options.findNextButton || null; + this.findController = options.findController || null; + this.eventBus = options.eventBus; + this.l10n = l10n; + if (this.findController === null) { + throw new Error('PDFFindBar cannot be used without a ' + 'PDFFindController instance.'); + } + this.toggleButton.addEventListener('click', function () { + _this.toggle(); + }); + this.findField.addEventListener('input', function () { + _this.dispatchEvent(''); + }); + this.bar.addEventListener('keydown', function (e) { + switch (e.keyCode) { + case 13: + if (e.target === _this.findField) { + _this.dispatchEvent('again', e.shiftKey); + } + break; + case 27: + _this.close(); + break; + } + }); + this.findPreviousButton.addEventListener('click', function () { + _this.dispatchEvent('again', true); + }); + this.findNextButton.addEventListener('click', function () { + _this.dispatchEvent('again', false); + }); + this.highlightAll.addEventListener('click', function () { + _this.dispatchEvent('highlightallchange'); + }); + this.caseSensitive.addEventListener('click', function () { + _this.dispatchEvent('casesensitivitychange'); + }); + this.eventBus.on('resize', this._adjustWidth.bind(this)); + } + + _createClass(PDFFindBar, [{ + key: 'reset', + value: function reset() { + this.updateUIState(); + } + }, { + key: 'dispatchEvent', + value: function dispatchEvent(type, findPrev) { + this.eventBus.dispatch('find', { + source: this, + type: type, + query: this.findField.value, + caseSensitive: this.caseSensitive.checked, + phraseSearch: true, + highlightAll: this.highlightAll.checked, + findPrevious: findPrev + }); + } + }, { + key: 'updateUIState', + value: function updateUIState(state, previous, matchCount) { + var _this2 = this; + + var notFound = false; + var findMsg = ''; + var status = ''; + switch (state) { + case _pdf_find_controller.FindState.FOUND: + break; + case _pdf_find_controller.FindState.PENDING: + status = 'pending'; + break; + case _pdf_find_controller.FindState.NOT_FOUND: + findMsg = this.l10n.get('find_not_found', null, 'Phrase not found'); + notFound = true; + break; + case _pdf_find_controller.FindState.WRAPPED: + if (previous) { + findMsg = this.l10n.get('find_reached_top', null, 'Reached top of document, continued from bottom'); + } else { + findMsg = this.l10n.get('find_reached_bottom', null, 'Reached end of document, continued from top'); + } + break; + } + if (notFound) { + this.findField.classList.add('notFound'); + } else { + this.findField.classList.remove('notFound'); + } + this.findField.setAttribute('data-status', status); + Promise.resolve(findMsg).then(function (msg) { + _this2.findMsg.textContent = msg; + _this2._adjustWidth(); + }); + this.updateResultsCount(matchCount); + } + }, { + key: 'updateResultsCount', + value: function updateResultsCount(matchCount) { + if (!this.findResultsCount) { + return; + } + if (!matchCount) { + this.findResultsCount.classList.add('hidden'); + this.findResultsCount.textContent = ''; + } else { + this.findResultsCount.textContent = matchCount.toLocaleString(); + this.findResultsCount.classList.remove('hidden'); + } + this._adjustWidth(); + } + }, { + key: 'open', + value: function open() { + if (!this.opened) { + this.opened = true; + this.toggleButton.classList.add('toggled'); + this.bar.classList.remove('hidden'); + } + this.findField.select(); + this.findField.focus(); + this._adjustWidth(); + } + }, { + key: 'close', + value: function close() { + if (!this.opened) { + return; + } + this.opened = false; + this.toggleButton.classList.remove('toggled'); + this.bar.classList.add('hidden'); + this.findController.active = false; + } + }, { + key: 'toggle', + value: function toggle() { + if (this.opened) { + this.close(); + } else { + this.open(); + } + } + }, { + key: '_adjustWidth', + value: function _adjustWidth() { + if (!this.opened) { + return; + } + this.bar.classList.remove('wrapContainers'); + var findbarHeight = this.bar.clientHeight; + var inputContainerHeight = this.bar.firstElementChild.clientHeight; + if (findbarHeight > inputContainerHeight) { + this.bar.classList.add('wrapContainers'); + } + } + }]); + + return PDFFindBar; +}(); + +exports.PDFFindBar = PDFFindBar; + +/***/ }), +/* 16 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.isDestsEqual = exports.PDFHistory = undefined; + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _ui_utils = __webpack_require__(0); + +var _dom_events = __webpack_require__(2); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var HASH_CHANGE_TIMEOUT = 1000; +var POSITION_UPDATED_THRESHOLD = 50; +var UPDATE_VIEWAREA_TIMEOUT = 1000; +function getCurrentHash() { + return document.location.hash; +} +function parseCurrentHash(linkService) { + var hash = unescape(getCurrentHash()).substring(1); + var params = (0, _ui_utils.parseQueryString)(hash); + var page = params.page | 0; + if (!(Number.isInteger(page) && page > 0 && page <= linkService.pagesCount)) { + page = null; + } + return { + hash: hash, + page: page, + rotation: linkService.rotation + }; +} + +var PDFHistory = function () { + function PDFHistory(_ref) { + var _this = this; + + var linkService = _ref.linkService, + eventBus = _ref.eventBus; + + _classCallCheck(this, PDFHistory); + + this.linkService = linkService; + this.eventBus = eventBus || (0, _dom_events.getGlobalEventBus)(); + this.initialized = false; + this.initialBookmark = null; + this.initialRotation = null; + this._boundEvents = Object.create(null); + this._isViewerInPresentationMode = false; + this._isPagesLoaded = false; + this.eventBus.on('presentationmodechanged', function (evt) { + _this._isViewerInPresentationMode = evt.active || evt.switchInProgress; + }); + this.eventBus.on('pagesloaded', function (evt) { + _this._isPagesLoaded = !!evt.pagesCount; + }); + } + + _createClass(PDFHistory, [{ + key: 'initialize', + value: function initialize(fingerprint) { + var resetHistory = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + if (!fingerprint || typeof fingerprint !== 'string') { + console.error('PDFHistory.initialize: The "fingerprint" must be a non-empty string.'); + return; + } + var reInitialized = this.initialized && this.fingerprint !== fingerprint; + this.fingerprint = fingerprint; + if (!this.initialized) { + this._bindEvents(); + } + var state = window.history.state; + this.initialized = true; + this.initialBookmark = null; + this.initialRotation = null; + this._popStateInProgress = false; + this._blockHashChange = 0; + this._currentHash = getCurrentHash(); + this._numPositionUpdates = 0; + this._currentUid = this._uid = 0; + this._destination = null; + this._position = null; + if (!this._isValidState(state) || resetHistory) { + var _parseCurrentHash = parseCurrentHash(this.linkService), + hash = _parseCurrentHash.hash, + page = _parseCurrentHash.page, + rotation = _parseCurrentHash.rotation; + + if (!hash || reInitialized || resetHistory) { + this._pushOrReplaceState(null, true); + return; + } + this._pushOrReplaceState({ + hash: hash, + page: page, + rotation: rotation + }, true); + return; + } + var destination = state.destination; + this._updateInternalState(destination, state.uid, true); + if (destination.rotation !== undefined) { + this.initialRotation = destination.rotation; + } + if (destination.dest) { + this.initialBookmark = JSON.stringify(destination.dest); + this._destination.page = null; + } else if (destination.hash) { + this.initialBookmark = destination.hash; + } else if (destination.page) { + this.initialBookmark = 'page=' + destination.page; + } + } + }, { + key: 'push', + value: function push(_ref2) { + var _this2 = this; + + var namedDest = _ref2.namedDest, + explicitDest = _ref2.explicitDest, + pageNumber = _ref2.pageNumber; + + if (!this.initialized) { + return; + } + if (namedDest && typeof namedDest !== 'string' || !(explicitDest instanceof Array) || !(Number.isInteger(pageNumber) && pageNumber > 0 && pageNumber <= this.linkService.pagesCount)) { + console.error('PDFHistory.push: Invalid parameters.'); + return; + } + var hash = namedDest || JSON.stringify(explicitDest); + if (!hash) { + return; + } + var forceReplace = false; + if (this._destination && (this._destination.hash === hash || isDestsEqual(this._destination.dest, explicitDest))) { + if (this._destination.page) { + return; + } + forceReplace = true; + } + if (this._popStateInProgress && !forceReplace) { + return; + } + this._pushOrReplaceState({ + dest: explicitDest, + hash: hash, + page: pageNumber, + rotation: this.linkService.rotation + }, forceReplace); + if (!this._popStateInProgress) { + this._popStateInProgress = true; + Promise.resolve().then(function () { + _this2._popStateInProgress = false; + }); + } + } + }, { + key: 'pushCurrentPosition', + value: function pushCurrentPosition() { + if (!this.initialized || this._popStateInProgress) { + return; + } + this._tryPushCurrentPosition(); + } + }, { + key: 'back', + value: function back() { + if (!this.initialized || this._popStateInProgress) { + return; + } + var state = window.history.state; + if (this._isValidState(state) && state.uid > 0) { + window.history.back(); + } + } + }, { + key: 'forward', + value: function forward() { + if (!this.initialized || this._popStateInProgress) { + return; + } + var state = window.history.state; + if (this._isValidState(state) && state.uid < this._uid - 1) { + window.history.forward(); + } + } + }, { + key: '_pushOrReplaceState', + value: function _pushOrReplaceState(destination) { + var forceReplace = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + var shouldReplace = forceReplace || !this._destination; + var newState = { + fingerprint: this.fingerprint, + uid: shouldReplace ? this._currentUid : this._uid, + destination: destination + }; + this._updateInternalState(destination, newState.uid); + if (shouldReplace) { + window.history.replaceState(newState, '', document.URL); + } else { + window.history.pushState(newState, '', document.URL); + } + } + }, { + key: '_tryPushCurrentPosition', + value: function _tryPushCurrentPosition() { + var temporary = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + + if (!this._position) { + return; + } + var position = this._position; + if (temporary) { + position = (0, _ui_utils.cloneObj)(this._position); + position.temporary = true; + } + if (!this._destination) { + this._pushOrReplaceState(position); + return; + } + if (this._destination.temporary) { + this._pushOrReplaceState(position, true); + return; + } + if (this._destination.hash === position.hash) { + return; + } + if (!this._destination.page && (POSITION_UPDATED_THRESHOLD <= 0 || this._numPositionUpdates <= POSITION_UPDATED_THRESHOLD)) { + return; + } + var forceReplace = false; + if (this._destination.page === position.first || this._destination.page === position.page) { + if (this._destination.dest || !this._destination.first) { + return; + } + forceReplace = true; + } + this._pushOrReplaceState(position, forceReplace); + } + }, { + key: '_isValidState', + value: function _isValidState(state) { + if (!state) { + return false; + } + if (state.fingerprint !== this.fingerprint) { + return false; + } + if (!Number.isInteger(state.uid) || state.uid < 0) { + return false; + } + if (state.destination === null || _typeof(state.destination) !== 'object') { + return false; + } + return true; + } + }, { + key: '_updateInternalState', + value: function _updateInternalState(destination, uid) { + var removeTemporary = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + + if (this._updateViewareaTimeout) { + clearTimeout(this._updateViewareaTimeout); + this._updateViewareaTimeout = null; + } + if (removeTemporary && destination && destination.temporary) { + delete destination.temporary; + } + this._destination = destination; + this._currentUid = uid; + this._uid = this._currentUid + 1; + this._numPositionUpdates = 0; + } + }, { + key: '_updateViewarea', + value: function _updateViewarea(_ref3) { + var _this3 = this; + + var location = _ref3.location; + + if (this._updateViewareaTimeout) { + clearTimeout(this._updateViewareaTimeout); + this._updateViewareaTimeout = null; + } + this._position = { + hash: this._isViewerInPresentationMode ? 'page=' + location.pageNumber : location.pdfOpenParams.substring(1), + page: this.linkService.page, + first: location.pageNumber, + rotation: location.rotation + }; + if (this._popStateInProgress) { + return; + } + if (POSITION_UPDATED_THRESHOLD > 0 && this._isPagesLoaded && this._destination && !this._destination.page) { + this._numPositionUpdates++; + } + if (UPDATE_VIEWAREA_TIMEOUT > 0) { + this._updateViewareaTimeout = setTimeout(function () { + if (!_this3._popStateInProgress) { + _this3._tryPushCurrentPosition(true); + } + _this3._updateViewareaTimeout = null; + }, UPDATE_VIEWAREA_TIMEOUT); + } + } + }, { + key: '_popState', + value: function _popState(_ref4) { + var _this4 = this; + + var state = _ref4.state; + + var newHash = getCurrentHash(), + hashChanged = this._currentHash !== newHash; + this._currentHash = newHash; + if (!state || false) { + this._currentUid = this._uid; + + var _parseCurrentHash2 = parseCurrentHash(this.linkService), + hash = _parseCurrentHash2.hash, + page = _parseCurrentHash2.page, + rotation = _parseCurrentHash2.rotation; + + this._pushOrReplaceState({ + hash: hash, + page: page, + rotation: rotation + }, true); + return; + } + if (!this._isValidState(state)) { + return; + } + this._popStateInProgress = true; + if (hashChanged) { + this._blockHashChange++; + (0, _ui_utils.waitOnEventOrTimeout)({ + target: window, + name: 'hashchange', + delay: HASH_CHANGE_TIMEOUT + }).then(function () { + _this4._blockHashChange--; + }); + } + var destination = state.destination; + this._updateInternalState(destination, state.uid, true); + if ((0, _ui_utils.isValidRotation)(destination.rotation)) { + this.linkService.rotation = destination.rotation; + } + if (destination.dest) { + this.linkService.navigateTo(destination.dest); + } else if (destination.hash) { + this.linkService.setHash(destination.hash); + } else if (destination.page) { + this.linkService.page = destination.page; + } + Promise.resolve().then(function () { + _this4._popStateInProgress = false; + }); + } + }, { + key: '_bindEvents', + value: function _bindEvents() { + var _this5 = this; + + var _boundEvents = this._boundEvents, + eventBus = this.eventBus; + + _boundEvents.updateViewarea = this._updateViewarea.bind(this); + _boundEvents.popState = this._popState.bind(this); + _boundEvents.pageHide = function (evt) { + if (!_this5._destination) { + _this5._tryPushCurrentPosition(); + } + }; + eventBus.on('updateviewarea', _boundEvents.updateViewarea); + window.addEventListener('popstate', _boundEvents.popState); + window.addEventListener('pagehide', _boundEvents.pageHide); + } + }, { + key: 'popStateInProgress', + get: function get() { + return this.initialized && (this._popStateInProgress || this._blockHashChange > 0); + } + }]); + + return PDFHistory; +}(); + +function isDestsEqual(firstDest, secondDest) { + function isEntryEqual(first, second) { + if ((typeof first === 'undefined' ? 'undefined' : _typeof(first)) !== (typeof second === 'undefined' ? 'undefined' : _typeof(second))) { + return false; + } + if (first instanceof Array || second instanceof Array) { + return false; + } + if (first !== null && (typeof first === 'undefined' ? 'undefined' : _typeof(first)) === 'object' && second !== null) { + if (Object.keys(first).length !== Object.keys(second).length) { + return false; + } + for (var key in first) { + if (!isEntryEqual(first[key], second[key])) { + return false; + } + } + return true; + } + return first === second || Number.isNaN(first) && Number.isNaN(second); + } + if (!(firstDest instanceof Array && secondDest instanceof Array)) { + return false; + } + if (firstDest.length !== secondDest.length) { + return false; + } + for (var i = 0, ii = firstDest.length; i < ii; i++) { + if (!isEntryEqual(firstDest[i], secondDest[i])) { + return false; + } + } + return true; +} +exports.PDFHistory = PDFHistory; +exports.isDestsEqual = isDestsEqual; + +/***/ }), +/* 17 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.PDFOutlineViewer = undefined; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _pdfjsLib = __webpack_require__(1); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var DEFAULT_TITLE = '\u2013'; + +var PDFOutlineViewer = function () { + function PDFOutlineViewer(_ref) { + var container = _ref.container, + linkService = _ref.linkService, + eventBus = _ref.eventBus; + + _classCallCheck(this, PDFOutlineViewer); + + this.container = container; + this.linkService = linkService; + this.eventBus = eventBus; + this.reset(); + } + + _createClass(PDFOutlineViewer, [{ + key: 'reset', + value: function reset() { + this.outline = null; + this.lastToggleIsShow = true; + this.container.textContent = ''; + this.container.classList.remove('outlineWithDeepNesting'); + } + }, { + key: '_dispatchEvent', + value: function _dispatchEvent(outlineCount) { + this.eventBus.dispatch('outlineloaded', { + source: this, + outlineCount: outlineCount + }); + } + }, { + key: '_bindLink', + value: function _bindLink(element, item) { + var _this = this; + + if (item.url) { + (0, _pdfjsLib.addLinkAttributes)(element, { + url: item.url, + target: item.newWindow ? _pdfjsLib.PDFJS.LinkTarget.BLANK : undefined + }); + return; + } + var destination = item.dest; + element.href = this.linkService.getDestinationHash(destination); + element.onclick = function () { + if (destination) { + _this.linkService.navigateTo(destination); + } + return false; + }; + } + }, { + key: '_setStyles', + value: function _setStyles(element, item) { + var styleStr = ''; + if (item.bold) { + styleStr += 'font-weight: bold;'; + } + if (item.italic) { + styleStr += 'font-style: italic;'; + } + if (styleStr) { + element.setAttribute('style', styleStr); + } + } + }, { + key: '_addToggleButton', + value: function _addToggleButton(div) { + var _this2 = this; + + var toggler = document.createElement('div'); + toggler.className = 'outlineItemToggler'; + toggler.onclick = function (evt) { + evt.stopPropagation(); + toggler.classList.toggle('outlineItemsHidden'); + if (evt.shiftKey) { + var shouldShowAll = !toggler.classList.contains('outlineItemsHidden'); + _this2._toggleOutlineItem(div, shouldShowAll); + } + }; + div.insertBefore(toggler, div.firstChild); + } + }, { + key: '_toggleOutlineItem', + value: function _toggleOutlineItem(root, show) { + this.lastToggleIsShow = show; + var togglers = root.querySelectorAll('.outlineItemToggler'); + for (var i = 0, ii = togglers.length; i < ii; ++i) { + togglers[i].classList[show ? 'remove' : 'add']('outlineItemsHidden'); + } + } + }, { + key: 'toggleOutlineTree', + value: function toggleOutlineTree() { + if (!this.outline) { + return; + } + this._toggleOutlineItem(this.container, !this.lastToggleIsShow); + } + }, { + key: 'render', + value: function render(_ref2) { + var outline = _ref2.outline; + + var outlineCount = 0; + if (this.outline) { + this.reset(); + } + this.outline = outline || null; + if (!outline) { + this._dispatchEvent(outlineCount); + return; + } + var fragment = document.createDocumentFragment(); + var queue = [{ + parent: fragment, + items: this.outline + }]; + var hasAnyNesting = false; + while (queue.length > 0) { + var levelData = queue.shift(); + for (var i = 0, len = levelData.items.length; i < len; i++) { + var item = levelData.items[i]; + var div = document.createElement('div'); + div.className = 'outlineItem'; + var element = document.createElement('a'); + this._bindLink(element, item); + this._setStyles(element, item); + element.textContent = (0, _pdfjsLib.removeNullCharacters)(item.title) || DEFAULT_TITLE; + div.appendChild(element); + if (item.items.length > 0) { + hasAnyNesting = true; + this._addToggleButton(div); + var itemsDiv = document.createElement('div'); + itemsDiv.className = 'outlineItems'; + div.appendChild(itemsDiv); + queue.push({ + parent: itemsDiv, + items: item.items + }); + } + levelData.parent.appendChild(div); + outlineCount++; + } + } + if (hasAnyNesting) { + this.container.classList.add('outlineWithDeepNesting'); + } + this.container.appendChild(fragment); + this._dispatchEvent(outlineCount); + } + }]); + + return PDFOutlineViewer; +}(); + +exports.PDFOutlineViewer = PDFOutlineViewer; + +/***/ }), +/* 18 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.PDFPresentationMode = undefined; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _ui_utils = __webpack_require__(0); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var DELAY_BEFORE_RESETTING_SWITCH_IN_PROGRESS = 1500; +var DELAY_BEFORE_HIDING_CONTROLS = 3000; +var ACTIVE_SELECTOR = 'pdfPresentationMode'; +var CONTROLS_SELECTOR = 'pdfPresentationModeControls'; +var MOUSE_SCROLL_COOLDOWN_TIME = 50; +var PAGE_SWITCH_THRESHOLD = 0.1; +var SWIPE_MIN_DISTANCE_THRESHOLD = 50; +var SWIPE_ANGLE_THRESHOLD = Math.PI / 6; + +var PDFPresentationMode = function () { + function PDFPresentationMode(_ref) { + var _this = this; + + var container = _ref.container, + _ref$viewer = _ref.viewer, + viewer = _ref$viewer === undefined ? null : _ref$viewer, + pdfViewer = _ref.pdfViewer, + eventBus = _ref.eventBus, + _ref$contextMenuItems = _ref.contextMenuItems, + contextMenuItems = _ref$contextMenuItems === undefined ? null : _ref$contextMenuItems; + + _classCallCheck(this, PDFPresentationMode); + + this.container = container; + this.viewer = viewer || container.firstElementChild; + this.pdfViewer = pdfViewer; + this.eventBus = eventBus; + this.active = false; + this.args = null; + this.contextMenuOpen = false; + this.mouseScrollTimeStamp = 0; + this.mouseScrollDelta = 0; + this.touchSwipeState = null; + if (contextMenuItems) { + contextMenuItems.contextFirstPage.addEventListener('click', function () { + _this.contextMenuOpen = false; + _this.eventBus.dispatch('firstpage'); + }); + contextMenuItems.contextLastPage.addEventListener('click', function () { + _this.contextMenuOpen = false; + _this.eventBus.dispatch('lastpage'); + }); + contextMenuItems.contextPageRotateCw.addEventListener('click', function () { + _this.contextMenuOpen = false; + _this.eventBus.dispatch('rotatecw'); + }); + contextMenuItems.contextPageRotateCcw.addEventListener('click', function () { + _this.contextMenuOpen = false; + _this.eventBus.dispatch('rotateccw'); + }); + } + } + + _createClass(PDFPresentationMode, [{ + key: 'request', + value: function request() { + if (this.switchInProgress || this.active || !this.viewer.hasChildNodes()) { + return false; + } + this._addFullscreenChangeListeners(); + this._setSwitchInProgress(); + this._notifyStateChange(); + if (this.container.requestFullscreen) { + this.container.requestFullscreen(); + } else if (this.container.mozRequestFullScreen) { + this.container.mozRequestFullScreen(); + } else if (this.container.webkitRequestFullscreen) { + this.container.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT); + } else if (this.container.msRequestFullscreen) { + this.container.msRequestFullscreen(); + } else { + return false; + } + this.args = { + page: this.pdfViewer.currentPageNumber, + previousScale: this.pdfViewer.currentScaleValue + }; + return true; + } + }, { + key: '_mouseWheel', + value: function _mouseWheel(evt) { + if (!this.active) { + return; + } + evt.preventDefault(); + var delta = (0, _ui_utils.normalizeWheelEventDelta)(evt); + var currentTime = new Date().getTime(); + var storedTime = this.mouseScrollTimeStamp; + if (currentTime > storedTime && currentTime - storedTime < MOUSE_SCROLL_COOLDOWN_TIME) { + return; + } + if (this.mouseScrollDelta > 0 && delta < 0 || this.mouseScrollDelta < 0 && delta > 0) { + this._resetMouseScrollState(); + } + this.mouseScrollDelta += delta; + if (Math.abs(this.mouseScrollDelta) >= PAGE_SWITCH_THRESHOLD) { + var totalDelta = this.mouseScrollDelta; + this._resetMouseScrollState(); + var success = totalDelta > 0 ? this._goToPreviousPage() : this._goToNextPage(); + if (success) { + this.mouseScrollTimeStamp = currentTime; + } + } + } + }, { + key: '_goToPreviousPage', + value: function _goToPreviousPage() { + var page = this.pdfViewer.currentPageNumber; + if (page <= 1) { + return false; + } + this.pdfViewer.currentPageNumber = page - 1; + return true; + } + }, { + key: '_goToNextPage', + value: function _goToNextPage() { + var page = this.pdfViewer.currentPageNumber; + if (page >= this.pdfViewer.pagesCount) { + return false; + } + this.pdfViewer.currentPageNumber = page + 1; + return true; + } + }, { + key: '_notifyStateChange', + value: function _notifyStateChange() { + this.eventBus.dispatch('presentationmodechanged', { + source: this, + active: this.active, + switchInProgress: !!this.switchInProgress + }); + } + }, { + key: '_setSwitchInProgress', + value: function _setSwitchInProgress() { + var _this2 = this; + + if (this.switchInProgress) { + clearTimeout(this.switchInProgress); + } + this.switchInProgress = setTimeout(function () { + _this2._removeFullscreenChangeListeners(); + delete _this2.switchInProgress; + _this2._notifyStateChange(); + }, DELAY_BEFORE_RESETTING_SWITCH_IN_PROGRESS); + } + }, { + key: '_resetSwitchInProgress', + value: function _resetSwitchInProgress() { + if (this.switchInProgress) { + clearTimeout(this.switchInProgress); + delete this.switchInProgress; + } + } + }, { + key: '_enter', + value: function _enter() { + var _this3 = this; + + this.active = true; + this._resetSwitchInProgress(); + this._notifyStateChange(); + this.container.classList.add(ACTIVE_SELECTOR); + setTimeout(function () { + _this3.pdfViewer.currentPageNumber = _this3.args.page; + _this3.pdfViewer.currentScaleValue = 'page-fit'; + }, 0); + this._addWindowListeners(); + this._showControls(); + this.contextMenuOpen = false; + this.container.setAttribute('contextmenu', 'viewerContextMenu'); + window.getSelection().removeAllRanges(); + } + }, { + key: '_exit', + value: function _exit() { + var _this4 = this; + + var page = this.pdfViewer.currentPageNumber; + this.container.classList.remove(ACTIVE_SELECTOR); + setTimeout(function () { + _this4.active = false; + _this4._removeFullscreenChangeListeners(); + _this4._notifyStateChange(); + _this4.pdfViewer.currentScaleValue = _this4.args.previousScale; + _this4.pdfViewer.currentPageNumber = page; + _this4.args = null; + }, 0); + this._removeWindowListeners(); + this._hideControls(); + this._resetMouseScrollState(); + this.container.removeAttribute('contextmenu'); + this.contextMenuOpen = false; + } + }, { + key: '_mouseDown', + value: function _mouseDown(evt) { + if (this.contextMenuOpen) { + this.contextMenuOpen = false; + evt.preventDefault(); + return; + } + if (evt.button === 0) { + var isInternalLink = evt.target.href && evt.target.classList.contains('internalLink'); + if (!isInternalLink) { + evt.preventDefault(); + if (evt.shiftKey) { + this._goToPreviousPage(); + } else { + this._goToNextPage(); + } + } + } + } + }, { + key: '_contextMenu', + value: function _contextMenu() { + this.contextMenuOpen = true; + } + }, { + key: '_showControls', + value: function _showControls() { + var _this5 = this; + + if (this.controlsTimeout) { + clearTimeout(this.controlsTimeout); + } else { + this.container.classList.add(CONTROLS_SELECTOR); + } + this.controlsTimeout = setTimeout(function () { + _this5.container.classList.remove(CONTROLS_SELECTOR); + delete _this5.controlsTimeout; + }, DELAY_BEFORE_HIDING_CONTROLS); + } + }, { + key: '_hideControls', + value: function _hideControls() { + if (!this.controlsTimeout) { + return; + } + clearTimeout(this.controlsTimeout); + this.container.classList.remove(CONTROLS_SELECTOR); + delete this.controlsTimeout; + } + }, { + key: '_resetMouseScrollState', + value: function _resetMouseScrollState() { + this.mouseScrollTimeStamp = 0; + this.mouseScrollDelta = 0; + } + }, { + key: '_touchSwipe', + value: function _touchSwipe(evt) { + if (!this.active) { + return; + } + if (evt.touches.length > 1) { + this.touchSwipeState = null; + return; + } + switch (evt.type) { + case 'touchstart': + this.touchSwipeState = { + startX: evt.touches[0].pageX, + startY: evt.touches[0].pageY, + endX: evt.touches[0].pageX, + endY: evt.touches[0].pageY + }; + break; + case 'touchmove': + if (this.touchSwipeState === null) { + return; + } + this.touchSwipeState.endX = evt.touches[0].pageX; + this.touchSwipeState.endY = evt.touches[0].pageY; + evt.preventDefault(); + break; + case 'touchend': + if (this.touchSwipeState === null) { + return; + } + var delta = 0; + var dx = this.touchSwipeState.endX - this.touchSwipeState.startX; + var dy = this.touchSwipeState.endY - this.touchSwipeState.startY; + var absAngle = Math.abs(Math.atan2(dy, dx)); + if (Math.abs(dx) > SWIPE_MIN_DISTANCE_THRESHOLD && (absAngle <= SWIPE_ANGLE_THRESHOLD || absAngle >= Math.PI - SWIPE_ANGLE_THRESHOLD)) { + delta = dx; + } else if (Math.abs(dy) > SWIPE_MIN_DISTANCE_THRESHOLD && Math.abs(absAngle - Math.PI / 2) <= SWIPE_ANGLE_THRESHOLD) { + delta = dy; + } + if (delta > 0) { + this._goToPreviousPage(); + } else if (delta < 0) { + this._goToNextPage(); + } + break; + } + } + }, { + key: '_addWindowListeners', + value: function _addWindowListeners() { + this.showControlsBind = this._showControls.bind(this); + this.mouseDownBind = this._mouseDown.bind(this); + this.mouseWheelBind = this._mouseWheel.bind(this); + this.resetMouseScrollStateBind = this._resetMouseScrollState.bind(this); + this.contextMenuBind = this._contextMenu.bind(this); + this.touchSwipeBind = this._touchSwipe.bind(this); + window.addEventListener('mousemove', this.showControlsBind); + window.addEventListener('mousedown', this.mouseDownBind); + window.addEventListener('wheel', this.mouseWheelBind); + window.addEventListener('keydown', this.resetMouseScrollStateBind); + window.addEventListener('contextmenu', this.contextMenuBind); + window.addEventListener('touchstart', this.touchSwipeBind); + window.addEventListener('touchmove', this.touchSwipeBind); + window.addEventListener('touchend', this.touchSwipeBind); + } + }, { + key: '_removeWindowListeners', + value: function _removeWindowListeners() { + window.removeEventListener('mousemove', this.showControlsBind); + window.removeEventListener('mousedown', this.mouseDownBind); + window.removeEventListener('wheel', this.mouseWheelBind); + window.removeEventListener('keydown', this.resetMouseScrollStateBind); + window.removeEventListener('contextmenu', this.contextMenuBind); + window.removeEventListener('touchstart', this.touchSwipeBind); + window.removeEventListener('touchmove', this.touchSwipeBind); + window.removeEventListener('touchend', this.touchSwipeBind); + delete this.showControlsBind; + delete this.mouseDownBind; + delete this.mouseWheelBind; + delete this.resetMouseScrollStateBind; + delete this.contextMenuBind; + delete this.touchSwipeBind; + } + }, { + key: '_fullscreenChange', + value: function _fullscreenChange() { + if (this.isFullscreen) { + this._enter(); + } else { + this._exit(); + } + } + }, { + key: '_addFullscreenChangeListeners', + value: function _addFullscreenChangeListeners() { + this.fullscreenChangeBind = this._fullscreenChange.bind(this); + window.addEventListener('fullscreenchange', this.fullscreenChangeBind); + window.addEventListener('mozfullscreenchange', this.fullscreenChangeBind); + window.addEventListener('webkitfullscreenchange', this.fullscreenChangeBind); + window.addEventListener('MSFullscreenChange', this.fullscreenChangeBind); + } + }, { + key: '_removeFullscreenChangeListeners', + value: function _removeFullscreenChangeListeners() { + window.removeEventListener('fullscreenchange', this.fullscreenChangeBind); + window.removeEventListener('mozfullscreenchange', this.fullscreenChangeBind); + window.removeEventListener('webkitfullscreenchange', this.fullscreenChangeBind); + window.removeEventListener('MSFullscreenChange', this.fullscreenChangeBind); + delete this.fullscreenChangeBind; + } + }, { + key: 'isFullscreen', + get: function get() { + return !!(document.fullscreenElement || document.mozFullScreen || document.webkitIsFullScreen || document.msFullscreenElement); + } + }]); + + return PDFPresentationMode; +}(); + +exports.PDFPresentationMode = PDFPresentationMode; + +/***/ }), +/* 19 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.PDFThumbnailViewer = undefined; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _ui_utils = __webpack_require__(0); + +var _pdf_thumbnail_view = __webpack_require__(20); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var THUMBNAIL_SCROLL_MARGIN = -19; + +var PDFThumbnailViewer = function () { + function PDFThumbnailViewer(_ref) { + var container = _ref.container, + linkService = _ref.linkService, + renderingQueue = _ref.renderingQueue, + _ref$l10n = _ref.l10n, + l10n = _ref$l10n === undefined ? _ui_utils.NullL10n : _ref$l10n; + + _classCallCheck(this, PDFThumbnailViewer); + + this.container = container; + this.linkService = linkService; + this.renderingQueue = renderingQueue; + this.l10n = l10n; + this.scroll = (0, _ui_utils.watchScroll)(this.container, this._scrollUpdated.bind(this)); + this._resetView(); + } + + _createClass(PDFThumbnailViewer, [{ + key: '_scrollUpdated', + value: function _scrollUpdated() { + this.renderingQueue.renderHighestPriority(); + } + }, { + key: 'getThumbnail', + value: function getThumbnail(index) { + return this._thumbnails[index]; + } + }, { + key: '_getVisibleThumbs', + value: function _getVisibleThumbs() { + return (0, _ui_utils.getVisibleElements)(this.container, this._thumbnails); + } + }, { + key: 'scrollThumbnailIntoView', + value: function scrollThumbnailIntoView(page) { + var selected = document.querySelector('.thumbnail.selected'); + if (selected) { + selected.classList.remove('selected'); + } + var thumbnail = document.querySelector('div.thumbnail[data-page-number="' + page + '"]'); + if (thumbnail) { + thumbnail.classList.add('selected'); + } + var visibleThumbs = this._getVisibleThumbs(); + var numVisibleThumbs = visibleThumbs.views.length; + if (numVisibleThumbs > 0) { + var first = visibleThumbs.first.id; + var last = numVisibleThumbs > 1 ? visibleThumbs.last.id : first; + if (page <= first || page >= last) { + (0, _ui_utils.scrollIntoView)(thumbnail, { top: THUMBNAIL_SCROLL_MARGIN }); + } + } + } + }, { + key: 'cleanup', + value: function cleanup() { + _pdf_thumbnail_view.PDFThumbnailView.cleanup(); + } + }, { + key: '_resetView', + value: function _resetView() { + this._thumbnails = []; + this._pageLabels = null; + this._pagesRotation = 0; + this._pagesRequests = []; + this.container.textContent = ''; + } + }, { + key: 'setDocument', + value: function setDocument(pdfDocument) { + var _this = this; + + if (this.pdfDocument) { + this._cancelRendering(); + this._resetView(); + } + this.pdfDocument = pdfDocument; + if (!pdfDocument) { + return; + } + pdfDocument.getPage(1).then(function (firstPage) { + var pagesCount = pdfDocument.numPages; + var viewport = firstPage.getViewport(1.0); + for (var pageNum = 1; pageNum <= pagesCount; ++pageNum) { + var thumbnail = new _pdf_thumbnail_view.PDFThumbnailView({ + container: _this.container, + id: pageNum, + defaultViewport: viewport.clone(), + linkService: _this.linkService, + renderingQueue: _this.renderingQueue, + disableCanvasToImageConversion: false, + l10n: _this.l10n + }); + _this._thumbnails.push(thumbnail); + } + }).catch(function (reason) { + console.error('Unable to initialize thumbnail viewer', reason); + }); + } + }, { + key: '_cancelRendering', + value: function _cancelRendering() { + for (var i = 0, ii = this._thumbnails.length; i < ii; i++) { + if (this._thumbnails[i]) { + this._thumbnails[i].cancelRendering(); + } + } + } + }, { + key: 'setPageLabels', + value: function setPageLabels(labels) { + if (!this.pdfDocument) { + return; + } + if (!labels) { + this._pageLabels = null; + } else if (!(labels instanceof Array && this.pdfDocument.numPages === labels.length)) { + this._pageLabels = null; + console.error('PDFThumbnailViewer_setPageLabels: Invalid page labels.'); + } else { + this._pageLabels = labels; + } + for (var i = 0, ii = this._thumbnails.length; i < ii; i++) { + var label = this._pageLabels && this._pageLabels[i]; + this._thumbnails[i].setPageLabel(label); + } + } + }, { + key: '_ensurePdfPageLoaded', + value: function _ensurePdfPageLoaded(thumbView) { + var _this2 = this; + + if (thumbView.pdfPage) { + return Promise.resolve(thumbView.pdfPage); + } + var pageNumber = thumbView.id; + if (this._pagesRequests[pageNumber]) { + return this._pagesRequests[pageNumber]; + } + var promise = this.pdfDocument.getPage(pageNumber).then(function (pdfPage) { + thumbView.setPdfPage(pdfPage); + _this2._pagesRequests[pageNumber] = null; + return pdfPage; + }).catch(function (reason) { + console.error('Unable to get page for thumb view', reason); + _this2._pagesRequests[pageNumber] = null; + }); + this._pagesRequests[pageNumber] = promise; + return promise; + } + }, { + key: 'forceRendering', + value: function forceRendering() { + var _this3 = this; + + var visibleThumbs = this._getVisibleThumbs(); + var thumbView = this.renderingQueue.getHighestPriority(visibleThumbs, this._thumbnails, this.scroll.down); + if (thumbView) { + this._ensurePdfPageLoaded(thumbView).then(function () { + _this3.renderingQueue.renderView(thumbView); + }); + return true; + } + return false; + } + }, { + key: 'pagesRotation', + get: function get() { + return this._pagesRotation; + }, + set: function set(rotation) { + if (!(0, _ui_utils.isValidRotation)(rotation)) { + throw new Error('Invalid thumbnails rotation angle.'); + } + if (!this.pdfDocument) { + return; + } + if (this._pagesRotation === rotation) { + return; + } + this._pagesRotation = rotation; + for (var i = 0, ii = this._thumbnails.length; i < ii; i++) { + this._thumbnails[i].update(rotation); + } + } + }]); + + return PDFThumbnailViewer; +}(); + +exports.PDFThumbnailViewer = PDFThumbnailViewer; + +/***/ }), +/* 20 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.PDFThumbnailView = undefined; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _pdfjsLib = __webpack_require__(1); + +var _ui_utils = __webpack_require__(0); + +var _pdf_rendering_queue = __webpack_require__(3); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var MAX_NUM_SCALING_STEPS = 3; +var THUMBNAIL_CANVAS_BORDER_WIDTH = 1; +var THUMBNAIL_WIDTH = 98; +var TempImageFactory = function TempImageFactoryClosure() { + var tempCanvasCache = null; + return { + getCanvas: function getCanvas(width, height) { + var tempCanvas = tempCanvasCache; + if (!tempCanvas) { + tempCanvas = document.createElement('canvas'); + tempCanvasCache = tempCanvas; + } + tempCanvas.width = width; + tempCanvas.height = height; + tempCanvas.mozOpaque = true; + var ctx = tempCanvas.getContext('2d', { alpha: false }); + ctx.save(); + ctx.fillStyle = 'rgb(255, 255, 255)'; + ctx.fillRect(0, 0, width, height); + ctx.restore(); + return tempCanvas; + }, + destroyCanvas: function destroyCanvas() { + var tempCanvas = tempCanvasCache; + if (tempCanvas) { + tempCanvas.width = 0; + tempCanvas.height = 0; + } + tempCanvasCache = null; + } + }; +}(); + +var PDFThumbnailView = function () { + function PDFThumbnailView(_ref) { + var container = _ref.container, + id = _ref.id, + defaultViewport = _ref.defaultViewport, + linkService = _ref.linkService, + renderingQueue = _ref.renderingQueue, + _ref$disableCanvasToI = _ref.disableCanvasToImageConversion, + disableCanvasToImageConversion = _ref$disableCanvasToI === undefined ? false : _ref$disableCanvasToI, + _ref$l10n = _ref.l10n, + l10n = _ref$l10n === undefined ? _ui_utils.NullL10n : _ref$l10n; + + _classCallCheck(this, PDFThumbnailView); + + this.id = id; + this.renderingId = 'thumbnail' + id; + this.pageLabel = null; + this.pdfPage = null; + this.rotation = 0; + this.viewport = defaultViewport; + this.pdfPageRotate = defaultViewport.rotation; + this.linkService = linkService; + this.renderingQueue = renderingQueue; + this.renderTask = null; + this.renderingState = _pdf_rendering_queue.RenderingStates.INITIAL; + this.resume = null; + this.disableCanvasToImageConversion = disableCanvasToImageConversion; + this.pageWidth = this.viewport.width; + this.pageHeight = this.viewport.height; + this.pageRatio = this.pageWidth / this.pageHeight; + this.canvasWidth = THUMBNAIL_WIDTH; + this.canvasHeight = this.canvasWidth / this.pageRatio | 0; + this.scale = this.canvasWidth / this.pageWidth; + this.l10n = l10n; + var anchor = document.createElement('a'); + anchor.href = linkService.getAnchorUrl('#page=' + id); + this.l10n.get('thumb_page_title', { page: id }, 'Page {{page}}').then(function (msg) { + anchor.title = msg; + }); + anchor.onclick = function () { + linkService.page = id; + return false; + }; + this.anchor = anchor; + var div = document.createElement('div'); + div.className = 'thumbnail'; + div.setAttribute('data-page-number', this.id); + this.div = div; + if (id === 1) { + div.classList.add('selected'); + } + var ring = document.createElement('div'); + ring.className = 'thumbnailSelectionRing'; + var borderAdjustment = 2 * THUMBNAIL_CANVAS_BORDER_WIDTH; + ring.style.width = this.canvasWidth + borderAdjustment + 'px'; + ring.style.height = this.canvasHeight + borderAdjustment + 'px'; + this.ring = ring; + div.appendChild(ring); + anchor.appendChild(div); + container.appendChild(anchor); + } + + _createClass(PDFThumbnailView, [{ + key: 'setPdfPage', + value: function setPdfPage(pdfPage) { + this.pdfPage = pdfPage; + this.pdfPageRotate = pdfPage.rotate; + var totalRotation = (this.rotation + this.pdfPageRotate) % 360; + this.viewport = pdfPage.getViewport(1, totalRotation); + this.reset(); + } + }, { + key: 'reset', + value: function reset() { + this.cancelRendering(); + this.pageWidth = this.viewport.width; + this.pageHeight = this.viewport.height; + this.pageRatio = this.pageWidth / this.pageHeight; + this.canvasHeight = this.canvasWidth / this.pageRatio | 0; + this.scale = this.canvasWidth / this.pageWidth; + this.div.removeAttribute('data-loaded'); + var ring = this.ring; + var childNodes = ring.childNodes; + for (var i = childNodes.length - 1; i >= 0; i--) { + ring.removeChild(childNodes[i]); + } + var borderAdjustment = 2 * THUMBNAIL_CANVAS_BORDER_WIDTH; + ring.style.width = this.canvasWidth + borderAdjustment + 'px'; + ring.style.height = this.canvasHeight + borderAdjustment + 'px'; + if (this.canvas) { + this.canvas.width = 0; + this.canvas.height = 0; + delete this.canvas; + } + if (this.image) { + this.image.removeAttribute('src'); + delete this.image; + } + } + }, { + key: 'update', + value: function update(rotation) { + if (typeof rotation !== 'undefined') { + this.rotation = rotation; + } + var totalRotation = (this.rotation + this.pdfPageRotate) % 360; + this.viewport = this.viewport.clone({ + scale: 1, + rotation: totalRotation + }); + this.reset(); + } + }, { + key: 'cancelRendering', + value: function cancelRendering() { + if (this.renderTask) { + this.renderTask.cancel(); + this.renderTask = null; + } + this.renderingState = _pdf_rendering_queue.RenderingStates.INITIAL; + this.resume = null; + } + }, { + key: '_getPageDrawContext', + value: function _getPageDrawContext() { + var noCtxScale = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + + var canvas = document.createElement('canvas'); + this.canvas = canvas; + canvas.mozOpaque = true; + var ctx = canvas.getContext('2d', { alpha: false }); + var outputScale = (0, _ui_utils.getOutputScale)(ctx); + canvas.width = this.canvasWidth * outputScale.sx | 0; + canvas.height = this.canvasHeight * outputScale.sy | 0; + canvas.style.width = this.canvasWidth + 'px'; + canvas.style.height = this.canvasHeight + 'px'; + if (!noCtxScale && outputScale.scaled) { + ctx.scale(outputScale.sx, outputScale.sy); + } + return ctx; + } + }, { + key: '_convertCanvasToImage', + value: function _convertCanvasToImage() { + var _this = this; + + if (!this.canvas) { + return; + } + if (this.renderingState !== _pdf_rendering_queue.RenderingStates.FINISHED) { + return; + } + var id = this.renderingId; + var className = 'thumbnailImage'; + if (this.disableCanvasToImageConversion) { + this.canvas.id = id; + this.canvas.className = className; + this.l10n.get('thumb_page_canvas', { page: this.pageId }, 'Thumbnail of Page {{page}}').then(function (msg) { + _this.canvas.setAttribute('aria-label', msg); + }); + this.div.setAttribute('data-loaded', true); + this.ring.appendChild(this.canvas); + return; + } + var image = document.createElement('img'); + image.id = id; + image.className = className; + this.l10n.get('thumb_page_canvas', { page: this.pageId }, 'Thumbnail of Page {{page}}').then(function (msg) { + image.setAttribute('aria-label', msg); + }); + image.style.width = this.canvasWidth + 'px'; + image.style.height = this.canvasHeight + 'px'; + image.src = this.canvas.toDataURL(); + this.image = image; + this.div.setAttribute('data-loaded', true); + this.ring.appendChild(image); + this.canvas.width = 0; + this.canvas.height = 0; + delete this.canvas; + } + }, { + key: 'draw', + value: function draw() { + var _this2 = this; + + if (this.renderingState !== _pdf_rendering_queue.RenderingStates.INITIAL) { + console.error('Must be in new state before drawing'); + return Promise.resolve(undefined); + } + this.renderingState = _pdf_rendering_queue.RenderingStates.RUNNING; + var renderCapability = (0, _pdfjsLib.createPromiseCapability)(); + var finishRenderTask = function finishRenderTask(error) { + if (renderTask === _this2.renderTask) { + _this2.renderTask = null; + } + if (error === 'cancelled' || error instanceof _pdfjsLib.RenderingCancelledException) { + renderCapability.resolve(undefined); + return; + } + _this2.renderingState = _pdf_rendering_queue.RenderingStates.FINISHED; + _this2._convertCanvasToImage(); + if (!error) { + renderCapability.resolve(undefined); + } else { + renderCapability.reject(error); + } + }; + var ctx = this._getPageDrawContext(); + var drawViewport = this.viewport.clone({ scale: this.scale }); + var renderContinueCallback = function renderContinueCallback(cont) { + if (!_this2.renderingQueue.isHighestPriority(_this2)) { + _this2.renderingState = _pdf_rendering_queue.RenderingStates.PAUSED; + _this2.resume = function () { + _this2.renderingState = _pdf_rendering_queue.RenderingStates.RUNNING; + cont(); + }; + return; + } + cont(); + }; + var renderContext = { + canvasContext: ctx, + viewport: drawViewport + }; + var renderTask = this.renderTask = this.pdfPage.render(renderContext); + renderTask.onContinue = renderContinueCallback; + renderTask.promise.then(function () { + finishRenderTask(null); + }, function (error) { + finishRenderTask(error); + }); + return renderCapability.promise; + } + }, { + key: 'setImage', + value: function setImage(pageView) { + if (this.renderingState !== _pdf_rendering_queue.RenderingStates.INITIAL) { + return; + } + var img = pageView.canvas; + if (!img) { + return; + } + if (!this.pdfPage) { + this.setPdfPage(pageView.pdfPage); + } + this.renderingState = _pdf_rendering_queue.RenderingStates.FINISHED; + var ctx = this._getPageDrawContext(true); + var canvas = ctx.canvas; + if (img.width <= 2 * canvas.width) { + ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, canvas.width, canvas.height); + this._convertCanvasToImage(); + return; + } + var reducedWidth = canvas.width << MAX_NUM_SCALING_STEPS; + var reducedHeight = canvas.height << MAX_NUM_SCALING_STEPS; + var reducedImage = TempImageFactory.getCanvas(reducedWidth, reducedHeight); + var reducedImageCtx = reducedImage.getContext('2d'); + while (reducedWidth > img.width || reducedHeight > img.height) { + reducedWidth >>= 1; + reducedHeight >>= 1; + } + reducedImageCtx.drawImage(img, 0, 0, img.width, img.height, 0, 0, reducedWidth, reducedHeight); + while (reducedWidth > 2 * canvas.width) { + reducedImageCtx.drawImage(reducedImage, 0, 0, reducedWidth, reducedHeight, 0, 0, reducedWidth >> 1, reducedHeight >> 1); + reducedWidth >>= 1; + reducedHeight >>= 1; + } + ctx.drawImage(reducedImage, 0, 0, reducedWidth, reducedHeight, 0, 0, canvas.width, canvas.height); + this._convertCanvasToImage(); + } + }, { + key: 'setPageLabel', + value: function setPageLabel(label) { + var _this3 = this; + + this.pageLabel = typeof label === 'string' ? label : null; + this.l10n.get('thumb_page_title', { page: this.pageId }, 'Page {{page}}').then(function (msg) { + _this3.anchor.title = msg; + }); + if (this.renderingState !== _pdf_rendering_queue.RenderingStates.FINISHED) { + return; + } + this.l10n.get('thumb_page_canvas', { page: this.pageId }, 'Thumbnail of Page {{page}}').then(function (ariaLabel) { + if (_this3.image) { + _this3.image.setAttribute('aria-label', ariaLabel); + } else if (_this3.disableCanvasToImageConversion && _this3.canvas) { + _this3.canvas.setAttribute('aria-label', ariaLabel); + } + }); + } + }, { + key: 'pageId', + get: function get() { + return this.pageLabel !== null ? this.pageLabel : this.id; + } + }], [{ + key: 'cleanup', + value: function cleanup() { + TempImageFactory.destroyCanvas(); + } + }]); + + return PDFThumbnailView; +}(); + +exports.PDFThumbnailView = PDFThumbnailView; + +/***/ }), +/* 21 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.PDFViewer = undefined; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _ui_utils = __webpack_require__(0); + +var _base_viewer = __webpack_require__(22); + +var _pdfjsLib = __webpack_require__(1); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var PDFViewer = function (_BaseViewer) { + _inherits(PDFViewer, _BaseViewer); + + function PDFViewer() { + _classCallCheck(this, PDFViewer); + + return _possibleConstructorReturn(this, (PDFViewer.__proto__ || Object.getPrototypeOf(PDFViewer)).apply(this, arguments)); + } + + _createClass(PDFViewer, [{ + key: '_scrollIntoView', + value: function _scrollIntoView(_ref) { + var pageDiv = _ref.pageDiv, + _ref$pageSpot = _ref.pageSpot, + pageSpot = _ref$pageSpot === undefined ? null : _ref$pageSpot; + + (0, _ui_utils.scrollIntoView)(pageDiv, pageSpot); + } + }, { + key: '_getVisiblePages', + value: function _getVisiblePages() { + if (!this.isInPresentationMode) { + return (0, _ui_utils.getVisibleElements)(this.container, this._pages, true); + } + var currentPage = this._pages[this._currentPageNumber - 1]; + var visible = [{ + id: currentPage.id, + view: currentPage + }]; + return { + first: currentPage, + last: currentPage, + views: visible + }; + } + }, { + key: 'update', + value: function update() { + var visible = this._getVisiblePages(); + var visiblePages = visible.views, + numVisiblePages = visiblePages.length; + if (numVisiblePages === 0) { + return; + } + this._resizeBuffer(numVisiblePages); + this.renderingQueue.renderHighestPriority(visible); + var currentId = this._currentPageNumber; + var stillFullyVisible = false; + for (var i = 0; i < numVisiblePages; ++i) { + var page = visiblePages[i]; + if (page.percent < 100) { + break; + } + if (page.id === currentId) { + stillFullyVisible = true; + break; + } + } + if (!stillFullyVisible) { + currentId = visiblePages[0].id; + } + if (!this.isInPresentationMode) { + this._setCurrentPageNumber(currentId); + } + this._updateLocation(visible.first); + this.eventBus.dispatch('updateviewarea', { + source: this, + location: this._location + }); + } + }, { + key: '_setDocumentViewerElement', + get: function get() { + return (0, _pdfjsLib.shadow)(this, '_setDocumentViewerElement', this.viewer); + } + }]); + + return PDFViewer; +}(_base_viewer.BaseViewer); + +exports.PDFViewer = PDFViewer; + +/***/ }), +/* 22 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.BaseViewer = undefined; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _pdfjsLib = __webpack_require__(1); + +var _ui_utils = __webpack_require__(0); + +var _pdf_rendering_queue = __webpack_require__(3); + +var _annotation_layer_builder = __webpack_require__(23); + +var _dom_events = __webpack_require__(2); + +var _pdf_page_view = __webpack_require__(24); + +var _pdf_link_service = __webpack_require__(5); + +var _text_layer_builder = __webpack_require__(25); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var DEFAULT_CACHE_SIZE = 10; +function PDFPageViewBuffer(size) { + var data = []; + this.push = function (view) { + var i = data.indexOf(view); + if (i >= 0) { + data.splice(i, 1); + } + data.push(view); + if (data.length > size) { + data.shift().destroy(); + } + }; + this.resize = function (newSize) { + size = newSize; + while (data.length > size) { + data.shift().destroy(); + } + }; +} +function isSameScale(oldScale, newScale) { + if (newScale === oldScale) { + return true; + } + if (Math.abs(newScale - oldScale) < 1e-15) { + return true; + } + return false; +} +function isPortraitOrientation(size) { + return size.width <= size.height; +} + +var BaseViewer = function () { + function BaseViewer(options) { + _classCallCheck(this, BaseViewer); + + if (this.constructor === BaseViewer) { + throw new Error('Cannot initialize BaseViewer.'); + } + this._name = this.constructor.name; + this.container = options.container; + this.viewer = options.viewer || options.container.firstElementChild; + this.eventBus = options.eventBus || (0, _dom_events.getGlobalEventBus)(); + this.linkService = options.linkService || new _pdf_link_service.SimpleLinkService(); + this.downloadManager = options.downloadManager || null; + this.removePageBorders = options.removePageBorders || false; + this.enhanceTextSelection = options.enhanceTextSelection || false; + this.renderInteractiveForms = options.renderInteractiveForms || false; + this.enablePrintAutoRotate = options.enablePrintAutoRotate || false; + this.renderer = options.renderer || _ui_utils.RendererType.CANVAS; + this.l10n = options.l10n || _ui_utils.NullL10n; + this.defaultRenderingQueue = !options.renderingQueue; + if (this.defaultRenderingQueue) { + this.renderingQueue = new _pdf_rendering_queue.PDFRenderingQueue(); + this.renderingQueue.setViewer(this); + } else { + this.renderingQueue = options.renderingQueue; + } + this.scroll = (0, _ui_utils.watchScroll)(this.container, this._scrollUpdate.bind(this)); + this.presentationModeState = _ui_utils.PresentationModeState.UNKNOWN; + this._resetView(); + if (this.removePageBorders) { + this.viewer.classList.add('removePageBorders'); + } + } + + _createClass(BaseViewer, [{ + key: 'getPageView', + value: function getPageView(index) { + return this._pages[index]; + } + }, { + key: '_setCurrentPageNumber', + value: function _setCurrentPageNumber(val) { + var resetCurrentPageView = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + if (this._currentPageNumber === val) { + if (resetCurrentPageView) { + this._resetCurrentPageView(); + } + return; + } + if (!(0 < val && val <= this.pagesCount)) { + console.error(this._name + '._setCurrentPageNumber: "' + val + '" is out of bounds.'); + return; + } + var arg = { + source: this, + pageNumber: val, + pageLabel: this._pageLabels && this._pageLabels[val - 1] + }; + this._currentPageNumber = val; + this.eventBus.dispatch('pagechanging', arg); + this.eventBus.dispatch('pagechange', arg); + if (resetCurrentPageView) { + this._resetCurrentPageView(); + } + } + }, { + key: 'setDocument', + value: function setDocument(pdfDocument) { + var _this = this; + + if (this.pdfDocument) { + this._cancelRendering(); + this._resetView(); + } + this.pdfDocument = pdfDocument; + if (!pdfDocument) { + return; + } + var pagesCount = pdfDocument.numPages; + var pagesCapability = (0, _pdfjsLib.createPromiseCapability)(); + this.pagesPromise = pagesCapability.promise; + pagesCapability.promise.then(function () { + _this._pageViewsReady = true; + _this.eventBus.dispatch('pagesloaded', { + source: _this, + pagesCount: pagesCount + }); + }); + var isOnePageRenderedResolved = false; + var onePageRenderedCapability = (0, _pdfjsLib.createPromiseCapability)(); + this.onePageRendered = onePageRenderedCapability.promise; + var bindOnAfterAndBeforeDraw = function bindOnAfterAndBeforeDraw(pageView) { + pageView.onBeforeDraw = function () { + _this._buffer.push(pageView); + }; + pageView.onAfterDraw = function () { + if (!isOnePageRenderedResolved) { + isOnePageRenderedResolved = true; + onePageRenderedCapability.resolve(); + } + }; + }; + var firstPagePromise = pdfDocument.getPage(1); + this.firstPagePromise = firstPagePromise; + firstPagePromise.then(function (pdfPage) { + var scale = _this.currentScale; + var viewport = pdfPage.getViewport(scale * _ui_utils.CSS_UNITS); + for (var pageNum = 1; pageNum <= pagesCount; ++pageNum) { + var textLayerFactory = null; + if (!_pdfjsLib.PDFJS.disableTextLayer) { + textLayerFactory = _this; + } + var pageView = new _pdf_page_view.PDFPageView({ + container: _this._setDocumentViewerElement, + eventBus: _this.eventBus, + id: pageNum, + scale: scale, + defaultViewport: viewport.clone(), + renderingQueue: _this.renderingQueue, + textLayerFactory: textLayerFactory, + annotationLayerFactory: _this, + enhanceTextSelection: _this.enhanceTextSelection, + renderInteractiveForms: _this.renderInteractiveForms, + renderer: _this.renderer, + l10n: _this.l10n + }); + bindOnAfterAndBeforeDraw(pageView); + _this._pages.push(pageView); + } + onePageRenderedCapability.promise.then(function () { + if (_pdfjsLib.PDFJS.disableAutoFetch) { + pagesCapability.resolve(); + return; + } + var getPagesLeft = pagesCount; + + var _loop = function _loop(_pageNum) { + pdfDocument.getPage(_pageNum).then(function (pdfPage) { + var pageView = _this._pages[_pageNum - 1]; + if (!pageView.pdfPage) { + pageView.setPdfPage(pdfPage); + } + _this.linkService.cachePageRef(_pageNum, pdfPage.ref); + if (--getPagesLeft === 0) { + pagesCapability.resolve(); + } + }, function (reason) { + console.error('Unable to get page ' + _pageNum + ' to initialize viewer', reason); + if (--getPagesLeft === 0) { + pagesCapability.resolve(); + } + }); + }; + + for (var _pageNum = 1; _pageNum <= pagesCount; ++_pageNum) { + _loop(_pageNum); + } + }); + _this.eventBus.dispatch('pagesinit', { source: _this }); + if (_this.defaultRenderingQueue) { + _this.update(); + } + if (_this.findController) { + _this.findController.resolveFirstPage(); + } + }).catch(function (reason) { + console.error('Unable to initialize viewer', reason); + }); + } + }, { + key: 'setPageLabels', + value: function setPageLabels(labels) { + if (!this.pdfDocument) { + return; + } + if (!labels) { + this._pageLabels = null; + } else if (!(labels instanceof Array && this.pdfDocument.numPages === labels.length)) { + this._pageLabels = null; + console.error(this._name + '.setPageLabels: Invalid page labels.'); + } else { + this._pageLabels = labels; + } + for (var i = 0, ii = this._pages.length; i < ii; i++) { + var pageView = this._pages[i]; + var label = this._pageLabels && this._pageLabels[i]; + pageView.setPageLabel(label); + } + } + }, { + key: '_resetView', + value: function _resetView() { + this._pages = []; + this._currentPageNumber = 1; + this._currentScale = _ui_utils.UNKNOWN_SCALE; + this._currentScaleValue = null; + this._pageLabels = null; + this._buffer = new PDFPageViewBuffer(DEFAULT_CACHE_SIZE); + this._location = null; + this._pagesRotation = 0; + this._pagesRequests = []; + this._pageViewsReady = false; + this.viewer.textContent = ''; + } + }, { + key: '_scrollUpdate', + value: function _scrollUpdate() { + if (this.pagesCount === 0) { + return; + } + this.update(); + } + }, { + key: '_scrollIntoView', + value: function _scrollIntoView(_ref) { + var pageDiv = _ref.pageDiv, + _ref$pageSpot = _ref.pageSpot, + pageSpot = _ref$pageSpot === undefined ? null : _ref$pageSpot, + _ref$pageNumber = _ref.pageNumber, + pageNumber = _ref$pageNumber === undefined ? null : _ref$pageNumber; + + throw new Error('Not implemented: _scrollIntoView'); + } + }, { + key: '_setScaleDispatchEvent', + value: function _setScaleDispatchEvent(newScale, newValue) { + var preset = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + + var arg = { + source: this, + scale: newScale, + presetValue: preset ? newValue : undefined + }; + this.eventBus.dispatch('scalechanging', arg); + this.eventBus.dispatch('scalechange', arg); + } + }, { + key: '_setScaleUpdatePages', + value: function _setScaleUpdatePages(newScale, newValue) { + var noScroll = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + var preset = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; + + this._currentScaleValue = newValue.toString(); + if (isSameScale(this._currentScale, newScale)) { + if (preset) { + this._setScaleDispatchEvent(newScale, newValue, true); + } + return; + } + for (var i = 0, ii = this._pages.length; i < ii; i++) { + this._pages[i].update(newScale); + } + this._currentScale = newScale; + if (!noScroll) { + var page = this._currentPageNumber, + dest = void 0; + if (this._location && !_pdfjsLib.PDFJS.ignoreCurrentPositionOnZoom && !(this.isInPresentationMode || this.isChangingPresentationMode)) { + page = this._location.pageNumber; + dest = [null, { name: 'XYZ' }, this._location.left, this._location.top, null]; + } + this.scrollPageIntoView({ + pageNumber: page, + destArray: dest, + allowNegativeOffset: true + }); + } + this._setScaleDispatchEvent(newScale, newValue, preset); + if (this.defaultRenderingQueue) { + this.update(); + } + } + }, { + key: '_setScale', + value: function _setScale(value) { + var noScroll = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + var scale = parseFloat(value); + if (scale > 0) { + this._setScaleUpdatePages(scale, value, noScroll, false); + } else { + var currentPage = this._pages[this._currentPageNumber - 1]; + if (!currentPage) { + return; + } + var hPadding = this.isInPresentationMode || this.removePageBorders ? 0 : _ui_utils.SCROLLBAR_PADDING; + var vPadding = this.isInPresentationMode || this.removePageBorders ? 0 : _ui_utils.VERTICAL_PADDING; + var pageWidthScale = (this.container.clientWidth - hPadding) / currentPage.width * currentPage.scale; + var pageHeightScale = (this.container.clientHeight - vPadding) / currentPage.height * currentPage.scale; + switch (value) { + case 'page-actual': + scale = 1; + break; + case 'page-width': + scale = pageWidthScale; + break; + case 'page-height': + scale = pageHeightScale; + break; + case 'page-fit': + scale = Math.min(pageWidthScale, pageHeightScale); + break; + case 'auto': + var isLandscape = currentPage.width > currentPage.height; + var horizontalScale = isLandscape ? Math.min(pageHeightScale, pageWidthScale) : pageWidthScale; + scale = Math.min(_ui_utils.MAX_AUTO_SCALE, horizontalScale); + break; + default: + console.error(this._name + '._setScale: "' + value + '" is an unknown zoom value.'); + return; + } + this._setScaleUpdatePages(scale, value, noScroll, true); + } + } + }, { + key: '_resetCurrentPageView', + value: function _resetCurrentPageView() { + if (this.isInPresentationMode) { + this._setScale(this._currentScaleValue, true); + } + var pageView = this._pages[this._currentPageNumber - 1]; + this._scrollIntoView({ pageDiv: pageView.div }); + } + }, { + key: 'scrollPageIntoView', + value: function scrollPageIntoView(params) { + if (arguments.length > 1 || typeof params === 'number') { + console.error('Call of scrollPageIntoView() with obsolete signature.'); + return; + } + if (!this.pdfDocument) { + return; + } + var pageNumber = params.pageNumber || 0; + var dest = params.destArray || null; + var allowNegativeOffset = params.allowNegativeOffset || false; + if (this.isInPresentationMode || !dest) { + this._setCurrentPageNumber(pageNumber, true); + return; + } + var pageView = this._pages[pageNumber - 1]; + if (!pageView) { + console.error(this._name + '.scrollPageIntoView: Invalid "pageNumber" parameter.'); + return; + } + var x = 0, + y = 0; + var width = 0, + height = 0, + widthScale = void 0, + heightScale = void 0; + var changeOrientation = pageView.rotation % 180 === 0 ? false : true; + var pageWidth = (changeOrientation ? pageView.height : pageView.width) / pageView.scale / _ui_utils.CSS_UNITS; + var pageHeight = (changeOrientation ? pageView.width : pageView.height) / pageView.scale / _ui_utils.CSS_UNITS; + var scale = 0; + switch (dest[1].name) { + case 'XYZ': + x = dest[2]; + y = dest[3]; + scale = dest[4]; + x = x !== null ? x : 0; + y = y !== null ? y : pageHeight; + break; + case 'Fit': + case 'FitB': + scale = 'page-fit'; + break; + case 'FitH': + case 'FitBH': + y = dest[2]; + scale = 'page-width'; + if (y === null && this._location) { + x = this._location.left; + y = this._location.top; + } + break; + case 'FitV': + case 'FitBV': + x = dest[2]; + width = pageWidth; + height = pageHeight; + scale = 'page-height'; + break; + case 'FitR': + x = dest[2]; + y = dest[3]; + width = dest[4] - x; + height = dest[5] - y; + var hPadding = this.removePageBorders ? 0 : _ui_utils.SCROLLBAR_PADDING; + var vPadding = this.removePageBorders ? 0 : _ui_utils.VERTICAL_PADDING; + widthScale = (this.container.clientWidth - hPadding) / width / _ui_utils.CSS_UNITS; + heightScale = (this.container.clientHeight - vPadding) / height / _ui_utils.CSS_UNITS; + scale = Math.min(Math.abs(widthScale), Math.abs(heightScale)); + break; + default: + console.error(this._name + '.scrollPageIntoView: "' + dest[1].name + '" ' + 'is not a valid destination type.'); + return; + } + if (scale && scale !== this._currentScale) { + this.currentScaleValue = scale; + } else if (this._currentScale === _ui_utils.UNKNOWN_SCALE) { + this.currentScaleValue = _ui_utils.DEFAULT_SCALE_VALUE; + } + if (scale === 'page-fit' && !dest[4]) { + this._scrollIntoView({ + pageDiv: pageView.div, + pageNumber: pageNumber + }); + return; + } + var boundingRect = [pageView.viewport.convertToViewportPoint(x, y), pageView.viewport.convertToViewportPoint(x + width, y + height)]; + var left = Math.min(boundingRect[0][0], boundingRect[1][0]); + var top = Math.min(boundingRect[0][1], boundingRect[1][1]); + if (!allowNegativeOffset) { + left = Math.max(left, 0); + top = Math.max(top, 0); + } + this._scrollIntoView({ + pageDiv: pageView.div, + pageSpot: { + left: left, + top: top + }, + pageNumber: pageNumber + }); + } + }, { + key: '_resizeBuffer', + value: function _resizeBuffer(numVisiblePages) { + var suggestedCacheSize = Math.max(DEFAULT_CACHE_SIZE, 2 * numVisiblePages + 1); + this._buffer.resize(suggestedCacheSize); + } + }, { + key: '_updateLocation', + value: function _updateLocation(firstPage) { + var currentScale = this._currentScale; + var currentScaleValue = this._currentScaleValue; + var normalizedScaleValue = parseFloat(currentScaleValue) === currentScale ? Math.round(currentScale * 10000) / 100 : currentScaleValue; + var pageNumber = firstPage.id; + var pdfOpenParams = '#page=' + pageNumber; + pdfOpenParams += '&zoom=' + normalizedScaleValue; + var currentPageView = this._pages[pageNumber - 1]; + var container = this.container; + var topLeft = currentPageView.getPagePoint(container.scrollLeft - firstPage.x, container.scrollTop - firstPage.y); + var intLeft = Math.round(topLeft[0]); + var intTop = Math.round(topLeft[1]); + pdfOpenParams += ',' + intLeft + ',' + intTop; + this._location = { + pageNumber: pageNumber, + scale: normalizedScaleValue, + top: intTop, + left: intLeft, + rotation: this._pagesRotation, + pdfOpenParams: pdfOpenParams + }; + } + }, { + key: 'update', + value: function update() { + throw new Error('Not implemented: update'); + } + }, { + key: 'containsElement', + value: function containsElement(element) { + return this.container.contains(element); + } + }, { + key: 'focus', + value: function focus() { + this.container.focus(); + } + }, { + key: '_getVisiblePages', + value: function _getVisiblePages() { + throw new Error('Not implemented: _getVisiblePages'); + } + }, { + key: 'cleanup', + value: function cleanup() { + for (var i = 0, ii = this._pages.length; i < ii; i++) { + if (this._pages[i] && this._pages[i].renderingState !== _pdf_rendering_queue.RenderingStates.FINISHED) { + this._pages[i].reset(); + } + } + } + }, { + key: '_cancelRendering', + value: function _cancelRendering() { + for (var i = 0, ii = this._pages.length; i < ii; i++) { + if (this._pages[i]) { + this._pages[i].cancelRendering(); + } + } + } + }, { + key: '_ensurePdfPageLoaded', + value: function _ensurePdfPageLoaded(pageView) { + var _this2 = this; + + if (pageView.pdfPage) { + return Promise.resolve(pageView.pdfPage); + } + var pageNumber = pageView.id; + if (this._pagesRequests[pageNumber]) { + return this._pagesRequests[pageNumber]; + } + var promise = this.pdfDocument.getPage(pageNumber).then(function (pdfPage) { + if (!pageView.pdfPage) { + pageView.setPdfPage(pdfPage); + } + _this2._pagesRequests[pageNumber] = null; + return pdfPage; + }).catch(function (reason) { + console.error('Unable to get page for page view', reason); + _this2._pagesRequests[pageNumber] = null; + }); + this._pagesRequests[pageNumber] = promise; + return promise; + } + }, { + key: 'forceRendering', + value: function forceRendering(currentlyVisiblePages) { + var _this3 = this; + + var visiblePages = currentlyVisiblePages || this._getVisiblePages(); + var pageView = this.renderingQueue.getHighestPriority(visiblePages, this._pages, this.scroll.down); + if (pageView) { + this._ensurePdfPageLoaded(pageView).then(function () { + _this3.renderingQueue.renderView(pageView); + }); + return true; + } + return false; + } + }, { + key: 'getPageTextContent', + value: function getPageTextContent(pageIndex) { + return this.pdfDocument.getPage(pageIndex + 1).then(function (page) { + return page.getTextContent({ normalizeWhitespace: true }); + }); + } + }, { + key: 'createTextLayerBuilder', + value: function createTextLayerBuilder(textLayerDiv, pageIndex, viewport) { + var enhanceTextSelection = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; + + return new _text_layer_builder.TextLayerBuilder({ + textLayerDiv: textLayerDiv, + eventBus: this.eventBus, + pageIndex: pageIndex, + viewport: viewport, + findController: this.isInPresentationMode ? null : this.findController, + enhanceTextSelection: this.isInPresentationMode ? false : enhanceTextSelection + }); + } + }, { + key: 'createAnnotationLayerBuilder', + value: function createAnnotationLayerBuilder(pageDiv, pdfPage) { + var renderInteractiveForms = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + var l10n = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : _ui_utils.NullL10n; + + return new _annotation_layer_builder.AnnotationLayerBuilder({ + pageDiv: pageDiv, + pdfPage: pdfPage, + renderInteractiveForms: renderInteractiveForms, + linkService: this.linkService, + downloadManager: this.downloadManager, + l10n: l10n + }); + } + }, { + key: 'setFindController', + value: function setFindController(findController) { + this.findController = findController; + } + }, { + key: 'getPagesOverview', + value: function getPagesOverview() { + var pagesOverview = this._pages.map(function (pageView) { + var viewport = pageView.pdfPage.getViewport(1); + return { + width: viewport.width, + height: viewport.height, + rotation: viewport.rotation + }; + }); + if (!this.enablePrintAutoRotate) { + return pagesOverview; + } + var isFirstPagePortrait = isPortraitOrientation(pagesOverview[0]); + return pagesOverview.map(function (size) { + if (isFirstPagePortrait === isPortraitOrientation(size)) { + return size; + } + return { + width: size.height, + height: size.width, + rotation: (size.rotation + 90) % 360 + }; + }); + } + }, { + key: 'pagesCount', + get: function get() { + return this._pages.length; + } + }, { + key: 'pageViewsReady', + get: function get() { + return this._pageViewsReady; + } + }, { + key: 'currentPageNumber', + get: function get() { + return this._currentPageNumber; + }, + set: function set(val) { + if (!Number.isInteger(val)) { + throw new Error('Invalid page number.'); + } + if (!this.pdfDocument) { + return; + } + this._setCurrentPageNumber(val, true); + } + }, { + key: 'currentPageLabel', + get: function get() { + return this._pageLabels && this._pageLabels[this._currentPageNumber - 1]; + }, + set: function set(val) { + var pageNumber = val | 0; + if (this._pageLabels) { + var i = this._pageLabels.indexOf(val); + if (i >= 0) { + pageNumber = i + 1; + } + } + this.currentPageNumber = pageNumber; + } + }, { + key: 'currentScale', + get: function get() { + return this._currentScale !== _ui_utils.UNKNOWN_SCALE ? this._currentScale : _ui_utils.DEFAULT_SCALE; + }, + set: function set(val) { + if (isNaN(val)) { + throw new Error('Invalid numeric scale'); + } + if (!this.pdfDocument) { + return; + } + this._setScale(val, false); + } + }, { + key: 'currentScaleValue', + get: function get() { + return this._currentScaleValue; + }, + set: function set(val) { + if (!this.pdfDocument) { + return; + } + this._setScale(val, false); + } + }, { + key: 'pagesRotation', + get: function get() { + return this._pagesRotation; + }, + set: function set(rotation) { + if (!(0, _ui_utils.isValidRotation)(rotation)) { + throw new Error('Invalid pages rotation angle.'); + } + if (!this.pdfDocument) { + return; + } + if (this._pagesRotation === rotation) { + return; + } + this._pagesRotation = rotation; + var pageNumber = this._currentPageNumber; + for (var i = 0, ii = this._pages.length; i < ii; i++) { + var pageView = this._pages[i]; + pageView.update(pageView.scale, rotation); + } + if (this._currentScaleValue) { + this._setScale(this._currentScaleValue, true); + } + this.eventBus.dispatch('rotationchanging', { + source: this, + pagesRotation: rotation, + pageNumber: pageNumber + }); + if (this.defaultRenderingQueue) { + this.update(); + } + } + }, { + key: '_setDocumentViewerElement', + get: function get() { + throw new Error('Not implemented: _setDocumentViewerElement'); + } + }, { + key: 'isInPresentationMode', + get: function get() { + return this.presentationModeState === _ui_utils.PresentationModeState.FULLSCREEN; + } + }, { + key: 'isChangingPresentationMode', + get: function get() { + return this.presentationModeState === _ui_utils.PresentationModeState.CHANGING; + } + }, { + key: 'isHorizontalScrollbarEnabled', + get: function get() { + return this.isInPresentationMode ? false : this.container.scrollWidth > this.container.clientWidth; + } + }, { + key: 'hasEqualPageSizes', + get: function get() { + var firstPageView = this._pages[0]; + for (var i = 1, ii = this._pages.length; i < ii; ++i) { + var pageView = this._pages[i]; + if (pageView.width !== firstPageView.width || pageView.height !== firstPageView.height) { + return false; + } + } + return true; + } + }]); + + return BaseViewer; +}(); + +exports.BaseViewer = BaseViewer; + +/***/ }), +/* 23 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.DefaultAnnotationLayerFactory = exports.AnnotationLayerBuilder = undefined; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _pdfjsLib = __webpack_require__(1); + +var _ui_utils = __webpack_require__(0); + +var _pdf_link_service = __webpack_require__(5); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var AnnotationLayerBuilder = function () { + function AnnotationLayerBuilder(_ref) { + var pageDiv = _ref.pageDiv, + pdfPage = _ref.pdfPage, + linkService = _ref.linkService, + downloadManager = _ref.downloadManager, + _ref$renderInteractiv = _ref.renderInteractiveForms, + renderInteractiveForms = _ref$renderInteractiv === undefined ? false : _ref$renderInteractiv, + _ref$l10n = _ref.l10n, + l10n = _ref$l10n === undefined ? _ui_utils.NullL10n : _ref$l10n; + + _classCallCheck(this, AnnotationLayerBuilder); + + this.pageDiv = pageDiv; + this.pdfPage = pdfPage; + this.linkService = linkService; + this.downloadManager = downloadManager; + this.renderInteractiveForms = renderInteractiveForms; + this.l10n = l10n; + this.div = null; + } + + _createClass(AnnotationLayerBuilder, [{ + key: 'render', + value: function render(viewport) { + var _this = this; + + var intent = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'display'; + + this.pdfPage.getAnnotations({ intent: intent }).then(function (annotations) { + var parameters = { + viewport: viewport.clone({ dontFlip: true }), + div: _this.div, + annotations: annotations, + page: _this.pdfPage, + renderInteractiveForms: _this.renderInteractiveForms, + linkService: _this.linkService, + downloadManager: _this.downloadManager + }; + if (_this.div) { + _pdfjsLib.AnnotationLayer.update(parameters); + } else { + if (annotations.length === 0) { + return; + } + _this.div = document.createElement('div'); + _this.div.className = 'annotationLayer'; + _this.pageDiv.appendChild(_this.div); + parameters.div = _this.div; + _pdfjsLib.AnnotationLayer.render(parameters); + _this.l10n.translate(_this.div); + } + }); + } + }, { + key: 'hide', + value: function hide() { + if (!this.div) { + return; + } + this.div.setAttribute('hidden', 'true'); + } + }]); + + return AnnotationLayerBuilder; +}(); + +var DefaultAnnotationLayerFactory = function () { + function DefaultAnnotationLayerFactory() { + _classCallCheck(this, DefaultAnnotationLayerFactory); + } + + _createClass(DefaultAnnotationLayerFactory, [{ + key: 'createAnnotationLayerBuilder', + value: function createAnnotationLayerBuilder(pageDiv, pdfPage) { + var renderInteractiveForms = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + var l10n = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : _ui_utils.NullL10n; + + return new AnnotationLayerBuilder({ + pageDiv: pageDiv, + pdfPage: pdfPage, + renderInteractiveForms: renderInteractiveForms, + linkService: new _pdf_link_service.SimpleLinkService(), + l10n: l10n + }); + } + }]); + + return DefaultAnnotationLayerFactory; +}(); + +exports.AnnotationLayerBuilder = AnnotationLayerBuilder; +exports.DefaultAnnotationLayerFactory = DefaultAnnotationLayerFactory; + +/***/ }), +/* 24 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.PDFPageView = undefined; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _ui_utils = __webpack_require__(0); + +var _pdfjsLib = __webpack_require__(1); + +var _dom_events = __webpack_require__(2); + +var _pdf_rendering_queue = __webpack_require__(3); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var PDFPageView = function () { + function PDFPageView(options) { + _classCallCheck(this, PDFPageView); + + var container = options.container; + var defaultViewport = options.defaultViewport; + this.id = options.id; + this.renderingId = 'page' + this.id; + this.pdfPage = null; + this.pageLabel = null; + this.rotation = 0; + this.scale = options.scale || _ui_utils.DEFAULT_SCALE; + this.viewport = defaultViewport; + this.pdfPageRotate = defaultViewport.rotation; + this.hasRestrictedScaling = false; + this.enhanceTextSelection = options.enhanceTextSelection || false; + this.renderInteractiveForms = options.renderInteractiveForms || false; + this.eventBus = options.eventBus || (0, _dom_events.getGlobalEventBus)(); + this.renderingQueue = options.renderingQueue; + this.textLayerFactory = options.textLayerFactory; + this.annotationLayerFactory = options.annotationLayerFactory; + this.renderer = options.renderer || _ui_utils.RendererType.CANVAS; + this.l10n = options.l10n || _ui_utils.NullL10n; + this.paintTask = null; + this.paintedViewportMap = new WeakMap(); + this.renderingState = _pdf_rendering_queue.RenderingStates.INITIAL; + this.resume = null; + this.error = null; + this.onBeforeDraw = null; + this.onAfterDraw = null; + this.annotationLayer = null; + this.textLayer = null; + this.zoomLayer = null; + var div = document.createElement('div'); + div.className = 'page'; + div.style.width = Math.floor(this.viewport.width) + 'px'; + div.style.height = Math.floor(this.viewport.height) + 'px'; + div.setAttribute('data-page-number', this.id); + this.div = div; + container.appendChild(div); + } + + _createClass(PDFPageView, [{ + key: 'setPdfPage', + value: function setPdfPage(pdfPage) { + this.pdfPage = pdfPage; + this.pdfPageRotate = pdfPage.rotate; + var totalRotation = (this.rotation + this.pdfPageRotate) % 360; + this.viewport = pdfPage.getViewport(this.scale * _ui_utils.CSS_UNITS, totalRotation); + this.stats = pdfPage.stats; + this.reset(); + } + }, { + key: 'destroy', + value: function destroy() { + this.reset(); + if (this.pdfPage) { + this.pdfPage.cleanup(); + } + } + }, { + key: '_resetZoomLayer', + value: function _resetZoomLayer() { + var removeFromDOM = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + + if (!this.zoomLayer) { + return; + } + var zoomLayerCanvas = this.zoomLayer.firstChild; + this.paintedViewportMap.delete(zoomLayerCanvas); + zoomLayerCanvas.width = 0; + zoomLayerCanvas.height = 0; + if (removeFromDOM) { + this.zoomLayer.remove(); + } + this.zoomLayer = null; + } + }, { + key: 'reset', + value: function reset() { + var keepZoomLayer = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + var keepAnnotations = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + this.cancelRendering(); + var div = this.div; + div.style.width = Math.floor(this.viewport.width) + 'px'; + div.style.height = Math.floor(this.viewport.height) + 'px'; + var childNodes = div.childNodes; + var currentZoomLayerNode = keepZoomLayer && this.zoomLayer || null; + var currentAnnotationNode = keepAnnotations && this.annotationLayer && this.annotationLayer.div || null; + for (var i = childNodes.length - 1; i >= 0; i--) { + var node = childNodes[i]; + if (currentZoomLayerNode === node || currentAnnotationNode === node) { + continue; + } + div.removeChild(node); + } + div.removeAttribute('data-loaded'); + if (currentAnnotationNode) { + this.annotationLayer.hide(); + } else { + this.annotationLayer = null; + } + if (!currentZoomLayerNode) { + if (this.canvas) { + this.paintedViewportMap.delete(this.canvas); + this.canvas.width = 0; + this.canvas.height = 0; + delete this.canvas; + } + this._resetZoomLayer(); + } + if (this.svg) { + this.paintedViewportMap.delete(this.svg); + delete this.svg; + } + this.loadingIconDiv = document.createElement('div'); + this.loadingIconDiv.className = 'loadingIcon'; + div.appendChild(this.loadingIconDiv); + } + }, { + key: 'update', + value: function update(scale, rotation) { + this.scale = scale || this.scale; + if (typeof rotation !== 'undefined') { + this.rotation = rotation; + } + var totalRotation = (this.rotation + this.pdfPageRotate) % 360; + this.viewport = this.viewport.clone({ + scale: this.scale * _ui_utils.CSS_UNITS, + rotation: totalRotation + }); + if (this.svg) { + this.cssTransform(this.svg, true); + this.eventBus.dispatch('pagerendered', { + source: this, + pageNumber: this.id, + cssTransform: true + }); + return; + } + var isScalingRestricted = false; + if (this.canvas && _pdfjsLib.PDFJS.maxCanvasPixels > 0) { + var outputScale = this.outputScale; + if ((Math.floor(this.viewport.width) * outputScale.sx | 0) * (Math.floor(this.viewport.height) * outputScale.sy | 0) > _pdfjsLib.PDFJS.maxCanvasPixels) { + isScalingRestricted = true; + } + } + if (this.canvas) { + if (_pdfjsLib.PDFJS.useOnlyCssZoom || this.hasRestrictedScaling && isScalingRestricted) { + this.cssTransform(this.canvas, true); + this.eventBus.dispatch('pagerendered', { + source: this, + pageNumber: this.id, + cssTransform: true + }); + return; + } + if (!this.zoomLayer && !this.canvas.hasAttribute('hidden')) { + this.zoomLayer = this.canvas.parentNode; + this.zoomLayer.style.position = 'absolute'; + } + } + if (this.zoomLayer) { + this.cssTransform(this.zoomLayer.firstChild); + } + this.reset(true, true); + } + }, { + key: 'cancelRendering', + value: function cancelRendering() { + if (this.paintTask) { + this.paintTask.cancel(); + this.paintTask = null; + } + this.renderingState = _pdf_rendering_queue.RenderingStates.INITIAL; + this.resume = null; + if (this.textLayer) { + this.textLayer.cancel(); + this.textLayer = null; + } + } + }, { + key: 'cssTransform', + value: function cssTransform(target) { + var redrawAnnotations = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + var width = this.viewport.width; + var height = this.viewport.height; + var div = this.div; + target.style.width = target.parentNode.style.width = div.style.width = Math.floor(width) + 'px'; + target.style.height = target.parentNode.style.height = div.style.height = Math.floor(height) + 'px'; + var relativeRotation = this.viewport.rotation - this.paintedViewportMap.get(target).rotation; + var absRotation = Math.abs(relativeRotation); + var scaleX = 1, + scaleY = 1; + if (absRotation === 90 || absRotation === 270) { + scaleX = height / width; + scaleY = width / height; + } + var cssTransform = 'rotate(' + relativeRotation + 'deg) ' + 'scale(' + scaleX + ',' + scaleY + ')'; + _pdfjsLib.CustomStyle.setProp('transform', target, cssTransform); + if (this.textLayer) { + var textLayerViewport = this.textLayer.viewport; + var textRelativeRotation = this.viewport.rotation - textLayerViewport.rotation; + var textAbsRotation = Math.abs(textRelativeRotation); + var scale = width / textLayerViewport.width; + if (textAbsRotation === 90 || textAbsRotation === 270) { + scale = width / textLayerViewport.height; + } + var textLayerDiv = this.textLayer.textLayerDiv; + var transX = void 0, + transY = void 0; + switch (textAbsRotation) { + case 0: + transX = transY = 0; + break; + case 90: + transX = 0; + transY = '-' + textLayerDiv.style.height; + break; + case 180: + transX = '-' + textLayerDiv.style.width; + transY = '-' + textLayerDiv.style.height; + break; + case 270: + transX = '-' + textLayerDiv.style.width; + transY = 0; + break; + default: + console.error('Bad rotation value.'); + break; + } + _pdfjsLib.CustomStyle.setProp('transform', textLayerDiv, 'rotate(' + textAbsRotation + 'deg) ' + 'scale(' + scale + ', ' + scale + ') ' + 'translate(' + transX + ', ' + transY + ')'); + _pdfjsLib.CustomStyle.setProp('transformOrigin', textLayerDiv, '0% 0%'); + } + if (redrawAnnotations && this.annotationLayer) { + this.annotationLayer.render(this.viewport, 'display'); + } + } + }, { + key: 'getPagePoint', + value: function getPagePoint(x, y) { + return this.viewport.convertToPdfPoint(x, y); + } + }, { + key: 'draw', + value: function draw() { + var _this = this; + + if (this.renderingState !== _pdf_rendering_queue.RenderingStates.INITIAL) { + console.error('Must be in new state before drawing'); + this.reset(); + } + if (!this.pdfPage) { + this.renderingState = _pdf_rendering_queue.RenderingStates.FINISHED; + return Promise.reject(new Error('Page is not loaded')); + } + this.renderingState = _pdf_rendering_queue.RenderingStates.RUNNING; + var pdfPage = this.pdfPage; + var div = this.div; + var canvasWrapper = document.createElement('div'); + canvasWrapper.style.width = div.style.width; + canvasWrapper.style.height = div.style.height; + canvasWrapper.classList.add('canvasWrapper'); + if (this.annotationLayer && this.annotationLayer.div) { + div.insertBefore(canvasWrapper, this.annotationLayer.div); + } else { + div.appendChild(canvasWrapper); + } + var textLayer = null; + if (this.textLayerFactory) { + var textLayerDiv = document.createElement('div'); + textLayerDiv.className = 'textLayer'; + textLayerDiv.style.width = canvasWrapper.style.width; + textLayerDiv.style.height = canvasWrapper.style.height; + if (this.annotationLayer && this.annotationLayer.div) { + div.insertBefore(textLayerDiv, this.annotationLayer.div); + } else { + div.appendChild(textLayerDiv); + } + textLayer = this.textLayerFactory.createTextLayerBuilder(textLayerDiv, this.id - 1, this.viewport, this.enhanceTextSelection); + } + this.textLayer = textLayer; + var renderContinueCallback = null; + if (this.renderingQueue) { + renderContinueCallback = function renderContinueCallback(cont) { + if (!_this.renderingQueue.isHighestPriority(_this)) { + _this.renderingState = _pdf_rendering_queue.RenderingStates.PAUSED; + _this.resume = function () { + _this.renderingState = _pdf_rendering_queue.RenderingStates.RUNNING; + cont(); + }; + return; + } + cont(); + }; + } + var finishPaintTask = function finishPaintTask(error) { + if (paintTask === _this.paintTask) { + _this.paintTask = null; + } + if (error === 'cancelled' || error instanceof _pdfjsLib.RenderingCancelledException) { + _this.error = null; + return Promise.resolve(undefined); + } + _this.renderingState = _pdf_rendering_queue.RenderingStates.FINISHED; + if (_this.loadingIconDiv) { + div.removeChild(_this.loadingIconDiv); + delete _this.loadingIconDiv; + } + _this._resetZoomLayer(true); + _this.error = error; + _this.stats = pdfPage.stats; + if (_this.onAfterDraw) { + _this.onAfterDraw(); + } + _this.eventBus.dispatch('pagerendered', { + source: _this, + pageNumber: _this.id, + cssTransform: false + }); + if (error) { + return Promise.reject(error); + } + return Promise.resolve(undefined); + }; + var paintTask = this.renderer === _ui_utils.RendererType.SVG ? this.paintOnSvg(canvasWrapper) : this.paintOnCanvas(canvasWrapper); + paintTask.onRenderContinue = renderContinueCallback; + this.paintTask = paintTask; + var resultPromise = paintTask.promise.then(function () { + return finishPaintTask(null).then(function () { + if (textLayer) { + var readableStream = pdfPage.streamTextContent({ normalizeWhitespace: true }); + textLayer.setTextContentStream(readableStream); + textLayer.render(); + } + }); + }, function (reason) { + return finishPaintTask(reason); + }); + if (this.annotationLayerFactory) { + if (!this.annotationLayer) { + this.annotationLayer = this.annotationLayerFactory.createAnnotationLayerBuilder(div, pdfPage, this.renderInteractiveForms, this.l10n); + } + this.annotationLayer.render(this.viewport, 'display'); + } + div.setAttribute('data-loaded', true); + if (this.onBeforeDraw) { + this.onBeforeDraw(); + } + return resultPromise; + } + }, { + key: 'paintOnCanvas', + value: function paintOnCanvas(canvasWrapper) { + var renderCapability = (0, _pdfjsLib.createPromiseCapability)(); + var result = { + promise: renderCapability.promise, + onRenderContinue: function onRenderContinue(cont) { + cont(); + }, + cancel: function cancel() { + renderTask.cancel(); + } + }; + var viewport = this.viewport; + var canvas = document.createElement('canvas'); + canvas.id = this.renderingId; + canvas.setAttribute('hidden', 'hidden'); + var isCanvasHidden = true; + var showCanvas = function showCanvas() { + if (isCanvasHidden) { + canvas.removeAttribute('hidden'); + isCanvasHidden = false; + } + }; + canvasWrapper.appendChild(canvas); + this.canvas = canvas; + canvas.mozOpaque = true; + var ctx = canvas.getContext('2d', { alpha: false }); + var outputScale = (0, _ui_utils.getOutputScale)(ctx); + this.outputScale = outputScale; + if (_pdfjsLib.PDFJS.useOnlyCssZoom) { + var actualSizeViewport = viewport.clone({ scale: _ui_utils.CSS_UNITS }); + outputScale.sx *= actualSizeViewport.width / viewport.width; + outputScale.sy *= actualSizeViewport.height / viewport.height; + outputScale.scaled = true; + } + if (_pdfjsLib.PDFJS.maxCanvasPixels > 0) { + var pixelsInViewport = viewport.width * viewport.height; + var maxScale = Math.sqrt(_pdfjsLib.PDFJS.maxCanvasPixels / pixelsInViewport); + if (outputScale.sx > maxScale || outputScale.sy > maxScale) { + outputScale.sx = maxScale; + outputScale.sy = maxScale; + outputScale.scaled = true; + this.hasRestrictedScaling = true; + } else { + this.hasRestrictedScaling = false; + } + } + var sfx = (0, _ui_utils.approximateFraction)(outputScale.sx); + var sfy = (0, _ui_utils.approximateFraction)(outputScale.sy); + canvas.width = (0, _ui_utils.roundToDivide)(viewport.width * outputScale.sx, sfx[0]); + canvas.height = (0, _ui_utils.roundToDivide)(viewport.height * outputScale.sy, sfy[0]); + canvas.style.width = (0, _ui_utils.roundToDivide)(viewport.width, sfx[1]) + 'px'; + canvas.style.height = (0, _ui_utils.roundToDivide)(viewport.height, sfy[1]) + 'px'; + this.paintedViewportMap.set(canvas, viewport); + var transform = !outputScale.scaled ? null : [outputScale.sx, 0, 0, outputScale.sy, 0, 0]; + var renderContext = { + canvasContext: ctx, + transform: transform, + viewport: this.viewport, + renderInteractiveForms: this.renderInteractiveForms + }; + var renderTask = this.pdfPage.render(renderContext); + renderTask.onContinue = function (cont) { + showCanvas(); + if (result.onRenderContinue) { + result.onRenderContinue(cont); + } else { + cont(); + } + }; + renderTask.promise.then(function () { + showCanvas(); + renderCapability.resolve(undefined); + }, function (error) { + showCanvas(); + renderCapability.reject(error); + }); + return result; + } + }, { + key: 'paintOnSvg', + value: function paintOnSvg(wrapper) { + var _this2 = this; + + var cancelled = false; + var ensureNotCancelled = function ensureNotCancelled() { + if (cancelled) { + if (_pdfjsLib.PDFJS.pdfjsNext) { + throw new _pdfjsLib.RenderingCancelledException('Rendering cancelled, page ' + _this2.id, 'svg'); + } else { + throw 'cancelled'; + } + } + }; + var pdfPage = this.pdfPage; + var actualSizeViewport = this.viewport.clone({ scale: _ui_utils.CSS_UNITS }); + var promise = pdfPage.getOperatorList().then(function (opList) { + ensureNotCancelled(); + var svgGfx = new _pdfjsLib.SVGGraphics(pdfPage.commonObjs, pdfPage.objs); + return svgGfx.getSVG(opList, actualSizeViewport).then(function (svg) { + ensureNotCancelled(); + _this2.svg = svg; + _this2.paintedViewportMap.set(svg, actualSizeViewport); + svg.style.width = wrapper.style.width; + svg.style.height = wrapper.style.height; + _this2.renderingState = _pdf_rendering_queue.RenderingStates.FINISHED; + wrapper.appendChild(svg); + }); + }); + return { + promise: promise, + onRenderContinue: function onRenderContinue(cont) { + cont(); + }, + cancel: function cancel() { + cancelled = true; + } + }; + } + }, { + key: 'setPageLabel', + value: function setPageLabel(label) { + this.pageLabel = typeof label === 'string' ? label : null; + if (this.pageLabel !== null) { + this.div.setAttribute('data-page-label', this.pageLabel); + } else { + this.div.removeAttribute('data-page-label'); + } + } + }, { + key: 'width', + get: function get() { + return this.viewport.width; + } + }, { + key: 'height', + get: function get() { + return this.viewport.height; + } + }]); + + return PDFPageView; +}(); + +exports.PDFPageView = PDFPageView; + +/***/ }), +/* 25 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.DefaultTextLayerFactory = exports.TextLayerBuilder = undefined; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _dom_events = __webpack_require__(2); + +var _pdfjsLib = __webpack_require__(1); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var EXPAND_DIVS_TIMEOUT = 300; + +var TextLayerBuilder = function () { + function TextLayerBuilder(_ref) { + var textLayerDiv = _ref.textLayerDiv, + eventBus = _ref.eventBus, + pageIndex = _ref.pageIndex, + viewport = _ref.viewport, + _ref$findController = _ref.findController, + findController = _ref$findController === undefined ? null : _ref$findController, + _ref$enhanceTextSelec = _ref.enhanceTextSelection, + enhanceTextSelection = _ref$enhanceTextSelec === undefined ? false : _ref$enhanceTextSelec; + + _classCallCheck(this, TextLayerBuilder); + + this.textLayerDiv = textLayerDiv; + this.eventBus = eventBus || (0, _dom_events.getGlobalEventBus)(); + this.textContent = null; + this.textContentItemsStr = []; + this.textContentStream = null; + this.renderingDone = false; + this.pageIdx = pageIndex; + this.pageNumber = this.pageIdx + 1; + this.matches = []; + this.viewport = viewport; + this.textDivs = []; + this.findController = findController; + this.textLayerRenderTask = null; + this.enhanceTextSelection = enhanceTextSelection; + this._bindMouse(); + } + + _createClass(TextLayerBuilder, [{ + key: '_finishRendering', + value: function _finishRendering() { + this.renderingDone = true; + if (!this.enhanceTextSelection) { + var endOfContent = document.createElement('div'); + endOfContent.className = 'endOfContent'; + this.textLayerDiv.appendChild(endOfContent); + } + this.eventBus.dispatch('textlayerrendered', { + source: this, + pageNumber: this.pageNumber, + numTextDivs: this.textDivs.length + }); + } + }, { + key: 'render', + value: function render() { + var _this = this; + + var timeout = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; + + if (!(this.textContent || this.textContentStream) || this.renderingDone) { + return; + } + this.cancel(); + this.textDivs = []; + var textLayerFrag = document.createDocumentFragment(); + this.textLayerRenderTask = (0, _pdfjsLib.renderTextLayer)({ + textContent: this.textContent, + textContentStream: this.textContentStream, + container: textLayerFrag, + viewport: this.viewport, + textDivs: this.textDivs, + textContentItemsStr: this.textContentItemsStr, + timeout: timeout, + enhanceTextSelection: this.enhanceTextSelection + }); + this.textLayerRenderTask.promise.then(function () { + _this.textLayerDiv.appendChild(textLayerFrag); + _this._finishRendering(); + _this.updateMatches(); + }, function (reason) {}); + } + }, { + key: 'cancel', + value: function cancel() { + if (this.textLayerRenderTask) { + this.textLayerRenderTask.cancel(); + this.textLayerRenderTask = null; + } + } + }, { + key: 'setTextContentStream', + value: function setTextContentStream(readableStream) { + this.cancel(); + this.textContentStream = readableStream; + } + }, { + key: 'setTextContent', + value: function setTextContent(textContent) { + this.cancel(); + this.textContent = textContent; + } + }, { + key: 'convertMatches', + value: function convertMatches(matches, matchesLength) { + var i = 0; + var iIndex = 0; + var textContentItemsStr = this.textContentItemsStr; + var end = textContentItemsStr.length - 1; + var queryLen = this.findController === null ? 0 : this.findController.state.query.length; + var ret = []; + if (!matches) { + return ret; + } + for (var m = 0, len = matches.length; m < len; m++) { + var matchIdx = matches[m]; + while (i !== end && matchIdx >= iIndex + textContentItemsStr[i].length) { + iIndex += textContentItemsStr[i].length; + i++; + } + if (i === textContentItemsStr.length) { + console.error('Could not find a matching mapping'); + } + var match = { + begin: { + divIdx: i, + offset: matchIdx - iIndex + } + }; + if (matchesLength) { + matchIdx += matchesLength[m]; + } else { + matchIdx += queryLen; + } + while (i !== end && matchIdx > iIndex + textContentItemsStr[i].length) { + iIndex += textContentItemsStr[i].length; + i++; + } + match.end = { + divIdx: i, + offset: matchIdx - iIndex + }; + ret.push(match); + } + return ret; + } + }, { + key: 'renderMatches', + value: function renderMatches(matches) { + if (matches.length === 0) { + return; + } + var textContentItemsStr = this.textContentItemsStr; + var textDivs = this.textDivs; + var prevEnd = null; + var pageIdx = this.pageIdx; + var isSelectedPage = this.findController === null ? false : pageIdx === this.findController.selected.pageIdx; + var selectedMatchIdx = this.findController === null ? -1 : this.findController.selected.matchIdx; + var highlightAll = this.findController === null ? false : this.findController.state.highlightAll; + var infinity = { + divIdx: -1, + offset: undefined + }; + function beginText(begin, className) { + var divIdx = begin.divIdx; + textDivs[divIdx].textContent = ''; + appendTextToDiv(divIdx, 0, begin.offset, className); + } + function appendTextToDiv(divIdx, fromOffset, toOffset, className) { + var div = textDivs[divIdx]; + var content = textContentItemsStr[divIdx].substring(fromOffset, toOffset); + var node = document.createTextNode(content); + if (className) { + var span = document.createElement('span'); + span.className = className; + span.appendChild(node); + div.appendChild(span); + return; + } + div.appendChild(node); + } + var i0 = selectedMatchIdx, + i1 = i0 + 1; + if (highlightAll) { + i0 = 0; + i1 = matches.length; + } else if (!isSelectedPage) { + return; + } + for (var i = i0; i < i1; i++) { + var match = matches[i]; + var begin = match.begin; + var end = match.end; + var isSelected = isSelectedPage && i === selectedMatchIdx; + var highlightSuffix = isSelected ? ' selected' : ''; + if (this.findController) { + this.findController.updateMatchPosition(pageIdx, i, textDivs, begin.divIdx); + } + if (!prevEnd || begin.divIdx !== prevEnd.divIdx) { + if (prevEnd !== null) { + appendTextToDiv(prevEnd.divIdx, prevEnd.offset, infinity.offset); + } + beginText(begin); + } else { + appendTextToDiv(prevEnd.divIdx, prevEnd.offset, begin.offset); + } + if (begin.divIdx === end.divIdx) { + appendTextToDiv(begin.divIdx, begin.offset, end.offset, 'highlight' + highlightSuffix); + } else { + appendTextToDiv(begin.divIdx, begin.offset, infinity.offset, 'highlight begin' + highlightSuffix); + for (var n0 = begin.divIdx + 1, n1 = end.divIdx; n0 < n1; n0++) { + textDivs[n0].className = 'highlight middle' + highlightSuffix; + } + beginText(end, 'highlight end' + highlightSuffix); + } + prevEnd = end; + } + if (prevEnd) { + appendTextToDiv(prevEnd.divIdx, prevEnd.offset, infinity.offset); + } + } + }, { + key: 'updateMatches', + value: function updateMatches() { + if (!this.renderingDone) { + return; + } + var matches = this.matches; + var textDivs = this.textDivs; + var textContentItemsStr = this.textContentItemsStr; + var clearedUntilDivIdx = -1; + for (var i = 0, len = matches.length; i < len; i++) { + var match = matches[i]; + var begin = Math.max(clearedUntilDivIdx, match.begin.divIdx); + for (var n = begin, end = match.end.divIdx; n <= end; n++) { + var div = textDivs[n]; + div.textContent = textContentItemsStr[n]; + div.className = ''; + } + clearedUntilDivIdx = match.end.divIdx + 1; + } + if (this.findController === null || !this.findController.active) { + return; + } + var pageMatches = void 0, + pageMatchesLength = void 0; + if (this.findController !== null) { + pageMatches = this.findController.pageMatches[this.pageIdx] || null; + pageMatchesLength = this.findController.pageMatchesLength ? this.findController.pageMatchesLength[this.pageIdx] || null : null; + } + this.matches = this.convertMatches(pageMatches, pageMatchesLength); + this.renderMatches(this.matches); + } + }, { + key: '_bindMouse', + value: function _bindMouse() { + var _this2 = this; + + var div = this.textLayerDiv; + var expandDivsTimer = null; + div.addEventListener('mousedown', function (evt) { + if (_this2.enhanceTextSelection && _this2.textLayerRenderTask) { + _this2.textLayerRenderTask.expandTextDivs(true); + if (expandDivsTimer) { + clearTimeout(expandDivsTimer); + expandDivsTimer = null; + } + return; + } + var end = div.querySelector('.endOfContent'); + if (!end) { + return; + } + var adjustTop = evt.target !== div; + adjustTop = adjustTop && window.getComputedStyle(end).getPropertyValue('-moz-user-select') !== 'none'; + if (adjustTop) { + var divBounds = div.getBoundingClientRect(); + var r = Math.max(0, (evt.pageY - divBounds.top) / divBounds.height); + end.style.top = (r * 100).toFixed(2) + '%'; + } + end.classList.add('active'); + }); + div.addEventListener('mouseup', function () { + if (_this2.enhanceTextSelection && _this2.textLayerRenderTask) { + expandDivsTimer = setTimeout(function () { + if (_this2.textLayerRenderTask) { + _this2.textLayerRenderTask.expandTextDivs(false); + } + expandDivsTimer = null; + }, EXPAND_DIVS_TIMEOUT); + return; + } + var end = div.querySelector('.endOfContent'); + if (!end) { + return; + } + end.style.top = ''; + end.classList.remove('active'); + }); + } + }]); + + return TextLayerBuilder; +}(); + +var DefaultTextLayerFactory = function () { + function DefaultTextLayerFactory() { + _classCallCheck(this, DefaultTextLayerFactory); + } + + _createClass(DefaultTextLayerFactory, [{ + key: 'createTextLayerBuilder', + value: function createTextLayerBuilder(textLayerDiv, pageIndex, viewport) { + var enhanceTextSelection = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; + + return new TextLayerBuilder({ + textLayerDiv: textLayerDiv, + pageIndex: pageIndex, + viewport: viewport, + enhanceTextSelection: enhanceTextSelection + }); + } + }]); + + return DefaultTextLayerFactory; +}(); + +exports.TextLayerBuilder = TextLayerBuilder; +exports.DefaultTextLayerFactory = DefaultTextLayerFactory; + +/***/ }), +/* 26 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.SecondaryToolbar = undefined; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _pdf_cursor_tools = __webpack_require__(6); + +var _ui_utils = __webpack_require__(0); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var SecondaryToolbar = function () { + function SecondaryToolbar(options, mainContainer, eventBus) { + _classCallCheck(this, SecondaryToolbar); + + this.toolbar = options.toolbar; + this.toggleButton = options.toggleButton; + this.toolbarButtonContainer = options.toolbarButtonContainer; + this.buttons = [{ + element: options.presentationModeButton, + eventName: 'presentationmode', + close: true + }, { + element: options.openFileButton, + eventName: 'openfile', + close: true + }, { + element: options.printButton, + eventName: 'print', + close: true + }, { + element: options.downloadButton, + eventName: 'download', + close: true + }, { + element: options.viewBookmarkButton, + eventName: null, + close: true + }, { + element: options.firstPageButton, + eventName: 'firstpage', + close: true + }, { + element: options.lastPageButton, + eventName: 'lastpage', + close: true + }, { + element: options.pageRotateCwButton, + eventName: 'rotatecw', + close: false + }, { + element: options.pageRotateCcwButton, + eventName: 'rotateccw', + close: false + }, { + element: options.cursorSelectToolButton, + eventName: 'switchcursortool', + eventDetails: { tool: _pdf_cursor_tools.CursorTool.SELECT }, + close: true + }, { + element: options.cursorHandToolButton, + eventName: 'switchcursortool', + eventDetails: { tool: _pdf_cursor_tools.CursorTool.HAND }, + close: true + }, { + element: options.documentPropertiesButton, + eventName: 'documentproperties', + close: true + }]; + this.items = { + firstPage: options.firstPageButton, + lastPage: options.lastPageButton, + pageRotateCw: options.pageRotateCwButton, + pageRotateCcw: options.pageRotateCcwButton + }; + this.mainContainer = mainContainer; + this.eventBus = eventBus; + this.opened = false; + this.containerHeight = null; + this.previousContainerHeight = null; + this.reset(); + this._bindClickListeners(); + this._bindCursorToolsListener(options); + this.eventBus.on('resize', this._setMaxHeight.bind(this)); + } + + _createClass(SecondaryToolbar, [{ + key: 'setPageNumber', + value: function setPageNumber(pageNumber) { + this.pageNumber = pageNumber; + this._updateUIState(); + } + }, { + key: 'setPagesCount', + value: function setPagesCount(pagesCount) { + this.pagesCount = pagesCount; + this._updateUIState(); + } + }, { + key: 'reset', + value: function reset() { + this.pageNumber = 0; + this.pagesCount = 0; + this._updateUIState(); + } + }, { + key: '_updateUIState', + value: function _updateUIState() { + this.items.firstPage.disabled = this.pageNumber <= 1; + this.items.lastPage.disabled = this.pageNumber >= this.pagesCount; + this.items.pageRotateCw.disabled = this.pagesCount === 0; + this.items.pageRotateCcw.disabled = this.pagesCount === 0; + } + }, { + key: '_bindClickListeners', + value: function _bindClickListeners() { + var _this = this; + + this.toggleButton.addEventListener('click', this.toggle.bind(this)); + + var _loop = function _loop(button) { + var _buttons$button = _this.buttons[button], + element = _buttons$button.element, + eventName = _buttons$button.eventName, + close = _buttons$button.close, + eventDetails = _buttons$button.eventDetails; + + element.addEventListener('click', function (evt) { + if (eventName !== null) { + var details = { source: _this }; + for (var property in eventDetails) { + details[property] = eventDetails[property]; + } + _this.eventBus.dispatch(eventName, details); + } + if (close) { + _this.close(); + } + }); + }; + + for (var button in this.buttons) { + _loop(button); + } + } + }, { + key: '_bindCursorToolsListener', + value: function _bindCursorToolsListener(buttons) { + this.eventBus.on('cursortoolchanged', function (evt) { + buttons.cursorSelectToolButton.classList.remove('toggled'); + buttons.cursorHandToolButton.classList.remove('toggled'); + switch (evt.tool) { + case _pdf_cursor_tools.CursorTool.SELECT: + buttons.cursorSelectToolButton.classList.add('toggled'); + break; + case _pdf_cursor_tools.CursorTool.HAND: + buttons.cursorHandToolButton.classList.add('toggled'); + break; + } + }); + } + }, { + key: 'open', + value: function open() { + if (this.opened) { + return; + } + this.opened = true; + this._setMaxHeight(); + this.toggleButton.classList.add('toggled'); + this.toolbar.classList.remove('hidden'); + } + }, { + key: 'close', + value: function close() { + if (!this.opened) { + return; + } + this.opened = false; + this.toolbar.classList.add('hidden'); + this.toggleButton.classList.remove('toggled'); + } + }, { + key: 'toggle', + value: function toggle() { + if (this.opened) { + this.close(); + } else { + this.open(); + } + } + }, { + key: '_setMaxHeight', + value: function _setMaxHeight() { + if (!this.opened) { + return; + } + this.containerHeight = this.mainContainer.clientHeight; + if (this.containerHeight === this.previousContainerHeight) { + return; + } + this.toolbarButtonContainer.setAttribute('style', 'max-height: ' + (this.containerHeight - _ui_utils.SCROLLBAR_PADDING) + 'px;'); + this.previousContainerHeight = this.containerHeight; + } + }, { + key: 'isOpen', + get: function get() { + return this.opened; + } + }]); + + return SecondaryToolbar; +}(); + +exports.SecondaryToolbar = SecondaryToolbar; + +/***/ }), +/* 27 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.Toolbar = undefined; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _ui_utils = __webpack_require__(0); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var PAGE_NUMBER_LOADING_INDICATOR = 'visiblePageIsLoading'; +var SCALE_SELECT_CONTAINER_PADDING = 8; +var SCALE_SELECT_PADDING = 22; + +var Toolbar = function () { + function Toolbar(options, mainContainer, eventBus) { + var l10n = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : _ui_utils.NullL10n; + + _classCallCheck(this, Toolbar); + + this.toolbar = options.container; + this.mainContainer = mainContainer; + this.eventBus = eventBus; + this.l10n = l10n; + this.items = options; + this._wasLocalized = false; + this.reset(); + this._bindListeners(); + } + + _createClass(Toolbar, [{ + key: 'setPageNumber', + value: function setPageNumber(pageNumber, pageLabel) { + this.pageNumber = pageNumber; + this.pageLabel = pageLabel; + this._updateUIState(false); + } + }, { + key: 'setPagesCount', + value: function setPagesCount(pagesCount, hasPageLabels) { + this.pagesCount = pagesCount; + this.hasPageLabels = hasPageLabels; + this._updateUIState(true); + } + }, { + key: 'setPageScale', + value: function setPageScale(pageScaleValue, pageScale) { + this.pageScaleValue = pageScaleValue; + this.pageScale = pageScale; + this._updateUIState(false); + } + }, { + key: 'reset', + value: function reset() { + this.pageNumber = 0; + this.pageLabel = null; + this.hasPageLabels = false; + this.pagesCount = 0; + this.pageScaleValue = _ui_utils.DEFAULT_SCALE_VALUE; + this.pageScale = _ui_utils.DEFAULT_SCALE; + this._updateUIState(true); + } + }, { + key: '_bindListeners', + value: function _bindListeners() { + var _this = this; + + var eventBus = this.eventBus, + items = this.items; + + var self = this; + items.previous.addEventListener('click', function () { + eventBus.dispatch('previouspage'); + }); + items.next.addEventListener('click', function () { + eventBus.dispatch('nextpage'); + }); + items.zoomIn.addEventListener('click', function () { + eventBus.dispatch('zoomin'); + }); + items.zoomOut.addEventListener('click', function () { + eventBus.dispatch('zoomout'); + }); + items.pageNumber.addEventListener('click', function () { + this.select(); + }); + items.pageNumber.addEventListener('change', function () { + eventBus.dispatch('pagenumberchanged', { + source: self, + value: this.value + }); + }); + items.scaleSelect.addEventListener('change', function () { + if (this.value === 'custom') { + return; + } + eventBus.dispatch('scalechanged', { + source: self, + value: this.value + }); + }); + items.presentationModeButton.addEventListener('click', function () { + eventBus.dispatch('presentationmode'); + }); + items.openFile.addEventListener('click', function () { + eventBus.dispatch('openfile'); + }); + items.print.addEventListener('click', function () { + eventBus.dispatch('print'); + }); + items.download.addEventListener('click', function () { + eventBus.dispatch('download'); + }); + items.scaleSelect.oncontextmenu = _ui_utils.noContextMenuHandler; + eventBus.on('localized', function () { + _this._localized(); + }); + } + }, { + key: '_localized', + value: function _localized() { + this._wasLocalized = true; + this._adjustScaleWidth(); + this._updateUIState(true); + } + }, { + key: '_updateUIState', + value: function _updateUIState() { + var resetNumPages = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + + if (!this._wasLocalized) { + return; + } + var pageNumber = this.pageNumber, + pagesCount = this.pagesCount, + items = this.items; + + var scaleValue = (this.pageScaleValue || this.pageScale).toString(); + var scale = this.pageScale; + if (resetNumPages) { + if (this.hasPageLabels) { + items.pageNumber.type = 'text'; + } else { + items.pageNumber.type = 'number'; + this.l10n.get('of_pages', { pagesCount: pagesCount }, 'of {{pagesCount}}').then(function (msg) { + items.numPages.textContent = msg; + }); + } + items.pageNumber.max = pagesCount; + } + if (this.hasPageLabels) { + items.pageNumber.value = this.pageLabel; + this.l10n.get('page_of_pages', { + pageNumber: pageNumber, + pagesCount: pagesCount + }, '({{pageNumber}} of {{pagesCount}})').then(function (msg) { + items.numPages.textContent = msg; + }); + } else { + items.pageNumber.value = pageNumber; + } + items.previous.disabled = pageNumber <= 1; + items.next.disabled = pageNumber >= pagesCount; + items.zoomOut.disabled = scale <= _ui_utils.MIN_SCALE; + items.zoomIn.disabled = scale >= _ui_utils.MAX_SCALE; + var customScale = Math.round(scale * 10000) / 100; + this.l10n.get('page_scale_percent', { scale: customScale }, '{{scale}}%').then(function (msg) { + var options = items.scaleSelect.options; + var predefinedValueFound = false; + for (var i = 0, ii = options.length; i < ii; i++) { + var option = options[i]; + if (option.value !== scaleValue) { + option.selected = false; + continue; + } + option.selected = true; + predefinedValueFound = true; + } + if (!predefinedValueFound) { + items.customScaleOption.textContent = msg; + items.customScaleOption.selected = true; + } + }); + } + }, { + key: 'updateLoadingIndicatorState', + value: function updateLoadingIndicatorState() { + var loading = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + + var pageNumberInput = this.items.pageNumber; + if (loading) { + pageNumberInput.classList.add(PAGE_NUMBER_LOADING_INDICATOR); + } else { + pageNumberInput.classList.remove(PAGE_NUMBER_LOADING_INDICATOR); + } + } + }, { + key: '_adjustScaleWidth', + value: function _adjustScaleWidth() { + var container = this.items.scaleSelectContainer; + var select = this.items.scaleSelect; + _ui_utils.animationStarted.then(function () { + if (container.clientWidth === 0) { + container.setAttribute('style', 'display: inherit;'); + } + if (container.clientWidth > 0) { + select.setAttribute('style', 'min-width: inherit;'); + var width = select.clientWidth + SCALE_SELECT_CONTAINER_PADDING; + select.setAttribute('style', 'min-width: ' + (width + SCALE_SELECT_PADDING) + 'px;'); + container.setAttribute('style', 'min-width: ' + width + 'px; ' + 'max-width: ' + width + 'px;'); + } + }); + } + }]); + + return Toolbar; +}(); + +exports.Toolbar = Toolbar; + +/***/ }), +/* 28 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var DEFAULT_VIEW_HISTORY_CACHE_SIZE = 20; + +var ViewHistory = function () { + function ViewHistory(fingerprint) { + var _this = this; + + var cacheSize = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : DEFAULT_VIEW_HISTORY_CACHE_SIZE; + + _classCallCheck(this, ViewHistory); + + this.fingerprint = fingerprint; + this.cacheSize = cacheSize; + this._initializedPromise = this._readFromStorage().then(function (databaseStr) { + var database = JSON.parse(databaseStr || '{}'); + if (!('files' in database)) { + database.files = []; + } + if (database.files.length >= _this.cacheSize) { + database.files.shift(); + } + var index = void 0; + for (var i = 0, length = database.files.length; i < length; i++) { + var branch = database.files[i]; + if (branch.fingerprint === _this.fingerprint) { + index = i; + break; + } + } + if (typeof index !== 'number') { + index = database.files.push({ fingerprint: _this.fingerprint }) - 1; + } + _this.file = database.files[index]; + _this.database = database; + }); + } + + _createClass(ViewHistory, [{ + key: '_writeToStorage', + value: function _writeToStorage() { + var _this2 = this; + + return new Promise(function (resolve) { + var databaseStr = JSON.stringify(_this2.database); + localStorage.setItem('pdfjs.history', databaseStr); + resolve(); + }); + } + }, { + key: '_readFromStorage', + value: function _readFromStorage() { + return new Promise(function (resolve) { + resolve(localStorage.getItem('pdfjs.history')); + }); + } + }, { + key: 'set', + value: function set(name, val) { + var _this3 = this; + + return this._initializedPromise.then(function () { + _this3.file[name] = val; + return _this3._writeToStorage(); + }); + } + }, { + key: 'setMultiple', + value: function setMultiple(properties) { + var _this4 = this; + + return this._initializedPromise.then(function () { + for (var name in properties) { + _this4.file[name] = properties[name]; + } + return _this4._writeToStorage(); + }); + } + }, { + key: 'get', + value: function get(name, defaultValue) { + var _this5 = this; + + return this._initializedPromise.then(function () { + var val = _this5.file[name]; + return val !== undefined ? val : defaultValue; + }); + } + }, { + key: 'getMultiple', + value: function getMultiple(properties) { + var _this6 = this; + + return this._initializedPromise.then(function () { + var values = Object.create(null); + for (var name in properties) { + var val = _this6.file[name]; + values[name] = val !== undefined ? val : properties[name]; + } + return values; + }); + } + }]); + + return ViewHistory; +}(); + +exports.ViewHistory = ViewHistory; + +/***/ }), +/* 29 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.GenericCom = undefined; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _app = __webpack_require__(4); + +var _preferences = __webpack_require__(30); + +var _download_manager = __webpack_require__(31); + +var _genericl10n = __webpack_require__(32); + +var _pdfjsLib = __webpack_require__(1); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +; +var GenericCom = {}; + +var GenericPreferences = function (_BasePreferences) { + _inherits(GenericPreferences, _BasePreferences); + + function GenericPreferences() { + _classCallCheck(this, GenericPreferences); + + return _possibleConstructorReturn(this, (GenericPreferences.__proto__ || Object.getPrototypeOf(GenericPreferences)).apply(this, arguments)); + } + + _createClass(GenericPreferences, [{ + key: '_writeToStorage', + value: function _writeToStorage(prefObj) { + return new Promise(function (resolve) { + localStorage.setItem('pdfjs.preferences', JSON.stringify(prefObj)); + resolve(); + }); + } + }, { + key: '_readFromStorage', + value: function _readFromStorage(prefObj) { + return new Promise(function (resolve) { + var readPrefs = JSON.parse(localStorage.getItem('pdfjs.preferences')); + resolve(readPrefs); + }); + } + }]); + + return GenericPreferences; +}(_preferences.BasePreferences); + +var GenericExternalServices = Object.create(_app.DefaultExternalServices); +GenericExternalServices.createDownloadManager = function () { + return new _download_manager.DownloadManager(); +}; +GenericExternalServices.createPreferences = function () { + return new GenericPreferences(); +}; +GenericExternalServices.createL10n = function () { + return new _genericl10n.GenericL10n(_pdfjsLib.PDFJS.locale); +}; +_app.PDFViewerApplication.externalServices = GenericExternalServices; +exports.GenericCom = GenericCom; + +/***/ }), +/* 30 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.BasePreferences = undefined; + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _ui_utils = __webpack_require__(0); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var defaultPreferences = null; +function getDefaultPreferences() { + if (!defaultPreferences) { + defaultPreferences = Promise.resolve({ + "showPreviousViewOnLoad": true, + "defaultZoomValue": "", + "sidebarViewOnLoad": 0, + "enableHandToolOnLoad": false, + "cursorToolOnLoad": 0, + "enableWebGL": false, + "pdfBugEnabled": false, + "disableRange": false, + "disableStream": false, + "disableAutoFetch": false, + "disableFontFace": false, + "disableTextLayer": false, + "useOnlyCssZoom": false, + "externalLinkTarget": 0, + "enhanceTextSelection": false, + "renderer": "canvas", + "renderInteractiveForms": false, + "enablePrintAutoRotate": false, + "disablePageMode": false, + "disablePageLabels": false + }); + } + return defaultPreferences; +} + +var BasePreferences = function () { + function BasePreferences() { + var _this = this; + + _classCallCheck(this, BasePreferences); + + if (this.constructor === BasePreferences) { + throw new Error('Cannot initialize BasePreferences.'); + } + this.prefs = null; + this._initializedPromise = getDefaultPreferences().then(function (defaults) { + Object.defineProperty(_this, 'defaults', { + value: Object.freeze(defaults), + writable: false, + enumerable: true, + configurable: false + }); + _this.prefs = (0, _ui_utils.cloneObj)(defaults); + return _this._readFromStorage(defaults); + }).then(function (prefObj) { + if (prefObj) { + _this.prefs = prefObj; + } + }); + } + + _createClass(BasePreferences, [{ + key: "_writeToStorage", + value: function _writeToStorage(prefObj) { + return Promise.reject(new Error('Not implemented: _writeToStorage')); + } + }, { + key: "_readFromStorage", + value: function _readFromStorage(prefObj) { + return Promise.reject(new Error('Not implemented: _readFromStorage')); + } + }, { + key: "reset", + value: function reset() { + var _this2 = this; + + return this._initializedPromise.then(function () { + _this2.prefs = (0, _ui_utils.cloneObj)(_this2.defaults); + return _this2._writeToStorage(_this2.defaults); + }); + } + }, { + key: "reload", + value: function reload() { + var _this3 = this; + + return this._initializedPromise.then(function () { + return _this3._readFromStorage(_this3.defaults); + }).then(function (prefObj) { + if (prefObj) { + _this3.prefs = prefObj; + } + }); + } + }, { + key: "set", + value: function set(name, value) { + var _this4 = this; + + return this._initializedPromise.then(function () { + if (_this4.defaults[name] === undefined) { + throw new Error("Set preference: \"" + name + "\" is undefined."); + } else if (value === undefined) { + throw new Error('Set preference: no value is specified.'); + } + var valueType = typeof value === "undefined" ? "undefined" : _typeof(value); + var defaultType = _typeof(_this4.defaults[name]); + if (valueType !== defaultType) { + if (valueType === 'number' && defaultType === 'string') { + value = value.toString(); + } else { + throw new Error("Set preference: \"" + value + "\" is a " + valueType + ", " + ("expected a " + defaultType + ".")); + } + } else { + if (valueType === 'number' && !Number.isInteger(value)) { + throw new Error("Set preference: \"" + value + "\" must be an integer."); + } + } + _this4.prefs[name] = value; + return _this4._writeToStorage(_this4.prefs); + }); + } + }, { + key: "get", + value: function get(name) { + var _this5 = this; + + return this._initializedPromise.then(function () { + var defaultValue = _this5.defaults[name]; + if (defaultValue === undefined) { + throw new Error("Get preference: \"" + name + "\" is undefined."); + } else { + var prefValue = _this5.prefs[name]; + if (prefValue !== undefined) { + return prefValue; + } + } + return defaultValue; + }); + } + }]); + + return BasePreferences; +}(); + +exports.BasePreferences = BasePreferences; + +/***/ }), +/* 31 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.DownloadManager = undefined; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +var _pdfjsLib = __webpack_require__(1); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +; +function _download(blobUrl, filename) { + var a = document.createElement('a'); + if (a.click) { + a.href = blobUrl; + a.target = '_parent'; + if ('download' in a) { + a.download = filename; + } + (document.body || document.documentElement).appendChild(a); + a.click(); + a.parentNode.removeChild(a); + } else { + if (window.top === window && blobUrl.split('#')[0] === window.location.href.split('#')[0]) { + var padCharacter = blobUrl.indexOf('?') === -1 ? '?' : '&'; + blobUrl = blobUrl.replace(/#|$/, padCharacter + '$&'); + } + window.open(blobUrl, '_parent'); + } +} + +var DownloadManager = function () { + function DownloadManager() { + _classCallCheck(this, DownloadManager); + } + + _createClass(DownloadManager, [{ + key: 'downloadUrl', + value: function downloadUrl(url, filename) { + if (!(0, _pdfjsLib.createValidAbsoluteUrl)(url, 'http://example.com')) { + return; + } + _download(url + '#pdfjs.action=download', filename); + } + }, { + key: 'downloadData', + value: function downloadData(data, filename, contentType) { + if (navigator.msSaveBlob) { + return navigator.msSaveBlob(new Blob([data], { type: contentType }), filename); + } + var blobUrl = (0, _pdfjsLib.createObjectURL)(data, contentType, _pdfjsLib.PDFJS.disableCreateObjectURL); + _download(blobUrl, filename); + } + }, { + key: 'download', + value: function download(blob, url, filename) { + if (navigator.msSaveBlob) { + if (!navigator.msSaveBlob(blob, filename)) { + this.downloadUrl(url, filename); + } + return; + } + if (_pdfjsLib.PDFJS.disableCreateObjectURL) { + this.downloadUrl(url, filename); + return; + } + var blobUrl = URL.createObjectURL(blob); + _download(blobUrl, filename); + } + }]); + + return DownloadManager; +}(); + +exports.DownloadManager = DownloadManager; + +/***/ }), +/* 32 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.GenericL10n = undefined; + +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +__webpack_require__(33); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var webL10n = document.webL10n; + +var GenericL10n = function () { + function GenericL10n(lang) { + _classCallCheck(this, GenericL10n); + + this._lang = lang; + this._ready = new Promise(function (resolve, reject) { + webL10n.setLanguage(lang, function () { + resolve(webL10n); + }); + }); + } + + _createClass(GenericL10n, [{ + key: 'getDirection', + value: function getDirection() { + return this._ready.then(function (l10n) { + return l10n.getDirection(); + }); + } + }, { + key: 'get', + value: function get(property, args, fallback) { + return this._ready.then(function (l10n) { + return l10n.get(property, args, fallback); + }); + } + }, { + key: 'translate', + value: function translate(element) { + return this._ready.then(function (l10n) { + return l10n.translate(element); + }); + } + }]); + + return GenericL10n; +}(); + +exports.GenericL10n = GenericL10n; + +/***/ }), +/* 33 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +document.webL10n = function (window, document, undefined) { + var gL10nData = {}; + var gTextData = ''; + var gTextProp = 'textContent'; + var gLanguage = ''; + var gMacros = {}; + var gReadyState = 'loading'; + var gAsyncResourceLoading = true; + function getL10nResourceLinks() { + return document.querySelectorAll('link[type="application/l10n"]'); + } + function getL10nDictionary() { + var script = document.querySelector('script[type="application/l10n"]'); + return script ? JSON.parse(script.innerHTML) : null; + } + function getTranslatableChildren(element) { + return element ? element.querySelectorAll('*[data-l10n-id]') : []; + } + function getL10nAttributes(element) { + if (!element) return {}; + var l10nId = element.getAttribute('data-l10n-id'); + var l10nArgs = element.getAttribute('data-l10n-args'); + var args = {}; + if (l10nArgs) { + try { + args = JSON.parse(l10nArgs); + } catch (e) { + console.warn('could not parse arguments for #' + l10nId); + } + } + return { + id: l10nId, + args: args + }; + } + function fireL10nReadyEvent(lang) { + var evtObject = document.createEvent('Event'); + evtObject.initEvent('localized', true, false); + evtObject.language = lang; + document.dispatchEvent(evtObject); + } + function xhrLoadText(url, onSuccess, onFailure) { + onSuccess = onSuccess || function _onSuccess(data) {}; + onFailure = onFailure || function _onFailure() {}; + var xhr = new XMLHttpRequest(); + xhr.open('GET', url, gAsyncResourceLoading); + if (xhr.overrideMimeType) { + xhr.overrideMimeType('text/plain; charset=utf-8'); + } + xhr.onreadystatechange = function () { + if (xhr.readyState == 4) { + if (xhr.status == 200 || xhr.status === 0) { + onSuccess(xhr.responseText); + } else { + onFailure(); + } + } + }; + xhr.onerror = onFailure; + xhr.ontimeout = onFailure; + try { + xhr.send(null); + } catch (e) { + onFailure(); + } + } + function parseResource(href, lang, successCallback, failureCallback) { + var baseURL = href.replace(/[^\/]*$/, '') || './'; + function evalString(text) { + if (text.lastIndexOf('\\') < 0) return text; + return text.replace(/\\\\/g, '\\').replace(/\\n/g, '\n').replace(/\\r/g, '\r').replace(/\\t/g, '\t').replace(/\\b/g, '\b').replace(/\\f/g, '\f').replace(/\\{/g, '{').replace(/\\}/g, '}').replace(/\\"/g, '"').replace(/\\'/g, "'"); + } + function parseProperties(text, parsedPropertiesCallback) { + var dictionary = {}; + var reBlank = /^\s*|\s*$/; + var reComment = /^\s*#|^\s*$/; + var reSection = /^\s*\[(.*)\]\s*$/; + var reImport = /^\s*@import\s+url\((.*)\)\s*$/i; + var reSplit = /^([^=\s]*)\s*=\s*(.+)$/; + function parseRawLines(rawText, extendedSyntax, parsedRawLinesCallback) { + var entries = rawText.replace(reBlank, '').split(/[\r\n]+/); + var currentLang = '*'; + var genericLang = lang.split('-', 1)[0]; + var skipLang = false; + var match = ''; + function nextEntry() { + while (true) { + if (!entries.length) { + parsedRawLinesCallback(); + return; + } + var line = entries.shift(); + if (reComment.test(line)) continue; + if (extendedSyntax) { + match = reSection.exec(line); + if (match) { + currentLang = match[1].toLowerCase(); + skipLang = currentLang !== '*' && currentLang !== lang && currentLang !== genericLang; + continue; + } else if (skipLang) { + continue; + } + match = reImport.exec(line); + if (match) { + loadImport(baseURL + match[1], nextEntry); + return; + } + } + var tmp = line.match(reSplit); + if (tmp && tmp.length == 3) { + dictionary[tmp[1]] = evalString(tmp[2]); + } + } + } + nextEntry(); + } + function loadImport(url, callback) { + xhrLoadText(url, function (content) { + parseRawLines(content, false, callback); + }, function () { + console.warn(url + ' not found.'); + callback(); + }); + } + parseRawLines(text, true, function () { + parsedPropertiesCallback(dictionary); + }); + } + xhrLoadText(href, function (response) { + gTextData += response; + parseProperties(response, function (data) { + for (var key in data) { + var id, + prop, + index = key.lastIndexOf('.'); + if (index > 0) { + id = key.substring(0, index); + prop = key.substr(index + 1); + } else { + id = key; + prop = gTextProp; + } + if (!gL10nData[id]) { + gL10nData[id] = {}; + } + gL10nData[id][prop] = data[key]; + } + if (successCallback) { + successCallback(); + } + }); + }, failureCallback); + } + function loadLocale(lang, callback) { + if (lang) { + lang = lang.toLowerCase(); + } + callback = callback || function _callback() {}; + clear(); + gLanguage = lang; + var langLinks = getL10nResourceLinks(); + var langCount = langLinks.length; + if (langCount === 0) { + var dict = getL10nDictionary(); + if (dict && dict.locales && dict.default_locale) { + console.log('using the embedded JSON directory, early way out'); + gL10nData = dict.locales[lang]; + if (!gL10nData) { + var defaultLocale = dict.default_locale.toLowerCase(); + for (var anyCaseLang in dict.locales) { + anyCaseLang = anyCaseLang.toLowerCase(); + if (anyCaseLang === lang) { + gL10nData = dict.locales[lang]; + break; + } else if (anyCaseLang === defaultLocale) { + gL10nData = dict.locales[defaultLocale]; + } + } + } + callback(); + } else { + console.log('no resource to load, early way out'); + } + fireL10nReadyEvent(lang); + gReadyState = 'complete'; + return; + } + var onResourceLoaded = null; + var gResourceCount = 0; + onResourceLoaded = function onResourceLoaded() { + gResourceCount++; + if (gResourceCount >= langCount) { + callback(); + fireL10nReadyEvent(lang); + gReadyState = 'complete'; + } + }; + function L10nResourceLink(link) { + var href = link.href; + this.load = function (lang, callback) { + parseResource(href, lang, callback, function () { + console.warn(href + ' not found.'); + console.warn('"' + lang + '" resource not found'); + gLanguage = ''; + callback(); + }); + }; + } + for (var i = 0; i < langCount; i++) { + var resource = new L10nResourceLink(langLinks[i]); + resource.load(lang, onResourceLoaded); + } + } + function clear() { + gL10nData = {}; + gTextData = ''; + gLanguage = ''; + } + function getPluralRules(lang) { + var locales2rules = { + 'af': 3, + 'ak': 4, + 'am': 4, + 'ar': 1, + 'asa': 3, + 'az': 0, + 'be': 11, + 'bem': 3, + 'bez': 3, + 'bg': 3, + 'bh': 4, + 'bm': 0, + 'bn': 3, + 'bo': 0, + 'br': 20, + 'brx': 3, + 'bs': 11, + 'ca': 3, + 'cgg': 3, + 'chr': 3, + 'cs': 12, + 'cy': 17, + 'da': 3, + 'de': 3, + 'dv': 3, + 'dz': 0, + 'ee': 3, + 'el': 3, + 'en': 3, + 'eo': 3, + 'es': 3, + 'et': 3, + 'eu': 3, + 'fa': 0, + 'ff': 5, + 'fi': 3, + 'fil': 4, + 'fo': 3, + 'fr': 5, + 'fur': 3, + 'fy': 3, + 'ga': 8, + 'gd': 24, + 'gl': 3, + 'gsw': 3, + 'gu': 3, + 'guw': 4, + 'gv': 23, + 'ha': 3, + 'haw': 3, + 'he': 2, + 'hi': 4, + 'hr': 11, + 'hu': 0, + 'id': 0, + 'ig': 0, + 'ii': 0, + 'is': 3, + 'it': 3, + 'iu': 7, + 'ja': 0, + 'jmc': 3, + 'jv': 0, + 'ka': 0, + 'kab': 5, + 'kaj': 3, + 'kcg': 3, + 'kde': 0, + 'kea': 0, + 'kk': 3, + 'kl': 3, + 'km': 0, + 'kn': 0, + 'ko': 0, + 'ksb': 3, + 'ksh': 21, + 'ku': 3, + 'kw': 7, + 'lag': 18, + 'lb': 3, + 'lg': 3, + 'ln': 4, + 'lo': 0, + 'lt': 10, + 'lv': 6, + 'mas': 3, + 'mg': 4, + 'mk': 16, + 'ml': 3, + 'mn': 3, + 'mo': 9, + 'mr': 3, + 'ms': 0, + 'mt': 15, + 'my': 0, + 'nah': 3, + 'naq': 7, + 'nb': 3, + 'nd': 3, + 'ne': 3, + 'nl': 3, + 'nn': 3, + 'no': 3, + 'nr': 3, + 'nso': 4, + 'ny': 3, + 'nyn': 3, + 'om': 3, + 'or': 3, + 'pa': 3, + 'pap': 3, + 'pl': 13, + 'ps': 3, + 'pt': 3, + 'rm': 3, + 'ro': 9, + 'rof': 3, + 'ru': 11, + 'rwk': 3, + 'sah': 0, + 'saq': 3, + 'se': 7, + 'seh': 3, + 'ses': 0, + 'sg': 0, + 'sh': 11, + 'shi': 19, + 'sk': 12, + 'sl': 14, + 'sma': 7, + 'smi': 7, + 'smj': 7, + 'smn': 7, + 'sms': 7, + 'sn': 3, + 'so': 3, + 'sq': 3, + 'sr': 11, + 'ss': 3, + 'ssy': 3, + 'st': 3, + 'sv': 3, + 'sw': 3, + 'syr': 3, + 'ta': 3, + 'te': 3, + 'teo': 3, + 'th': 0, + 'ti': 4, + 'tig': 3, + 'tk': 3, + 'tl': 4, + 'tn': 3, + 'to': 0, + 'tr': 0, + 'ts': 3, + 'tzm': 22, + 'uk': 11, + 'ur': 3, + 've': 3, + 'vi': 0, + 'vun': 3, + 'wa': 4, + 'wae': 3, + 'wo': 0, + 'xh': 3, + 'xog': 3, + 'yo': 0, + 'zh': 0, + 'zu': 3 + }; + function isIn(n, list) { + return list.indexOf(n) !== -1; + } + function isBetween(n, start, end) { + return start <= n && n <= end; + } + var pluralRules = { + '0': function _(n) { + return 'other'; + }, + '1': function _(n) { + if (isBetween(n % 100, 3, 10)) return 'few'; + if (n === 0) return 'zero'; + if (isBetween(n % 100, 11, 99)) return 'many'; + if (n == 2) return 'two'; + if (n == 1) return 'one'; + return 'other'; + }, + '2': function _(n) { + if (n !== 0 && n % 10 === 0) return 'many'; + if (n == 2) return 'two'; + if (n == 1) return 'one'; + return 'other'; + }, + '3': function _(n) { + if (n == 1) return 'one'; + return 'other'; + }, + '4': function _(n) { + if (isBetween(n, 0, 1)) return 'one'; + return 'other'; + }, + '5': function _(n) { + if (isBetween(n, 0, 2) && n != 2) return 'one'; + return 'other'; + }, + '6': function _(n) { + if (n === 0) return 'zero'; + if (n % 10 == 1 && n % 100 != 11) return 'one'; + return 'other'; + }, + '7': function _(n) { + if (n == 2) return 'two'; + if (n == 1) return 'one'; + return 'other'; + }, + '8': function _(n) { + if (isBetween(n, 3, 6)) return 'few'; + if (isBetween(n, 7, 10)) return 'many'; + if (n == 2) return 'two'; + if (n == 1) return 'one'; + return 'other'; + }, + '9': function _(n) { + if (n === 0 || n != 1 && isBetween(n % 100, 1, 19)) return 'few'; + if (n == 1) return 'one'; + return 'other'; + }, + '10': function _(n) { + if (isBetween(n % 10, 2, 9) && !isBetween(n % 100, 11, 19)) return 'few'; + if (n % 10 == 1 && !isBetween(n % 100, 11, 19)) return 'one'; + return 'other'; + }, + '11': function _(n) { + if (isBetween(n % 10, 2, 4) && !isBetween(n % 100, 12, 14)) return 'few'; + if (n % 10 === 0 || isBetween(n % 10, 5, 9) || isBetween(n % 100, 11, 14)) return 'many'; + if (n % 10 == 1 && n % 100 != 11) return 'one'; + return 'other'; + }, + '12': function _(n) { + if (isBetween(n, 2, 4)) return 'few'; + if (n == 1) return 'one'; + return 'other'; + }, + '13': function _(n) { + if (isBetween(n % 10, 2, 4) && !isBetween(n % 100, 12, 14)) return 'few'; + if (n != 1 && isBetween(n % 10, 0, 1) || isBetween(n % 10, 5, 9) || isBetween(n % 100, 12, 14)) return 'many'; + if (n == 1) return 'one'; + return 'other'; + }, + '14': function _(n) { + if (isBetween(n % 100, 3, 4)) return 'few'; + if (n % 100 == 2) return 'two'; + if (n % 100 == 1) return 'one'; + return 'other'; + }, + '15': function _(n) { + if (n === 0 || isBetween(n % 100, 2, 10)) return 'few'; + if (isBetween(n % 100, 11, 19)) return 'many'; + if (n == 1) return 'one'; + return 'other'; + }, + '16': function _(n) { + if (n % 10 == 1 && n != 11) return 'one'; + return 'other'; + }, + '17': function _(n) { + if (n == 3) return 'few'; + if (n === 0) return 'zero'; + if (n == 6) return 'many'; + if (n == 2) return 'two'; + if (n == 1) return 'one'; + return 'other'; + }, + '18': function _(n) { + if (n === 0) return 'zero'; + if (isBetween(n, 0, 2) && n !== 0 && n != 2) return 'one'; + return 'other'; + }, + '19': function _(n) { + if (isBetween(n, 2, 10)) return 'few'; + if (isBetween(n, 0, 1)) return 'one'; + return 'other'; + }, + '20': function _(n) { + if ((isBetween(n % 10, 3, 4) || n % 10 == 9) && !(isBetween(n % 100, 10, 19) || isBetween(n % 100, 70, 79) || isBetween(n % 100, 90, 99))) return 'few'; + if (n % 1000000 === 0 && n !== 0) return 'many'; + if (n % 10 == 2 && !isIn(n % 100, [12, 72, 92])) return 'two'; + if (n % 10 == 1 && !isIn(n % 100, [11, 71, 91])) return 'one'; + return 'other'; + }, + '21': function _(n) { + if (n === 0) return 'zero'; + if (n == 1) return 'one'; + return 'other'; + }, + '22': function _(n) { + if (isBetween(n, 0, 1) || isBetween(n, 11, 99)) return 'one'; + return 'other'; + }, + '23': function _(n) { + if (isBetween(n % 10, 1, 2) || n % 20 === 0) return 'one'; + return 'other'; + }, + '24': function _(n) { + if (isBetween(n, 3, 10) || isBetween(n, 13, 19)) return 'few'; + if (isIn(n, [2, 12])) return 'two'; + if (isIn(n, [1, 11])) return 'one'; + return 'other'; + } + }; + var index = locales2rules[lang.replace(/-.*$/, '')]; + if (!(index in pluralRules)) { + console.warn('plural form unknown for [' + lang + ']'); + return function () { + return 'other'; + }; + } + return pluralRules[index]; + } + gMacros.plural = function (str, param, key, prop) { + var n = parseFloat(param); + if (isNaN(n)) return str; + if (prop != gTextProp) return str; + if (!gMacros._pluralRules) { + gMacros._pluralRules = getPluralRules(gLanguage); + } + var index = '[' + gMacros._pluralRules(n) + ']'; + if (n === 0 && key + '[zero]' in gL10nData) { + str = gL10nData[key + '[zero]'][prop]; + } else if (n == 1 && key + '[one]' in gL10nData) { + str = gL10nData[key + '[one]'][prop]; + } else if (n == 2 && key + '[two]' in gL10nData) { + str = gL10nData[key + '[two]'][prop]; + } else if (key + index in gL10nData) { + str = gL10nData[key + index][prop]; + } else if (key + '[other]' in gL10nData) { + str = gL10nData[key + '[other]'][prop]; + } + return str; + }; + function getL10nData(key, args, fallback) { + var data = gL10nData[key]; + if (!data) { + console.warn('#' + key + ' is undefined.'); + if (!fallback) { + return null; + } + data = fallback; + } + var rv = {}; + for (var prop in data) { + var str = data[prop]; + str = substIndexes(str, args, key, prop); + str = substArguments(str, args, key); + rv[prop] = str; + } + return rv; + } + function substIndexes(str, args, key, prop) { + var reIndex = /\{\[\s*([a-zA-Z]+)\(([a-zA-Z]+)\)\s*\]\}/; + var reMatch = reIndex.exec(str); + if (!reMatch || !reMatch.length) return str; + var macroName = reMatch[1]; + var paramName = reMatch[2]; + var param; + if (args && paramName in args) { + param = args[paramName]; + } else if (paramName in gL10nData) { + param = gL10nData[paramName]; + } + if (macroName in gMacros) { + var macro = gMacros[macroName]; + str = macro(str, param, key, prop); + } + return str; + } + function substArguments(str, args, key) { + var reArgs = /\{\{\s*(.+?)\s*\}\}/g; + return str.replace(reArgs, function (matched_text, arg) { + if (args && arg in args) { + return args[arg]; + } + if (arg in gL10nData) { + return gL10nData[arg]; + } + console.log('argument {{' + arg + '}} for #' + key + ' is undefined.'); + return matched_text; + }); + } + function translateElement(element) { + var l10n = getL10nAttributes(element); + if (!l10n.id) return; + var data = getL10nData(l10n.id, l10n.args); + if (!data) { + console.warn('#' + l10n.id + ' is undefined.'); + return; + } + if (data[gTextProp]) { + if (getChildElementCount(element) === 0) { + element[gTextProp] = data[gTextProp]; + } else { + var children = element.childNodes; + var found = false; + for (var i = 0, l = children.length; i < l; i++) { + if (children[i].nodeType === 3 && /\S/.test(children[i].nodeValue)) { + if (found) { + children[i].nodeValue = ''; + } else { + children[i].nodeValue = data[gTextProp]; + found = true; + } + } + } + if (!found) { + var textNode = document.createTextNode(data[gTextProp]); + element.insertBefore(textNode, element.firstChild); + } + } + delete data[gTextProp]; + } + for (var k in data) { + element[k] = data[k]; + } + } + function getChildElementCount(element) { + if (element.children) { + return element.children.length; + } + if (typeof element.childElementCount !== 'undefined') { + return element.childElementCount; + } + var count = 0; + for (var i = 0; i < element.childNodes.length; i++) { + count += element.nodeType === 1 ? 1 : 0; + } + return count; + } + function translateFragment(element) { + element = element || document.documentElement; + var children = getTranslatableChildren(element); + var elementCount = children.length; + for (var i = 0; i < elementCount; i++) { + translateElement(children[i]); + } + translateElement(element); + } + return { + get: function get(key, args, fallbackString) { + var index = key.lastIndexOf('.'); + var prop = gTextProp; + if (index > 0) { + prop = key.substr(index + 1); + key = key.substring(0, index); + } + var fallback; + if (fallbackString) { + fallback = {}; + fallback[prop] = fallbackString; + } + var data = getL10nData(key, args, fallback); + if (data && prop in data) { + return data[prop]; + } + return '{{' + key + '}}'; + }, + getData: function getData() { + return gL10nData; + }, + getText: function getText() { + return gTextData; + }, + getLanguage: function getLanguage() { + return gLanguage; + }, + setLanguage: function setLanguage(lang, callback) { + loadLocale(lang, function () { + if (callback) callback(); + }); + }, + getDirection: function getDirection() { + var rtlList = ['ar', 'he', 'fa', 'ps', 'ur']; + var shortCode = gLanguage.split('-', 1)[0]; + return rtlList.indexOf(shortCode) >= 0 ? 'rtl' : 'ltr'; + }, + translate: translateFragment, + getReadyState: function getReadyState() { + return gReadyState; + }, + ready: function ready(callback) { + if (!callback) { + return; + } else if (gReadyState == 'complete' || gReadyState == 'interactive') { + window.setTimeout(function () { + callback(); + }); + } else if (document.addEventListener) { + document.addEventListener('localized', function once() { + document.removeEventListener('localized', once); + callback(); + }); + } + } + }; +}(window, document); + +/***/ }), +/* 34 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.PDFPrintService = undefined; + +var _ui_utils = __webpack_require__(0); + +var _app = __webpack_require__(4); + +var _pdfjsLib = __webpack_require__(1); + +var activeService = null; +var overlayManager = null; +function renderPage(activeServiceOnEntry, pdfDocument, pageNumber, size) { + var scratchCanvas = activeService.scratchCanvas; + var PRINT_RESOLUTION = 150; + var PRINT_UNITS = PRINT_RESOLUTION / 72.0; + scratchCanvas.width = Math.floor(size.width * PRINT_UNITS); + scratchCanvas.height = Math.floor(size.height * PRINT_UNITS); + var width = Math.floor(size.width * _ui_utils.CSS_UNITS) + 'px'; + var height = Math.floor(size.height * _ui_utils.CSS_UNITS) + 'px'; + var ctx = scratchCanvas.getContext('2d'); + ctx.save(); + ctx.fillStyle = 'rgb(255, 255, 255)'; + ctx.fillRect(0, 0, scratchCanvas.width, scratchCanvas.height); + ctx.restore(); + return pdfDocument.getPage(pageNumber).then(function (pdfPage) { + var renderContext = { + canvasContext: ctx, + transform: [PRINT_UNITS, 0, 0, PRINT_UNITS, 0, 0], + viewport: pdfPage.getViewport(1, size.rotation), + intent: 'print' + }; + return pdfPage.render(renderContext).promise; + }).then(function () { + return { + width: width, + height: height + }; + }); +} +function PDFPrintService(pdfDocument, pagesOverview, printContainer, l10n) { + this.pdfDocument = pdfDocument; + this.pagesOverview = pagesOverview; + this.printContainer = printContainer; + this.l10n = l10n || _ui_utils.NullL10n; + this.currentPage = -1; + this.scratchCanvas = document.createElement('canvas'); +} +PDFPrintService.prototype = { + layout: function layout() { + this.throwIfInactive(); + var body = document.querySelector('body'); + body.setAttribute('data-pdfjsprinting', true); + var hasEqualPageSizes = this.pagesOverview.every(function (size) { + return size.width === this.pagesOverview[0].width && size.height === this.pagesOverview[0].height; + }, this); + if (!hasEqualPageSizes) { + console.warn('Not all pages have the same size. The printed ' + 'result may be incorrect!'); + } + this.pageStyleSheet = document.createElement('style'); + var pageSize = this.pagesOverview[0]; + this.pageStyleSheet.textContent = '@supports ((size:A4) and (size:1pt 1pt)) {' + '@page { size: ' + pageSize.width + 'pt ' + pageSize.height + 'pt;}' + '}'; + body.appendChild(this.pageStyleSheet); + }, + destroy: function destroy() { + if (activeService !== this) { + return; + } + this.printContainer.textContent = ''; + if (this.pageStyleSheet && this.pageStyleSheet.parentNode) { + this.pageStyleSheet.parentNode.removeChild(this.pageStyleSheet); + this.pageStyleSheet = null; + } + this.scratchCanvas.width = this.scratchCanvas.height = 0; + this.scratchCanvas = null; + activeService = null; + ensureOverlay().then(function () { + if (overlayManager.active !== 'printServiceOverlay') { + return; + } + overlayManager.close('printServiceOverlay'); + }); + }, + renderPages: function renderPages() { + var _this = this; + + var pageCount = this.pagesOverview.length; + var renderNextPage = function renderNextPage(resolve, reject) { + _this.throwIfInactive(); + if (++_this.currentPage >= pageCount) { + renderProgress(pageCount, pageCount, _this.l10n); + resolve(); + return; + } + var index = _this.currentPage; + renderProgress(index, pageCount, _this.l10n); + renderPage(_this, _this.pdfDocument, index + 1, _this.pagesOverview[index]).then(_this.useRenderedPage.bind(_this)).then(function () { + renderNextPage(resolve, reject); + }, reject); + }; + return new Promise(renderNextPage); + }, + useRenderedPage: function useRenderedPage(printItem) { + this.throwIfInactive(); + var img = document.createElement('img'); + img.style.width = printItem.width; + img.style.height = printItem.height; + var scratchCanvas = this.scratchCanvas; + if ('toBlob' in scratchCanvas && !_pdfjsLib.PDFJS.disableCreateObjectURL) { + scratchCanvas.toBlob(function (blob) { + img.src = URL.createObjectURL(blob); + }); + } else { + img.src = scratchCanvas.toDataURL(); + } + var wrapper = document.createElement('div'); + wrapper.appendChild(img); + this.printContainer.appendChild(wrapper); + return new Promise(function (resolve, reject) { + img.onload = resolve; + img.onerror = reject; + }); + }, + performPrint: function performPrint() { + var _this2 = this; + + this.throwIfInactive(); + return new Promise(function (resolve) { + setTimeout(function () { + if (!_this2.active) { + resolve(); + return; + } + print.call(window); + setTimeout(resolve, 20); + }, 0); + }); + }, + + get active() { + return this === activeService; + }, + throwIfInactive: function throwIfInactive() { + if (!this.active) { + throw new Error('This print request was cancelled or completed.'); + } + } +}; +var print = window.print; +window.print = function print() { + if (activeService) { + console.warn('Ignored window.print() because of a pending print job.'); + return; + } + ensureOverlay().then(function () { + if (activeService) { + overlayManager.open('printServiceOverlay'); + } + }); + try { + dispatchEvent('beforeprint'); + } finally { + if (!activeService) { + console.error('Expected print service to be initialized.'); + ensureOverlay().then(function () { + if (overlayManager.active === 'printServiceOverlay') { + overlayManager.close('printServiceOverlay'); + } + }); + return; + } + var activeServiceOnEntry = activeService; + activeService.renderPages().then(function () { + return activeServiceOnEntry.performPrint(); + }).catch(function () {}).then(function () { + if (activeServiceOnEntry.active) { + abort(); + } + }); + } +}; +function dispatchEvent(eventType) { + var event = document.createEvent('CustomEvent'); + event.initCustomEvent(eventType, false, false, 'custom'); + window.dispatchEvent(event); +} +function abort() { + if (activeService) { + activeService.destroy(); + dispatchEvent('afterprint'); + } +} +function renderProgress(index, total, l10n) { + var progressContainer = document.getElementById('printServiceOverlay'); + var progress = Math.round(100 * index / total); + var progressBar = progressContainer.querySelector('progress'); + var progressPerc = progressContainer.querySelector('.relative-progress'); + progressBar.value = progress; + l10n.get('print_progress_percent', { progress: progress }, progress + '%').then(function (msg) { + progressPerc.textContent = msg; + }); +} +var hasAttachEvent = !!document.attachEvent; +window.addEventListener('keydown', function (event) { + if (event.keyCode === 80 && (event.ctrlKey || event.metaKey) && !event.altKey && (!event.shiftKey || window.chrome || window.opera)) { + window.print(); + if (hasAttachEvent) { + return; + } + event.preventDefault(); + if (event.stopImmediatePropagation) { + event.stopImmediatePropagation(); + } else { + event.stopPropagation(); + } + return; + } +}, true); +if (hasAttachEvent) { + document.attachEvent('onkeydown', function (event) { + event = event || window.event; + if (event.keyCode === 80 && event.ctrlKey) { + event.keyCode = 0; + return false; + } + }); +} +if ('onbeforeprint' in window) { + var stopPropagationIfNeeded = function stopPropagationIfNeeded(event) { + if (event.detail !== 'custom' && event.stopImmediatePropagation) { + event.stopImmediatePropagation(); + } + }; + window.addEventListener('beforeprint', stopPropagationIfNeeded); + window.addEventListener('afterprint', stopPropagationIfNeeded); +} +var overlayPromise; +function ensureOverlay() { + if (!overlayPromise) { + overlayManager = _app.PDFViewerApplication.overlayManager; + if (!overlayManager) { + throw new Error('The overlay manager has not yet been initialized.'); + } + overlayPromise = overlayManager.register('printServiceOverlay', document.getElementById('printServiceOverlay'), abort, true); + document.getElementById('printCancel').onclick = abort; + } + return overlayPromise; +} +_app.PDFPrintServiceFactory.instance = { + supportsPrinting: true, + createPrintService: function createPrintService(pdfDocument, pagesOverview, printContainer, l10n) { + if (activeService) { + throw new Error('The print service is created and active.'); + } + activeService = new PDFPrintService(pdfDocument, pagesOverview, printContainer, l10n); + return activeService; + } +}; +exports.PDFPrintService = PDFPrintService; + +/***/ }) +/******/ ]); +//# sourceMappingURL=viewer.js.map \ No newline at end of file diff --git a/org.adempiere.ui.zk/pdf.js/web/viewer.js.map b/org.adempiere.ui.zk/pdf.js/web/viewer.js.map new file mode 100644 index 0000000000..d7544d1360 --- /dev/null +++ b/org.adempiere.ui.zk/pdf.js/web/viewer.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["webpack:///webpack/bootstrap 3c33d1830224ccaf767e","webpack:///web/ui_utils.js","webpack:///web/pdfjs.js","webpack:///web/dom_events.js","webpack:///web/pdf_rendering_queue.js","webpack:///web/app.js","webpack:///web/pdf_link_service.js","webpack:///web/pdf_cursor_tools.js","webpack:///web/pdf_find_controller.js","webpack:///web/viewer.js","webpack:///web/grab_to_pan.js","webpack:///web/pdf_sidebar.js","webpack:///web/overlay_manager.js","webpack:///web/password_prompt.js","webpack:///web/pdf_attachment_viewer.js","webpack:///web/pdf_document_properties.js","webpack:///web/pdf_find_bar.js","webpack:///web/pdf_history.js","webpack:///web/pdf_outline_viewer.js","webpack:///web/pdf_presentation_mode.js","webpack:///web/pdf_thumbnail_viewer.js","webpack:///web/pdf_thumbnail_view.js","webpack:///web/pdf_viewer.js","webpack:///web/base_viewer.js","webpack:///web/annotation_layer_builder.js","webpack:///web/pdf_page_view.js","webpack:///web/text_layer_builder.js","webpack:///web/secondary_toolbar.js","webpack:///web/toolbar.js","webpack:///web/view_history.js","webpack:///web/genericcom.js","webpack:///web/preferences.js","webpack:///web/download_manager.js","webpack:///web/genericl10n.js","webpack:///external/webL10n/l10n.js","webpack:///web/pdf_print_service.js"],"names":[],"mappings":"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","file":"viewer.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 8);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 3c33d1830224ccaf767e","/* Copyright 2012 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { createPromiseCapability, PDFJS } from 'pdfjs-lib';\n\nconst CSS_UNITS = 96.0 / 72.0;\nconst DEFAULT_SCALE_VALUE = 'auto';\nconst DEFAULT_SCALE = 1.0;\nconst MIN_SCALE = 0.25;\nconst MAX_SCALE = 10.0;\nconst UNKNOWN_SCALE = 0;\nconst MAX_AUTO_SCALE = 1.25;\nconst SCROLLBAR_PADDING = 40;\nconst VERTICAL_PADDING = 5;\n\nconst PresentationModeState = {\n UNKNOWN: 0,\n NORMAL: 1,\n CHANGING: 2,\n FULLSCREEN: 3,\n};\n\nconst RendererType = {\n CANVAS: 'canvas',\n SVG: 'svg',\n};\n\n// Replaces {{arguments}} with their values.\nfunction formatL10nValue(text, args) {\n if (!args) {\n return text;\n }\n return text.replace(/\\{\\{\\s*(\\w+)\\s*\\}\\}/g, (all, name) => {\n return (name in args ? args[name] : '{{' + name + '}}');\n });\n}\n\n/**\n * No-op implemetation of the localization service.\n * @implements {IL10n}\n */\nlet NullL10n = {\n get(property, args, fallback) {\n return Promise.resolve(formatL10nValue(fallback, args));\n },\n\n translate(element) {\n return Promise.resolve();\n },\n};\n\n/**\n * Disables fullscreen support, and by extension Presentation Mode,\n * in browsers which support the fullscreen API.\n * @var {boolean}\n */\nPDFJS.disableFullscreen = (PDFJS.disableFullscreen === undefined ?\n false : PDFJS.disableFullscreen);\n\n/**\n * Enables CSS only zooming.\n * @var {boolean}\n */\nPDFJS.useOnlyCssZoom = (PDFJS.useOnlyCssZoom === undefined ?\n false : PDFJS.useOnlyCssZoom);\n\n/**\n * The maximum supported canvas size in total pixels e.g. width * height.\n * The default value is 4096 * 4096. Use -1 for no limit.\n * @var {number}\n */\nPDFJS.maxCanvasPixels = (PDFJS.maxCanvasPixels === undefined ?\n 16777216 : PDFJS.maxCanvasPixels);\n\n/**\n * Disables saving of the last position of the viewed PDF.\n * @var {boolean}\n */\nPDFJS.disableHistory = (PDFJS.disableHistory === undefined ?\n false : PDFJS.disableHistory);\n\n/**\n * Disables creation of the text layer that used for text selection and search.\n * @var {boolean}\n */\nPDFJS.disableTextLayer = (PDFJS.disableTextLayer === undefined ?\n false : PDFJS.disableTextLayer);\n\n/**\n * Disables maintaining the current position in the document when zooming.\n */\nPDFJS.ignoreCurrentPositionOnZoom = (PDFJS.ignoreCurrentPositionOnZoom ===\n undefined ? false : PDFJS.ignoreCurrentPositionOnZoom);\n\nif (typeof PDFJSDev === 'undefined' ||\n !PDFJSDev.test('FIREFOX || MOZCENTRAL')) {\n /**\n * Interface locale settings.\n * @var {string}\n */\n PDFJS.locale =\n (PDFJS.locale === undefined && typeof navigator !== 'undefined' ?\n navigator.language : PDFJS.locale);\n}\n\n/**\n * Returns scale factor for the canvas. It makes sense for the HiDPI displays.\n * @return {Object} The object with horizontal (sx) and vertical (sy)\n scales. The scaled property is set to false if scaling is\n not required, true otherwise.\n */\nfunction getOutputScale(ctx) {\n let devicePixelRatio = window.devicePixelRatio || 1;\n let backingStoreRatio = ctx.webkitBackingStorePixelRatio ||\n ctx.mozBackingStorePixelRatio ||\n ctx.msBackingStorePixelRatio ||\n ctx.oBackingStorePixelRatio ||\n ctx.backingStorePixelRatio || 1;\n let pixelRatio = devicePixelRatio / backingStoreRatio;\n return {\n sx: pixelRatio,\n sy: pixelRatio,\n scaled: pixelRatio !== 1,\n };\n}\n\n/**\n * Scrolls specified element into view of its parent.\n * @param {Object} element - The element to be visible.\n * @param {Object} spot - An object with optional top and left properties,\n * specifying the offset from the top left edge.\n * @param {boolean} skipOverflowHiddenElements - Ignore elements that have\n * the CSS rule `overflow: hidden;` set. The default is false.\n */\nfunction scrollIntoView(element, spot, skipOverflowHiddenElements = false) {\n // Assuming offsetParent is available (it's not available when viewer is in\n // hidden iframe or object). We have to scroll: if the offsetParent is not set\n // producing the error. See also animationStarted.\n let parent = element.offsetParent;\n if (!parent) {\n console.error('offsetParent is not set -- cannot scroll');\n return;\n }\n let offsetY = element.offsetTop + element.clientTop;\n let offsetX = element.offsetLeft + element.clientLeft;\n while (parent.clientHeight === parent.scrollHeight ||\n (skipOverflowHiddenElements &&\n getComputedStyle(parent).overflow === 'hidden')) {\n if (parent.dataset._scaleY) {\n offsetY /= parent.dataset._scaleY;\n offsetX /= parent.dataset._scaleX;\n }\n offsetY += parent.offsetTop;\n offsetX += parent.offsetLeft;\n parent = parent.offsetParent;\n if (!parent) {\n return; // no need to scroll\n }\n }\n if (spot) {\n if (spot.top !== undefined) {\n offsetY += spot.top;\n }\n if (spot.left !== undefined) {\n offsetX += spot.left;\n parent.scrollLeft = offsetX;\n }\n }\n parent.scrollTop = offsetY;\n}\n\n/**\n * Helper function to start monitoring the scroll event and converting them into\n * PDF.js friendly one: with scroll debounce and scroll direction.\n */\nfunction watchScroll(viewAreaElement, callback) {\n let debounceScroll = function(evt) {\n if (rAF) {\n return;\n }\n // schedule an invocation of scroll for next animation frame.\n rAF = window.requestAnimationFrame(function viewAreaElementScrolled() {\n rAF = null;\n\n let currentY = viewAreaElement.scrollTop;\n let lastY = state.lastY;\n if (currentY !== lastY) {\n state.down = currentY > lastY;\n }\n state.lastY = currentY;\n callback(state);\n });\n };\n\n let state = {\n down: true,\n lastY: viewAreaElement.scrollTop,\n _eventHandler: debounceScroll,\n };\n\n let rAF = null;\n viewAreaElement.addEventListener('scroll', debounceScroll, true);\n return state;\n}\n\n/**\n * Helper function to parse query string (e.g. ?param1=value&parm2=...).\n */\nfunction parseQueryString(query) {\n let parts = query.split('&');\n let params = Object.create(null);\n for (let i = 0, ii = parts.length; i < ii; ++i) {\n let param = parts[i].split('=');\n let key = param[0].toLowerCase();\n let value = param.length > 1 ? param[1] : null;\n params[decodeURIComponent(key)] = decodeURIComponent(value);\n }\n return params;\n}\n\n/**\n * Use binary search to find the index of the first item in a given array which\n * passes a given condition. The items are expected to be sorted in the sense\n * that if the condition is true for one item in the array, then it is also true\n * for all following items.\n *\n * @returns {Number} Index of the first array element to pass the test,\n * or |items.length| if no such element exists.\n */\nfunction binarySearchFirstItem(items, condition) {\n let minIndex = 0;\n let maxIndex = items.length - 1;\n\n if (items.length === 0 || !condition(items[maxIndex])) {\n return items.length;\n }\n if (condition(items[minIndex])) {\n return minIndex;\n }\n\n while (minIndex < maxIndex) {\n let currentIndex = (minIndex + maxIndex) >> 1;\n let currentItem = items[currentIndex];\n if (condition(currentItem)) {\n maxIndex = currentIndex;\n } else {\n minIndex = currentIndex + 1;\n }\n }\n return minIndex; /* === maxIndex */\n}\n\n/**\n * Approximates float number as a fraction using Farey sequence (max order\n * of 8).\n * @param {number} x - Positive float number.\n * @returns {Array} Estimated fraction: the first array item is a numerator,\n * the second one is a denominator.\n */\nfunction approximateFraction(x) {\n // Fast paths for int numbers or their inversions.\n if (Math.floor(x) === x) {\n return [x, 1];\n }\n let xinv = 1 / x;\n let limit = 8;\n if (xinv > limit) {\n return [1, limit];\n } else if (Math.floor(xinv) === xinv) {\n return [1, xinv];\n }\n\n let x_ = x > 1 ? xinv : x;\n // a/b and c/d are neighbours in Farey sequence.\n let a = 0, b = 1, c = 1, d = 1;\n // Limiting search to order 8.\n while (true) {\n // Generating next term in sequence (order of q).\n let p = a + c, q = b + d;\n if (q > limit) {\n break;\n }\n if (x_ <= p / q) {\n c = p; d = q;\n } else {\n a = p; b = q;\n }\n }\n let result;\n // Select closest of the neighbours to x.\n if (x_ - a / b < c / d - x_) {\n result = x_ === x ? [a, b] : [b, a];\n } else {\n result = x_ === x ? [c, d] : [d, c];\n }\n return result;\n}\n\nfunction roundToDivide(x, div) {\n let r = x % div;\n return r === 0 ? x : Math.round(x - r + div);\n}\n\n/**\n * Generic helper to find out what elements are visible within a scroll pane.\n */\nfunction getVisibleElements(scrollEl, views, sortByVisibility = false) {\n let top = scrollEl.scrollTop, bottom = top + scrollEl.clientHeight;\n let left = scrollEl.scrollLeft, right = left + scrollEl.clientWidth;\n\n function isElementBottomBelowViewTop(view) {\n let element = view.div;\n let elementBottom =\n element.offsetTop + element.clientTop + element.clientHeight;\n return elementBottom > top;\n }\n\n let visible = [], view, element;\n let currentHeight, viewHeight, hiddenHeight, percentHeight;\n let currentWidth, viewWidth;\n let firstVisibleElementInd = views.length === 0 ? 0 :\n binarySearchFirstItem(views, isElementBottomBelowViewTop);\n\n for (let i = firstVisibleElementInd, ii = views.length; i < ii; i++) {\n view = views[i];\n element = view.div;\n currentHeight = element.offsetTop + element.clientTop;\n viewHeight = element.clientHeight;\n\n if (currentHeight > bottom) {\n break;\n }\n\n currentWidth = element.offsetLeft + element.clientLeft;\n viewWidth = element.clientWidth;\n if (currentWidth + viewWidth < left || currentWidth > right) {\n continue;\n }\n hiddenHeight = Math.max(0, top - currentHeight) +\n Math.max(0, currentHeight + viewHeight - bottom);\n percentHeight = ((viewHeight - hiddenHeight) * 100 / viewHeight) | 0;\n\n visible.push({\n id: view.id,\n x: currentWidth,\n y: currentHeight,\n view,\n percent: percentHeight,\n });\n }\n\n let first = visible[0];\n let last = visible[visible.length - 1];\n\n if (sortByVisibility) {\n visible.sort(function(a, b) {\n let pc = a.percent - b.percent;\n if (Math.abs(pc) > 0.001) {\n return -pc;\n }\n return a.id - b.id; // ensure stability\n });\n }\n return { first, last, views: visible, };\n}\n\n/**\n * Event handler to suppress context menu.\n */\nfunction noContextMenuHandler(evt) {\n evt.preventDefault();\n}\n\nfunction isDataSchema(url) {\n let i = 0, ii = url.length;\n while (i < ii && url[i].trim() === '') {\n i++;\n }\n return url.substr(i, 5).toLowerCase() === 'data:';\n}\n\n/**\n * Returns the filename or guessed filename from the url (see issue 3455).\n * @param {string} url - The original PDF location.\n * @param {string} defaultFilename - The value returned if the filename is\n * unknown, or the protocol is unsupported.\n * @returns {string} Guessed PDF filename.\n */\nfunction getPDFFileNameFromURL(url, defaultFilename = 'document.pdf') {\n if (isDataSchema(url)) {\n console.warn('getPDFFileNameFromURL: ' +\n 'ignoring \"data:\" URL for performance reasons.');\n return defaultFilename;\n }\n const reURI = /^(?:(?:[^:]+:)?\\/\\/[^\\/]+)?([^?#]*)(\\?[^#]*)?(#.*)?$/;\n // SCHEME HOST 1.PATH 2.QUERY 3.REF\n // Pattern to get last matching NAME.pdf\n const reFilename = /[^\\/?#=]+\\.pdf\\b(?!.*\\.pdf\\b)/i;\n let splitURI = reURI.exec(url);\n let suggestedFilename = reFilename.exec(splitURI[1]) ||\n reFilename.exec(splitURI[2]) ||\n reFilename.exec(splitURI[3]);\n if (suggestedFilename) {\n suggestedFilename = suggestedFilename[0];\n if (suggestedFilename.indexOf('%') !== -1) {\n // URL-encoded %2Fpath%2Fto%2Ffile.pdf should be file.pdf\n try {\n suggestedFilename =\n reFilename.exec(decodeURIComponent(suggestedFilename))[0];\n } catch (ex) { // Possible (extremely rare) errors:\n // URIError \"Malformed URI\", e.g. for \"%AA.pdf\"\n // TypeError \"null has no properties\", e.g. for \"%2F.pdf\"\n }\n }\n }\n return suggestedFilename || defaultFilename;\n}\n\nfunction normalizeWheelEventDelta(evt) {\n let delta = Math.sqrt(evt.deltaX * evt.deltaX + evt.deltaY * evt.deltaY);\n let angle = Math.atan2(evt.deltaY, evt.deltaX);\n if (-0.25 * Math.PI < angle && angle < 0.75 * Math.PI) {\n // All that is left-up oriented has to change the sign.\n delta = -delta;\n }\n\n const MOUSE_DOM_DELTA_PIXEL_MODE = 0;\n const MOUSE_DOM_DELTA_LINE_MODE = 1;\n const MOUSE_PIXELS_PER_LINE = 30;\n const MOUSE_LINES_PER_PAGE = 30;\n\n // Converts delta to per-page units\n if (evt.deltaMode === MOUSE_DOM_DELTA_PIXEL_MODE) {\n delta /= MOUSE_PIXELS_PER_LINE * MOUSE_LINES_PER_PAGE;\n } else if (evt.deltaMode === MOUSE_DOM_DELTA_LINE_MODE) {\n delta /= MOUSE_LINES_PER_PAGE;\n }\n return delta;\n}\n\nfunction isValidRotation(angle) {\n return Number.isInteger(angle) && angle % 90 === 0;\n}\n\nfunction cloneObj(obj) {\n let result = Object.create(null);\n for (let i in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, i)) {\n result[i] = obj[i];\n }\n }\n return result;\n}\n\nconst WaitOnType = {\n EVENT: 'event',\n TIMEOUT: 'timeout',\n};\n\n/**\n * @typedef {Object} WaitOnEventOrTimeoutParameters\n * @property {Object} target - The event target, can for example be:\n * `window`, `document`, a DOM element, or an {EventBus} instance.\n * @property {string} name - The name of the event.\n * @property {number} delay - The delay, in milliseconds, after which the\n * timeout occurs (if the event wasn't already dispatched).\n */\n\n/**\n * Allows waiting for an event or a timeout, whichever occurs first.\n * Can be used to ensure that an action always occurs, even when an event\n * arrives late or not at all.\n *\n * @param {WaitOnEventOrTimeoutParameters}\n * @returns {Promise} A promise that is resolved with a {WaitOnType} value.\n */\nfunction waitOnEventOrTimeout({ target, name, delay = 0, }) {\n if (typeof target !== 'object' || !(name && typeof name === 'string') ||\n !(Number.isInteger(delay) && delay >= 0)) {\n return Promise.reject(\n new Error('waitOnEventOrTimeout - invalid paramaters.'));\n }\n let capability = createPromiseCapability();\n\n function handler(type) {\n if (target instanceof EventBus) {\n target.off(name, eventHandler);\n } else {\n target.removeEventListener(name, eventHandler);\n }\n\n if (timeout) {\n clearTimeout(timeout);\n }\n capability.resolve(type);\n }\n\n let eventHandler = handler.bind(null, WaitOnType.EVENT);\n if (target instanceof EventBus) {\n target.on(name, eventHandler);\n } else {\n target.addEventListener(name, eventHandler);\n }\n\n let timeoutHandler = handler.bind(null, WaitOnType.TIMEOUT);\n let timeout = setTimeout(timeoutHandler, delay);\n\n return capability.promise;\n}\n\n/**\n * Promise that is resolved when DOM window becomes visible.\n */\nlet animationStarted = new Promise(function (resolve) {\n window.requestAnimationFrame(resolve);\n});\n\n/**\n * (deprecated) External localization service.\n */\nlet mozL10n;\n\n/**\n * (deprecated) Promise that is resolved when UI localization is finished.\n */\nlet localized = Promise.resolve();\n\n/**\n * Simple event bus for an application. Listeners are attached using the\n * `on` and `off` methods. To raise an event, the `dispatch` method shall be\n * used.\n */\nclass EventBus {\n constructor() {\n this._listeners = Object.create(null);\n }\n\n on(eventName, listener) {\n let eventListeners = this._listeners[eventName];\n if (!eventListeners) {\n eventListeners = [];\n this._listeners[eventName] = eventListeners;\n }\n eventListeners.push(listener);\n }\n\n off(eventName, listener) {\n let eventListeners = this._listeners[eventName];\n let i;\n if (!eventListeners || ((i = eventListeners.indexOf(listener)) < 0)) {\n return;\n }\n eventListeners.splice(i, 1);\n }\n\n dispatch(eventName) {\n let eventListeners = this._listeners[eventName];\n if (!eventListeners || eventListeners.length === 0) {\n return;\n }\n // Passing all arguments after the eventName to the listeners.\n let args = Array.prototype.slice.call(arguments, 1);\n // Making copy of the listeners array in case if it will be modified\n // during dispatch.\n eventListeners.slice(0).forEach(function (listener) {\n listener.apply(null, args);\n });\n }\n}\n\nfunction clamp(v, min, max) {\n return Math.min(Math.max(v, min), max);\n}\n\nclass ProgressBar {\n constructor(id, { height, width, units, } = {}) {\n this.visible = true;\n\n // Fetch the sub-elements for later.\n this.div = document.querySelector(id + ' .progress');\n // Get the loading bar element, so it can be resized to fit the viewer.\n this.bar = this.div.parentNode;\n\n // Get options, with sensible defaults.\n this.height = height || 100;\n this.width = width || 100;\n this.units = units || '%';\n\n // Initialize heights.\n this.div.style.height = this.height + this.units;\n this.percent = 0;\n }\n\n _updateBar() {\n if (this._indeterminate) {\n this.div.classList.add('indeterminate');\n this.div.style.width = this.width + this.units;\n return;\n }\n\n this.div.classList.remove('indeterminate');\n let progressSize = this.width * this._percent / 100;\n this.div.style.width = progressSize + this.units;\n }\n\n get percent() {\n return this._percent;\n }\n\n set percent(val) {\n this._indeterminate = isNaN(val);\n this._percent = clamp(val, 0, 100);\n this._updateBar();\n }\n\n setWidth(viewer) {\n if (!viewer) {\n return;\n }\n let container = viewer.parentNode;\n let scrollbarWidth = container.offsetWidth - viewer.offsetWidth;\n if (scrollbarWidth > 0) {\n this.bar.setAttribute('style', 'width: calc(100% - ' +\n scrollbarWidth + 'px);');\n }\n }\n\n hide() {\n if (!this.visible) {\n return;\n }\n this.visible = false;\n this.bar.classList.add('hidden');\n document.body.classList.remove('loadingInProgress');\n }\n\n show() {\n if (this.visible) {\n return;\n }\n this.visible = true;\n document.body.classList.add('loadingInProgress');\n this.bar.classList.remove('hidden');\n }\n}\n\nexport {\n CSS_UNITS,\n DEFAULT_SCALE_VALUE,\n DEFAULT_SCALE,\n MIN_SCALE,\n MAX_SCALE,\n UNKNOWN_SCALE,\n MAX_AUTO_SCALE,\n SCROLLBAR_PADDING,\n VERTICAL_PADDING,\n isValidRotation,\n cloneObj,\n PresentationModeState,\n RendererType,\n mozL10n,\n NullL10n,\n EventBus,\n ProgressBar,\n getPDFFileNameFromURL,\n noContextMenuHandler,\n parseQueryString,\n getVisibleElements,\n roundToDivide,\n approximateFraction,\n getOutputScale,\n scrollIntoView,\n watchScroll,\n binarySearchFirstItem,\n normalizeWheelEventDelta,\n animationStarted,\n localized,\n WaitOnType,\n waitOnEventOrTimeout,\n};\n\n\n\n// WEBPACK FOOTER //\n// web/ui_utils.js","/* Copyright 2016 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/* globals module, __non_webpack_require__ */\n\n'use strict';\n\nvar pdfjsLib;\nif (typeof window !== 'undefined' && window['pdfjs-dist/build/pdf']) {\n pdfjsLib = window['pdfjs-dist/build/pdf'];\n} else {\n pdfjsLib = __non_webpack_require__('../build/pdf.js');\n}\nmodule.exports = pdfjsLib;\n\n\n\n// WEBPACK FOOTER //\n// web/pdfjs.js","/* Copyright 2016 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { EventBus } from './ui_utils';\n\n// Attaching to the application event bus to dispatch events to the DOM for\n// backwards viewer API compatibility.\nfunction attachDOMEventsToEventBus(eventBus) {\n eventBus.on('documentload', function() {\n let event = document.createEvent('CustomEvent');\n event.initCustomEvent('documentload', true, true, {});\n window.dispatchEvent(event);\n });\n eventBus.on('pagerendered', function(evt) {\n let event = document.createEvent('CustomEvent');\n event.initCustomEvent('pagerendered', true, true, {\n pageNumber: evt.pageNumber,\n cssTransform: evt.cssTransform,\n });\n evt.source.div.dispatchEvent(event);\n });\n eventBus.on('textlayerrendered', function(evt) {\n let event = document.createEvent('CustomEvent');\n event.initCustomEvent('textlayerrendered', true, true, {\n pageNumber: evt.pageNumber,\n });\n evt.source.textLayerDiv.dispatchEvent(event);\n });\n eventBus.on('pagechange', function(evt) {\n let event = document.createEvent('UIEvents');\n event.initUIEvent('pagechange', true, true, window, 0);\n event.pageNumber = evt.pageNumber;\n evt.source.container.dispatchEvent(event);\n });\n eventBus.on('pagesinit', function(evt) {\n let event = document.createEvent('CustomEvent');\n event.initCustomEvent('pagesinit', true, true, null);\n evt.source.container.dispatchEvent(event);\n });\n eventBus.on('pagesloaded', function(evt) {\n let event = document.createEvent('CustomEvent');\n event.initCustomEvent('pagesloaded', true, true, {\n pagesCount: evt.pagesCount,\n });\n evt.source.container.dispatchEvent(event);\n });\n eventBus.on('scalechange', function(evt) {\n let event = document.createEvent('UIEvents');\n event.initUIEvent('scalechange', true, true, window, 0);\n event.scale = evt.scale;\n event.presetValue = evt.presetValue;\n evt.source.container.dispatchEvent(event);\n });\n eventBus.on('updateviewarea', function(evt) {\n let event = document.createEvent('UIEvents');\n event.initUIEvent('updateviewarea', true, true, window, 0);\n event.location = evt.location;\n evt.source.container.dispatchEvent(event);\n });\n eventBus.on('find', function(evt) {\n if (evt.source === window) {\n return; // event comes from FirefoxCom, no need to replicate\n }\n let event = document.createEvent('CustomEvent');\n event.initCustomEvent('find' + evt.type, true, true, {\n query: evt.query,\n phraseSearch: evt.phraseSearch,\n caseSensitive: evt.caseSensitive,\n highlightAll: evt.highlightAll,\n findPrevious: evt.findPrevious,\n });\n window.dispatchEvent(event);\n });\n eventBus.on('attachmentsloaded', function(evt) {\n let event = document.createEvent('CustomEvent');\n event.initCustomEvent('attachmentsloaded', true, true, {\n attachmentsCount: evt.attachmentsCount,\n });\n evt.source.container.dispatchEvent(event);\n });\n eventBus.on('sidebarviewchanged', function(evt) {\n let event = document.createEvent('CustomEvent');\n event.initCustomEvent('sidebarviewchanged', true, true, {\n view: evt.view,\n });\n evt.source.outerContainer.dispatchEvent(event);\n });\n eventBus.on('pagemode', function(evt) {\n let event = document.createEvent('CustomEvent');\n event.initCustomEvent('pagemode', true, true, {\n mode: evt.mode,\n });\n evt.source.pdfViewer.container.dispatchEvent(event);\n });\n eventBus.on('namedaction', function(evt) {\n let event = document.createEvent('CustomEvent');\n event.initCustomEvent('namedaction', true, true, {\n action: evt.action,\n });\n evt.source.pdfViewer.container.dispatchEvent(event);\n });\n eventBus.on('presentationmodechanged', function(evt) {\n let event = document.createEvent('CustomEvent');\n event.initCustomEvent('presentationmodechanged', true, true, {\n active: evt.active,\n switchInProgress: evt.switchInProgress,\n });\n window.dispatchEvent(event);\n });\n eventBus.on('outlineloaded', function(evt) {\n let event = document.createEvent('CustomEvent');\n event.initCustomEvent('outlineloaded', true, true, {\n outlineCount: evt.outlineCount,\n });\n evt.source.container.dispatchEvent(event);\n });\n}\n\nlet globalEventBus = null;\nfunction getGlobalEventBus() {\n if (globalEventBus) {\n return globalEventBus;\n }\n globalEventBus = new EventBus();\n attachDOMEventsToEventBus(globalEventBus);\n return globalEventBus;\n}\n\nexport {\n attachDOMEventsToEventBus,\n getGlobalEventBus,\n};\n\n\n\n// WEBPACK FOOTER //\n// web/dom_events.js","/* Copyright 2012 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nconst CLEANUP_TIMEOUT = 30000;\n\nconst RenderingStates = {\n INITIAL: 0,\n RUNNING: 1,\n PAUSED: 2,\n FINISHED: 3,\n};\n\n/**\n * Controls rendering of the views for pages and thumbnails.\n */\nclass PDFRenderingQueue {\n constructor() {\n this.pdfViewer = null;\n this.pdfThumbnailViewer = null;\n this.onIdle = null;\n this.highestPriorityPage = null;\n this.idleTimeout = null;\n this.printing = false;\n this.isThumbnailViewEnabled = false;\n }\n\n /**\n * @param {PDFViewer} pdfViewer\n */\n setViewer(pdfViewer) {\n this.pdfViewer = pdfViewer;\n }\n\n /**\n * @param {PDFThumbnailViewer} pdfThumbnailViewer\n */\n setThumbnailViewer(pdfThumbnailViewer) {\n this.pdfThumbnailViewer = pdfThumbnailViewer;\n }\n\n /**\n * @param {IRenderableView} view\n * @returns {boolean}\n */\n isHighestPriority(view) {\n return this.highestPriorityPage === view.renderingId;\n }\n\n /**\n * @param {Object} currentlyVisiblePages\n */\n renderHighestPriority(currentlyVisiblePages) {\n if (this.idleTimeout) {\n clearTimeout(this.idleTimeout);\n this.idleTimeout = null;\n }\n\n // Pages have a higher priority than thumbnails, so check them first.\n if (this.pdfViewer.forceRendering(currentlyVisiblePages)) {\n return;\n }\n // No pages needed rendering, so check thumbnails.\n if (this.pdfThumbnailViewer && this.isThumbnailViewEnabled) {\n if (this.pdfThumbnailViewer.forceRendering()) {\n return;\n }\n }\n\n if (this.printing) {\n // If printing is currently ongoing do not reschedule cleanup.\n return;\n }\n\n if (this.onIdle) {\n this.idleTimeout = setTimeout(this.onIdle.bind(this), CLEANUP_TIMEOUT);\n }\n }\n\n /**\n * @param {Object} visible\n * @param {Array} views\n * @param {boolean} scrolledDown\n */\n getHighestPriority(visible, views, scrolledDown) {\n /**\n * The state has changed. Figure out which page has the highest priority to\n * render next (if any).\n *\n * Priority:\n * 1. visible pages\n * 2. if last scrolled down, the page after the visible pages, or\n * if last scrolled up, the page before the visible pages\n */\n var visibleViews = visible.views;\n\n var numVisible = visibleViews.length;\n if (numVisible === 0) {\n return false;\n }\n for (var i = 0; i < numVisible; ++i) {\n var view = visibleViews[i].view;\n if (!this.isViewFinished(view)) {\n return view;\n }\n }\n\n // All the visible views have rendered; try to render next/previous pages.\n if (scrolledDown) {\n var nextPageIndex = visible.last.id;\n // IDs start at 1, so no need to add 1.\n if (views[nextPageIndex] && !this.isViewFinished(views[nextPageIndex])) {\n return views[nextPageIndex];\n }\n } else {\n var previousPageIndex = visible.first.id - 2;\n if (views[previousPageIndex] &&\n !this.isViewFinished(views[previousPageIndex])) {\n return views[previousPageIndex];\n }\n }\n // Everything that needs to be rendered has been.\n return null;\n }\n\n /**\n * @param {IRenderableView} view\n * @returns {boolean}\n */\n isViewFinished(view) {\n return view.renderingState === RenderingStates.FINISHED;\n }\n\n /**\n * Render a page or thumbnail view. This calls the appropriate function\n * based on the views state. If the view is already rendered it will return\n * `false`.\n *\n * @param {IRenderableView} view\n */\n renderView(view) {\n switch (view.renderingState) {\n case RenderingStates.FINISHED:\n return false;\n case RenderingStates.PAUSED:\n this.highestPriorityPage = view.renderingId;\n view.resume();\n break;\n case RenderingStates.RUNNING:\n this.highestPriorityPage = view.renderingId;\n break;\n case RenderingStates.INITIAL:\n this.highestPriorityPage = view.renderingId;\n var continueRendering = () => {\n this.renderHighestPriority();\n };\n view.draw().then(continueRendering, continueRendering);\n break;\n }\n return true;\n }\n}\n\nexport {\n RenderingStates,\n PDFRenderingQueue,\n};\n\n\n\n// WEBPACK FOOTER //\n// web/pdf_rendering_queue.js","/* Copyright 2012 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/* globals PDFBug, Stats */\n\nimport {\n animationStarted, DEFAULT_SCALE_VALUE, getPDFFileNameFromURL, isValidRotation,\n MAX_SCALE, MIN_SCALE, noContextMenuHandler, normalizeWheelEventDelta,\n parseQueryString, PresentationModeState, ProgressBar, RendererType\n} from './ui_utils';\nimport {\n build, createBlob, getDocument, getFilenameFromUrl, InvalidPDFException,\n MissingPDFException, OPS, PDFJS, shadow, UnexpectedResponseException,\n UNSUPPORTED_FEATURES, version\n} from 'pdfjs-lib';\nimport { CursorTool, PDFCursorTools } from './pdf_cursor_tools';\nimport { PDFRenderingQueue, RenderingStates } from './pdf_rendering_queue';\nimport { PDFSidebar, SidebarView } from './pdf_sidebar';\nimport { getGlobalEventBus } from './dom_events';\nimport { OverlayManager } from './overlay_manager';\nimport { PasswordPrompt } from './password_prompt';\nimport { PDFAttachmentViewer } from './pdf_attachment_viewer';\nimport { PDFDocumentProperties } from './pdf_document_properties';\nimport { PDFFindBar } from './pdf_find_bar';\nimport { PDFFindController } from './pdf_find_controller';\nimport { PDFHistory } from './pdf_history';\nimport { PDFLinkService } from './pdf_link_service';\nimport { PDFOutlineViewer } from './pdf_outline_viewer';\nimport { PDFPresentationMode } from './pdf_presentation_mode';\nimport { PDFThumbnailViewer } from './pdf_thumbnail_viewer';\nimport { PDFViewer } from './pdf_viewer';\nimport { SecondaryToolbar } from './secondary_toolbar';\nimport { Toolbar } from './toolbar';\nimport { ViewHistory } from './view_history';\n\nconst DEFAULT_SCALE_DELTA = 1.1;\nconst DISABLE_AUTO_FETCH_LOADING_BAR_TIMEOUT = 5000;\n\nfunction configure(PDFJS) {\n PDFJS.imageResourcesPath = './images/';\n if (typeof PDFJSDev !== 'undefined' &&\n PDFJSDev.test('FIREFOX || MOZCENTRAL || GENERIC || CHROME')) {\n PDFJS.workerSrc = '../build/pdf.worker.js';\n }\n if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('PRODUCTION')) {\n PDFJS.cMapUrl = '../external/bcmaps/';\n PDFJS.cMapPacked = true;\n PDFJS.workerSrc = '../src/worker_loader.js';\n PDFJS.pdfjsNext = true;\n } else {\n PDFJS.cMapUrl = '../web/cmaps/';\n PDFJS.cMapPacked = true;\n }\n}\n\nconst DefaultExternalServices = {\n updateFindControlState(data) {},\n initPassiveLoading(callbacks) {},\n fallback(data, callback) {},\n reportTelemetry(data) {},\n createDownloadManager() {\n throw new Error('Not implemented: createDownloadManager');\n },\n createPreferences() {\n throw new Error('Not implemented: createPreferences');\n },\n createL10n() {\n throw new Error('Not implemented: createL10n');\n },\n supportsIntegratedFind: false,\n supportsDocumentFonts: true,\n supportsDocumentColors: true,\n supportedMouseWheelZoomModifierKeys: {\n ctrlKey: true,\n metaKey: true,\n },\n};\n\nlet PDFViewerApplication = {\n initialBookmark: document.location.hash.substring(1),\n initialized: false,\n fellback: false,\n appConfig: null,\n pdfDocument: null,\n pdfLoadingTask: null,\n printService: null,\n /** @type {PDFViewer} */\n pdfViewer: null,\n /** @type {PDFThumbnailViewer} */\n pdfThumbnailViewer: null,\n /** @type {PDFRenderingQueue} */\n pdfRenderingQueue: null,\n /** @type {PDFPresentationMode} */\n pdfPresentationMode: null,\n /** @type {PDFDocumentProperties} */\n pdfDocumentProperties: null,\n /** @type {PDFLinkService} */\n pdfLinkService: null,\n /** @type {PDFHistory} */\n pdfHistory: null,\n /** @type {PDFSidebar} */\n pdfSidebar: null,\n /** @type {PDFOutlineViewer} */\n pdfOutlineViewer: null,\n /** @type {PDFAttachmentViewer} */\n pdfAttachmentViewer: null,\n /** @type {PDFCursorTools} */\n pdfCursorTools: null,\n /** @type {ViewHistory} */\n store: null,\n /** @type {DownloadManager} */\n downloadManager: null,\n /** @type {OverlayManager} */\n overlayManager: null,\n /** @type {Preferences} */\n preferences: null,\n /** @type {Toolbar} */\n toolbar: null,\n /** @type {SecondaryToolbar} */\n secondaryToolbar: null,\n /** @type {EventBus} */\n eventBus: null,\n /** @type {IL10n} */\n l10n: null,\n isInitialViewSet: false,\n downloadComplete: false,\n viewerPrefs: {\n sidebarViewOnLoad: SidebarView.NONE,\n pdfBugEnabled: false,\n showPreviousViewOnLoad: true,\n defaultZoomValue: '',\n disablePageMode: false,\n disablePageLabels: false,\n renderer: 'canvas',\n enhanceTextSelection: false,\n renderInteractiveForms: false,\n enablePrintAutoRotate: false,\n },\n isViewerEmbedded: (window.parent !== window),\n url: '',\n baseUrl: '',\n externalServices: DefaultExternalServices,\n _boundEvents: {},\n\n // Called once when the document is loaded.\n initialize(appConfig) {\n this.preferences = this.externalServices.createPreferences();\n\n configure(PDFJS);\n this.appConfig = appConfig;\n\n return this._readPreferences().then(() => {\n return this._initializeL10n();\n }).then(() => {\n return this._initializeViewerComponents();\n }).then(() => {\n // Bind the various event handlers *after* the viewer has been\n // initialized, to prevent errors if an event arrives too soon.\n this.bindEvents();\n this.bindWindowEvents();\n\n // We can start UI localization now.\n let appContainer = appConfig.appContainer || document.documentElement;\n this.l10n.translate(appContainer).then(() => {\n // Dispatch the 'localized' event on the `eventBus` once the viewer\n // has been fully initialized and translated.\n this.eventBus.dispatch('localized');\n });\n\n if (this.isViewerEmbedded && !PDFJS.isExternalLinkTargetSet()) {\n // Prevent external links from \"replacing\" the viewer,\n // when it's embedded in e.g. an iframe or an object.\n PDFJS.externalLinkTarget = PDFJS.LinkTarget.TOP;\n }\n\n this.initialized = true;\n });\n },\n\n /**\n * @private\n */\n _readPreferences() {\n let { preferences, viewerPrefs, } = this;\n\n return Promise.all([\n preferences.get('enableWebGL').then(function resolved(value) {\n PDFJS.disableWebGL = !value;\n }),\n preferences.get('sidebarViewOnLoad').then(function resolved(value) {\n viewerPrefs['sidebarViewOnLoad'] = value;\n }),\n preferences.get('pdfBugEnabled').then(function resolved(value) {\n viewerPrefs['pdfBugEnabled'] = value;\n }),\n preferences.get('showPreviousViewOnLoad').then(function resolved(value) {\n viewerPrefs['showPreviousViewOnLoad'] = value;\n }),\n preferences.get('defaultZoomValue').then(function resolved(value) {\n viewerPrefs['defaultZoomValue'] = value;\n }),\n preferences.get('enhanceTextSelection').then(function resolved(value) {\n viewerPrefs['enhanceTextSelection'] = value;\n }),\n preferences.get('disableTextLayer').then(function resolved(value) {\n if (PDFJS.disableTextLayer === true) {\n return;\n }\n PDFJS.disableTextLayer = value;\n }),\n preferences.get('disableRange').then(function resolved(value) {\n if (PDFJS.disableRange === true) {\n return;\n }\n PDFJS.disableRange = value;\n }),\n preferences.get('disableStream').then(function resolved(value) {\n if (PDFJS.disableStream === true) {\n return;\n }\n PDFJS.disableStream = value;\n }),\n preferences.get('disableAutoFetch').then(function resolved(value) {\n PDFJS.disableAutoFetch = value;\n }),\n preferences.get('disableFontFace').then(function resolved(value) {\n if (PDFJS.disableFontFace === true) {\n return;\n }\n PDFJS.disableFontFace = value;\n }),\n preferences.get('useOnlyCssZoom').then(function resolved(value) {\n PDFJS.useOnlyCssZoom = value;\n }),\n preferences.get('externalLinkTarget').then(function resolved(value) {\n if (PDFJS.isExternalLinkTargetSet()) {\n return;\n }\n PDFJS.externalLinkTarget = value;\n }),\n preferences.get('renderer').then(function resolved(value) {\n viewerPrefs['renderer'] = value;\n }),\n preferences.get('renderInteractiveForms').then(function resolved(value) {\n viewerPrefs['renderInteractiveForms'] = value;\n }),\n preferences.get('disablePageMode').then(function resolved(value) {\n viewerPrefs['disablePageMode'] = value;\n }),\n preferences.get('disablePageLabels').then(function resolved(value) {\n viewerPrefs['disablePageLabels'] = value;\n }),\n preferences.get('enablePrintAutoRotate').then(function resolved(value) {\n viewerPrefs['enablePrintAutoRotate'] = value;\n }),\n ]).catch(function(reason) { });\n },\n\n _initializeL10n() {\n // Locale can be changed only when special debugging flags is present in\n // the hash section of the URL, or development version of viewer is used.\n // It is not possible to change locale for Firefox extension builds.\n if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('PRODUCTION') ||\n (!PDFJSDev.test('FIREFOX || MOZCENTRAL') &&\n this.viewerPrefs['pdfBugEnabled'])) {\n let hash = document.location.hash.substring(1);\n let hashParams = parseQueryString(hash);\n if ('locale' in hashParams) {\n PDFJS.locale = hashParams['locale'];\n }\n }\n this.l10n = this.externalServices.createL10n();\n return this.l10n.getDirection().then((dir) => {\n document.getElementsByTagName('html')[0].dir = dir;\n });\n },\n\n /**\n * @private\n */\n _initializeViewerComponents() {\n let appConfig = this.appConfig;\n\n return new Promise((resolve, reject) => {\n this.overlayManager = new OverlayManager();\n\n let eventBus = appConfig.eventBus || getGlobalEventBus();\n this.eventBus = eventBus;\n\n let pdfRenderingQueue = new PDFRenderingQueue();\n pdfRenderingQueue.onIdle = this.cleanup.bind(this);\n this.pdfRenderingQueue = pdfRenderingQueue;\n\n let pdfLinkService = new PDFLinkService({\n eventBus,\n });\n this.pdfLinkService = pdfLinkService;\n\n let downloadManager = this.externalServices.createDownloadManager();\n this.downloadManager = downloadManager;\n\n let container = appConfig.mainContainer;\n let viewer = appConfig.viewerContainer;\n this.pdfViewer = new PDFViewer({\n container,\n viewer,\n eventBus,\n renderingQueue: pdfRenderingQueue,\n linkService: pdfLinkService,\n downloadManager,\n renderer: this.viewerPrefs['renderer'],\n l10n: this.l10n,\n enhanceTextSelection: this.viewerPrefs['enhanceTextSelection'],\n renderInteractiveForms: this.viewerPrefs['renderInteractiveForms'],\n enablePrintAutoRotate: this.viewerPrefs['enablePrintAutoRotate'],\n });\n pdfRenderingQueue.setViewer(this.pdfViewer);\n pdfLinkService.setViewer(this.pdfViewer);\n\n let thumbnailContainer = appConfig.sidebar.thumbnailView;\n this.pdfThumbnailViewer = new PDFThumbnailViewer({\n container: thumbnailContainer,\n renderingQueue: pdfRenderingQueue,\n linkService: pdfLinkService,\n l10n: this.l10n,\n });\n pdfRenderingQueue.setThumbnailViewer(this.pdfThumbnailViewer);\n\n this.pdfHistory = new PDFHistory({\n linkService: pdfLinkService,\n eventBus,\n });\n pdfLinkService.setHistory(this.pdfHistory);\n\n this.findController = new PDFFindController({\n pdfViewer: this.pdfViewer,\n });\n this.findController.onUpdateResultsCount = (matchCount) => {\n if (this.supportsIntegratedFind) {\n return;\n }\n this.findBar.updateResultsCount(matchCount);\n };\n this.findController.onUpdateState = (state, previous, matchCount) => {\n if (this.supportsIntegratedFind) {\n this.externalServices.updateFindControlState({\n result: state,\n findPrevious: previous,\n });\n } else {\n this.findBar.updateUIState(state, previous, matchCount);\n }\n };\n\n this.pdfViewer.setFindController(this.findController);\n\n // TODO: improve `PDFFindBar` constructor parameter passing\n let findBarConfig = Object.create(appConfig.findBar);\n findBarConfig.findController = this.findController;\n findBarConfig.eventBus = eventBus;\n this.findBar = new PDFFindBar(findBarConfig, this.l10n);\n\n this.pdfDocumentProperties =\n new PDFDocumentProperties(appConfig.documentProperties,\n this.overlayManager, this.l10n);\n\n this.pdfCursorTools = new PDFCursorTools({\n container,\n eventBus,\n preferences: this.preferences,\n });\n\n this.toolbar = new Toolbar(appConfig.toolbar, container, eventBus,\n this.l10n);\n\n this.secondaryToolbar =\n new SecondaryToolbar(appConfig.secondaryToolbar, container, eventBus);\n\n if (this.supportsFullscreen) {\n this.pdfPresentationMode = new PDFPresentationMode({\n container,\n viewer,\n pdfViewer: this.pdfViewer,\n eventBus,\n contextMenuItems: appConfig.fullscreen,\n });\n }\n\n this.passwordPrompt = new PasswordPrompt(appConfig.passwordOverlay,\n this.overlayManager, this.l10n);\n\n this.pdfOutlineViewer = new PDFOutlineViewer({\n container: appConfig.sidebar.outlineView,\n eventBus,\n linkService: pdfLinkService,\n });\n\n this.pdfAttachmentViewer = new PDFAttachmentViewer({\n container: appConfig.sidebar.attachmentsView,\n eventBus,\n downloadManager,\n });\n\n // TODO: improve `PDFSidebar` constructor parameter passing\n let sidebarConfig = Object.create(appConfig.sidebar);\n sidebarConfig.pdfViewer = this.pdfViewer;\n sidebarConfig.pdfThumbnailViewer = this.pdfThumbnailViewer;\n sidebarConfig.pdfOutlineViewer = this.pdfOutlineViewer;\n sidebarConfig.eventBus = eventBus;\n this.pdfSidebar = new PDFSidebar(sidebarConfig, this.l10n);\n this.pdfSidebar.onToggled = this.forceRendering.bind(this);\n\n resolve(undefined);\n });\n },\n\n run(config) {\n this.initialize(config).then(webViewerInitialized);\n },\n\n zoomIn(ticks) {\n let newScale = this.pdfViewer.currentScale;\n do {\n newScale = (newScale * DEFAULT_SCALE_DELTA).toFixed(2);\n newScale = Math.ceil(newScale * 10) / 10;\n newScale = Math.min(MAX_SCALE, newScale);\n } while (--ticks > 0 && newScale < MAX_SCALE);\n this.pdfViewer.currentScaleValue = newScale;\n },\n\n zoomOut(ticks) {\n let newScale = this.pdfViewer.currentScale;\n do {\n newScale = (newScale / DEFAULT_SCALE_DELTA).toFixed(2);\n newScale = Math.floor(newScale * 10) / 10;\n newScale = Math.max(MIN_SCALE, newScale);\n } while (--ticks > 0 && newScale > MIN_SCALE);\n this.pdfViewer.currentScaleValue = newScale;\n },\n\n get pagesCount() {\n return this.pdfDocument ? this.pdfDocument.numPages : 0;\n },\n\n get pageRotation() {\n return this.pdfViewer.pagesRotation;\n },\n\n set page(val) {\n this.pdfViewer.currentPageNumber = val;\n },\n\n get page() {\n return this.pdfViewer.currentPageNumber;\n },\n\n get printing() {\n return !!this.printService;\n },\n\n get supportsPrinting() {\n return PDFPrintServiceFactory.instance.supportsPrinting;\n },\n\n get supportsFullscreen() {\n let support;\n if (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('MOZCENTRAL')) {\n support = document.fullscreenEnabled === true ||\n document.mozFullScreenEnabled === true;\n } else {\n let doc = document.documentElement;\n support = !!(doc.requestFullscreen || doc.mozRequestFullScreen ||\n doc.webkitRequestFullScreen || doc.msRequestFullscreen);\n\n if (document.fullscreenEnabled === false ||\n document.mozFullScreenEnabled === false ||\n document.webkitFullscreenEnabled === false ||\n document.msFullscreenEnabled === false) {\n support = false;\n }\n }\n if (support && PDFJS.disableFullscreen === true) {\n support = false;\n }\n\n return shadow(this, 'supportsFullscreen', support);\n },\n\n get supportsIntegratedFind() {\n return this.externalServices.supportsIntegratedFind;\n },\n\n get supportsDocumentFonts() {\n return this.externalServices.supportsDocumentFonts;\n },\n\n get supportsDocumentColors() {\n return this.externalServices.supportsDocumentColors;\n },\n\n get loadingBar() {\n let bar = new ProgressBar('#loadingBar');\n return shadow(this, 'loadingBar', bar);\n },\n\n get supportedMouseWheelZoomModifierKeys() {\n return this.externalServices.supportedMouseWheelZoomModifierKeys;\n },\n\n initPassiveLoading() {\n if (typeof PDFJSDev === 'undefined' ||\n !PDFJSDev.test('FIREFOX || MOZCENTRAL || CHROME')) {\n throw new Error('Not implemented: initPassiveLoading');\n }\n this.externalServices.initPassiveLoading({\n onOpenWithTransport(url, length, transport) {\n PDFViewerApplication.open(url, { range: transport, });\n\n if (length) {\n PDFViewerApplication.pdfDocumentProperties.setFileSize(length);\n }\n },\n onOpenWithData(data) {\n PDFViewerApplication.open(data);\n },\n onOpenWithURL(url, length, originalURL) {\n let file = url, args = null;\n if (length !== undefined) {\n args = { length, };\n }\n if (originalURL !== undefined) {\n file = { file: url, originalURL, };\n }\n PDFViewerApplication.open(file, args);\n },\n onError(err) {\n PDFViewerApplication.l10n.get('loading_error', null,\n 'An error occurred while loading the PDF.').then((msg) => {\n PDFViewerApplication.error(msg, err);\n });\n },\n onProgress(loaded, total) {\n PDFViewerApplication.progress(loaded / total);\n },\n });\n },\n\n setTitleUsingUrl(url) {\n this.url = url;\n this.baseUrl = url.split('#')[0];\n let title = getPDFFileNameFromURL(url, '');\n if (!title) {\n try {\n title = decodeURIComponent(getFilenameFromUrl(url)) || url;\n } catch (ex) {\n // decodeURIComponent may throw URIError,\n // fall back to using the unprocessed url in that case\n title = url;\n }\n }\n this.setTitle(title);\n },\n\n setTitle(title) {\n if (this.isViewerEmbedded) {\n // Embedded PDF viewers should not be changing their parent page's title.\n return;\n }\n document.title = title;\n },\n\n /**\n * Closes opened PDF document.\n * @returns {Promise} - Returns the promise, which is resolved when all\n * destruction is completed.\n */\n close() {\n let errorWrapper = this.appConfig.errorWrapper.container;\n errorWrapper.setAttribute('hidden', 'true');\n\n if (!this.pdfLoadingTask) {\n return Promise.resolve();\n }\n\n let promise = this.pdfLoadingTask.destroy();\n this.pdfLoadingTask = null;\n\n if (this.pdfDocument) {\n this.pdfDocument = null;\n\n this.pdfThumbnailViewer.setDocument(null);\n this.pdfViewer.setDocument(null);\n this.pdfLinkService.setDocument(null, null);\n this.pdfDocumentProperties.setDocument(null, null);\n }\n this.store = null;\n this.isInitialViewSet = false;\n this.downloadComplete = false;\n\n this.pdfSidebar.reset();\n this.pdfOutlineViewer.reset();\n this.pdfAttachmentViewer.reset();\n\n this.findController.reset();\n this.findBar.reset();\n this.toolbar.reset();\n this.secondaryToolbar.reset();\n\n if (typeof PDFBug !== 'undefined') {\n PDFBug.cleanup();\n }\n return promise;\n },\n\n /**\n * Opens PDF document specified by URL or array with additional arguments.\n * @param {string|TypedArray|ArrayBuffer} file - PDF location or binary data.\n * @param {Object} args - (optional) Additional arguments for the getDocument\n * call, e.g. HTTP headers ('httpHeaders') or\n * alternative data transport ('range').\n * @returns {Promise} - Returns the promise, which is resolved when document\n * is opened.\n */\n open(file, args) {\n if ((typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC')) &&\n (arguments.length > 2 || typeof args === 'number')) {\n return Promise.reject(\n new Error('Call of open() with obsolete signature.'));\n }\n if (this.pdfLoadingTask) {\n // We need to destroy already opened document.\n return this.close().then(() => {\n // Reload the preferences if a document was previously opened.\n this.preferences.reload();\n // ... and repeat the open() call.\n return this.open(file, args);\n });\n }\n\n let parameters = Object.create(null);\n if (typeof file === 'string') { // URL\n this.setTitleUsingUrl(file);\n parameters.url = file;\n } else if (file && 'byteLength' in file) { // ArrayBuffer\n parameters.data = file;\n } else if (file.url && file.originalUrl) {\n this.setTitleUsingUrl(file.originalUrl);\n parameters.url = file.url;\n }\n if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('PRODUCTION')) {\n parameters.docBaseUrl = document.URL.split('#')[0];\n } else if (typeof PDFJSDev !== 'undefined' &&\n PDFJSDev.test('FIREFOX || MOZCENTRAL || CHROME')) {\n parameters.docBaseUrl = this.baseUrl;\n }\n\n if (args) {\n for (let prop in args) {\n if ((typeof PDFJSDev === 'undefined' || !PDFJSDev.test('PDFJS_NEXT')) &&\n !PDFJS.pdfjsNext && prop === 'scale') {\n console.error('Call of open() with obsolete \"scale\" argument, ' +\n 'please use the \"defaultZoomValue\" preference instead.');\n continue;\n } else if (prop === 'length') {\n this.pdfDocumentProperties.setFileSize(args[prop]);\n }\n parameters[prop] = args[prop];\n }\n }\n\n let loadingTask = getDocument(parameters);\n this.pdfLoadingTask = loadingTask;\n\n loadingTask.onPassword = (updateCallback, reason) => {\n this.passwordPrompt.setUpdateCallback(updateCallback, reason);\n this.passwordPrompt.open();\n };\n\n loadingTask.onProgress = ({ loaded, total, }) => {\n this.progress(loaded / total);\n };\n\n // Listen for unsupported features to trigger the fallback UI.\n loadingTask.onUnsupportedFeature = this.fallback.bind(this);\n\n return loadingTask.promise.then((pdfDocument) => {\n this.load(pdfDocument);\n }, (exception) => {\n let message = exception && exception.message;\n let loadingErrorMessage;\n if (exception instanceof InvalidPDFException) {\n // change error message also for other builds\n loadingErrorMessage = this.l10n.get('invalid_file_error', null,\n 'Invalid or corrupted PDF file.');\n } else if (exception instanceof MissingPDFException) {\n // special message for missing PDF's\n loadingErrorMessage = this.l10n.get('missing_file_error', null,\n 'Missing PDF file.');\n } else if (exception instanceof UnexpectedResponseException) {\n loadingErrorMessage = this.l10n.get('unexpected_response_error', null,\n 'Unexpected server response.');\n } else {\n loadingErrorMessage = this.l10n.get('loading_error', null,\n 'An error occurred while loading the PDF.');\n }\n\n return loadingErrorMessage.then((msg) => {\n this.error(msg, { message, });\n throw new Error(msg);\n });\n });\n },\n\n download() {\n function downloadByUrl() {\n downloadManager.downloadUrl(url, filename);\n }\n\n let url = this.baseUrl;\n // Use this.url instead of this.baseUrl to perform filename detection based\n // on the reference fragment as ultimate fallback if needed.\n let filename = getPDFFileNameFromURL(this.url);\n let downloadManager = this.downloadManager;\n downloadManager.onerror = (err) => {\n // This error won't really be helpful because it's likely the\n // fallback won't work either (or is already open).\n this.error(`PDF failed to download: ${err}`);\n };\n\n // When the PDF document isn't ready, or the PDF file is still downloading,\n // simply download using the URL.\n if (!this.pdfDocument || !this.downloadComplete) {\n downloadByUrl();\n return;\n }\n\n this.pdfDocument.getData().then(function(data) {\n let blob = createBlob(data, 'application/pdf');\n downloadManager.download(blob, url, filename);\n }).catch(downloadByUrl); // Error occurred, try downloading with the URL.\n },\n\n fallback(featureId) {\n if (typeof PDFJSDev !== 'undefined' &&\n PDFJSDev.test('FIREFOX || MOZCENTRAL')) {\n // Only trigger the fallback once so we don't spam the user with messages\n // for one PDF.\n if (this.fellback) {\n return;\n }\n this.fellback = true;\n this.externalServices.fallback({\n featureId,\n url: this.baseUrl,\n }, function response(download) {\n if (!download) {\n return;\n }\n PDFViewerApplication.download();\n });\n }\n },\n\n /**\n * Show the error box.\n * @param {String} message A message that is human readable.\n * @param {Object} moreInfo (optional) Further information about the error\n * that is more technical. Should have a 'message'\n * and optionally a 'stack' property.\n */\n error(message, moreInfo) {\n let moreInfoText = [this.l10n.get('error_version_info',\n { version: version || '?', build: build || '?', },\n 'PDF.js v{{version}} (build: {{build}})')];\n if (moreInfo) {\n moreInfoText.push(\n this.l10n.get('error_message', { message: moreInfo.message, },\n 'Message: {{message}}'));\n if (moreInfo.stack) {\n moreInfoText.push(\n this.l10n.get('error_stack', { stack: moreInfo.stack, },\n 'Stack: {{stack}}'));\n } else {\n if (moreInfo.filename) {\n moreInfoText.push(\n this.l10n.get('error_file', { file: moreInfo.filename, },\n 'File: {{file}}'));\n }\n if (moreInfo.lineNumber) {\n moreInfoText.push(\n this.l10n.get('error_line', { line: moreInfo.lineNumber, },\n 'Line: {{line}}'));\n }\n }\n }\n\n if (typeof PDFJSDev === 'undefined' ||\n !PDFJSDev.test('FIREFOX || MOZCENTRAL')) {\n let errorWrapperConfig = this.appConfig.errorWrapper;\n let errorWrapper = errorWrapperConfig.container;\n errorWrapper.removeAttribute('hidden');\n\n let errorMessage = errorWrapperConfig.errorMessage;\n errorMessage.textContent = message;\n\n let closeButton = errorWrapperConfig.closeButton;\n closeButton.onclick = function() {\n errorWrapper.setAttribute('hidden', 'true');\n };\n\n let errorMoreInfo = errorWrapperConfig.errorMoreInfo;\n let moreInfoButton = errorWrapperConfig.moreInfoButton;\n let lessInfoButton = errorWrapperConfig.lessInfoButton;\n moreInfoButton.onclick = function() {\n errorMoreInfo.removeAttribute('hidden');\n moreInfoButton.setAttribute('hidden', 'true');\n lessInfoButton.removeAttribute('hidden');\n errorMoreInfo.style.height = errorMoreInfo.scrollHeight + 'px';\n };\n lessInfoButton.onclick = function() {\n errorMoreInfo.setAttribute('hidden', 'true');\n moreInfoButton.removeAttribute('hidden');\n lessInfoButton.setAttribute('hidden', 'true');\n };\n moreInfoButton.oncontextmenu = noContextMenuHandler;\n lessInfoButton.oncontextmenu = noContextMenuHandler;\n closeButton.oncontextmenu = noContextMenuHandler;\n moreInfoButton.removeAttribute('hidden');\n lessInfoButton.setAttribute('hidden', 'true');\n Promise.all(moreInfoText).then((parts) => {\n errorMoreInfo.value = parts.join('\\n');\n });\n } else {\n Promise.all(moreInfoText).then((parts) => {\n console.error(message + '\\n' + parts.join('\\n'));\n });\n this.fallback();\n }\n },\n\n progress(level) {\n if (this.downloadComplete) {\n // Don't accidentally show the loading bar again when the entire file has\n // already been fetched (only an issue when disableAutoFetch is enabled).\n return;\n }\n let percent = Math.round(level * 100);\n // When we transition from full request to range requests, it's possible\n // that we discard some of the loaded data. This can cause the loading\n // bar to move backwards. So prevent this by only updating the bar if it\n // increases.\n if (percent > this.loadingBar.percent || isNaN(percent)) {\n this.loadingBar.percent = percent;\n\n // When disableAutoFetch is enabled, it's not uncommon for the entire file\n // to never be fetched (depends on e.g. the file structure). In this case\n // the loading bar will not be completely filled, nor will it be hidden.\n // To prevent displaying a partially filled loading bar permanently, we\n // hide it when no data has been loaded during a certain amount of time.\n if (PDFJS.disableAutoFetch && percent) {\n if (this.disableAutoFetchLoadingBarTimeout) {\n clearTimeout(this.disableAutoFetchLoadingBarTimeout);\n this.disableAutoFetchLoadingBarTimeout = null;\n }\n this.loadingBar.show();\n\n this.disableAutoFetchLoadingBarTimeout = setTimeout(() => {\n this.loadingBar.hide();\n this.disableAutoFetchLoadingBarTimeout = null;\n }, DISABLE_AUTO_FETCH_LOADING_BAR_TIMEOUT);\n }\n }\n },\n\n load(pdfDocument) {\n this.pdfDocument = pdfDocument;\n\n pdfDocument.getDownloadInfo().then(() => {\n this.downloadComplete = true;\n this.loadingBar.hide();\n\n firstPagePromise.then(() => {\n this.eventBus.dispatch('documentload', { source: this, });\n });\n });\n\n // Since the `setInitialView` call below depends on this being resolved,\n // fetch it early to avoid delaying initial rendering of the PDF document.\n let pageModePromise = pdfDocument.getPageMode().catch(\n function() { /* Avoid breaking initial rendering; ignoring errors. */ });\n\n this.toolbar.setPagesCount(pdfDocument.numPages, false);\n this.secondaryToolbar.setPagesCount(pdfDocument.numPages);\n\n let id = this.documentFingerprint = pdfDocument.fingerprint;\n let store = this.store = new ViewHistory(id);\n\n let baseDocumentUrl;\n if (typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC')) {\n baseDocumentUrl = null;\n } else if (PDFJSDev.test('FIREFOX || MOZCENTRAL')) {\n baseDocumentUrl = this.baseUrl;\n } else if (PDFJSDev.test('CHROME')) {\n baseDocumentUrl = location.href.split('#')[0];\n }\n this.pdfLinkService.setDocument(pdfDocument, baseDocumentUrl);\n this.pdfDocumentProperties.setDocument(pdfDocument, this.url);\n\n let pdfViewer = this.pdfViewer;\n pdfViewer.setDocument(pdfDocument);\n let firstPagePromise = pdfViewer.firstPagePromise;\n let pagesPromise = pdfViewer.pagesPromise;\n let onePageRendered = pdfViewer.onePageRendered;\n\n let pdfThumbnailViewer = this.pdfThumbnailViewer;\n pdfThumbnailViewer.setDocument(pdfDocument);\n\n firstPagePromise.then((pdfPage) => {\n this.loadingBar.setWidth(this.appConfig.viewerContainer);\n\n if (!PDFJS.disableHistory && !this.isViewerEmbedded) {\n // The browsing history is only enabled when the viewer is standalone,\n // i.e. not when it is embedded in a web page.\n let resetHistory = !this.viewerPrefs['showPreviousViewOnLoad'];\n this.pdfHistory.initialize(id, resetHistory);\n\n if (this.pdfHistory.initialBookmark) {\n this.initialBookmark = this.pdfHistory.initialBookmark;\n\n this.initialRotation = this.pdfHistory.initialRotation;\n }\n }\n\n let initialParams = {\n bookmark: null,\n hash: null,\n };\n let storePromise = store.getMultiple({\n exists: false,\n page: '1',\n zoom: DEFAULT_SCALE_VALUE,\n scrollLeft: '0',\n scrollTop: '0',\n rotation: null,\n sidebarView: SidebarView.NONE,\n }).catch(() => { /* Unable to read from storage; ignoring errors. */ });\n\n Promise.all([storePromise, pageModePromise]).then(\n ([values = {}, pageMode]) => {\n // Initialize the default values, from user preferences.\n let hash = this.viewerPrefs['defaultZoomValue'] ?\n ('zoom=' + this.viewerPrefs['defaultZoomValue']) : null;\n let rotation = null;\n let sidebarView = this.viewerPrefs['sidebarViewOnLoad'];\n\n if (values.exists && this.viewerPrefs['showPreviousViewOnLoad']) {\n hash = 'page=' + values.page +\n '&zoom=' + (this.viewerPrefs['defaultZoomValue'] || values.zoom) +\n ',' + values.scrollLeft + ',' + values.scrollTop;\n rotation = parseInt(values.rotation, 10);\n sidebarView = sidebarView || (values.sidebarView | 0);\n }\n if (pageMode && !this.viewerPrefs['disablePageMode']) {\n // Always let the user preference/history take precedence.\n sidebarView = sidebarView || apiPageModeToSidebarView(pageMode);\n }\n return {\n hash,\n rotation,\n sidebarView,\n };\n }).then(({ hash, rotation, sidebarView, }) => {\n initialParams.bookmark = this.initialBookmark;\n initialParams.hash = hash;\n\n this.setInitialView(hash, { rotation, sidebarView, });\n\n // Make all navigation keys work on document load,\n // unless the viewer is embedded in a web page.\n if (!this.isViewerEmbedded) {\n pdfViewer.focus();\n }\n return pagesPromise;\n }).then(() => {\n // For documents with different page sizes, once all pages are resolved,\n // ensure that the correct location becomes visible on load.\n if (!initialParams.bookmark && !initialParams.hash) {\n return;\n }\n if (pdfViewer.hasEqualPageSizes) {\n return;\n }\n this.initialBookmark = initialParams.bookmark;\n\n pdfViewer.currentScaleValue = pdfViewer.currentScaleValue;\n this.setInitialView(initialParams.hash);\n }).then(function() {\n // At this point, rendering of the initial page(s) should always have\n // started (and may even have completed).\n // To prevent any future issues, e.g. the document being completely\n // blank on load, always trigger rendering here.\n pdfViewer.update();\n });\n });\n\n pdfDocument.getPageLabels().then((labels) => {\n if (!labels || this.viewerPrefs['disablePageLabels']) {\n return;\n }\n let i = 0, numLabels = labels.length;\n if (numLabels !== this.pagesCount) {\n console.error('The number of Page Labels does not match ' +\n 'the number of pages in the document.');\n return;\n }\n // Ignore page labels that correspond to standard page numbering.\n while (i < numLabels && labels[i] === (i + 1).toString()) {\n i++;\n }\n if (i === numLabels) {\n return;\n }\n\n pdfViewer.setPageLabels(labels);\n pdfThumbnailViewer.setPageLabels(labels);\n\n // Changing toolbar page display to use labels and we need to set\n // the label of the current page.\n this.toolbar.setPagesCount(pdfDocument.numPages, true);\n this.toolbar.setPageNumber(pdfViewer.currentPageNumber,\n pdfViewer.currentPageLabel);\n });\n\n pagesPromise.then(() => {\n if (!this.supportsPrinting) {\n return;\n }\n pdfDocument.getJavaScript().then((javaScript) => {\n if (javaScript.length) {\n console.warn('Warning: JavaScript is not supported');\n this.fallback(UNSUPPORTED_FEATURES.javaScript);\n }\n // Hack to support auto printing.\n let regex = /\\bprint\\s*\\(/;\n for (let i = 0, ii = javaScript.length; i < ii; i++) {\n let js = javaScript[i];\n if (js && regex.test(js)) {\n setTimeout(function() {\n window.print();\n });\n return;\n }\n }\n });\n });\n\n Promise.all([onePageRendered, animationStarted]).then(() => {\n pdfDocument.getOutline().then((outline) => {\n this.pdfOutlineViewer.render({ outline, });\n });\n pdfDocument.getAttachments().then((attachments) => {\n this.pdfAttachmentViewer.render({ attachments, });\n });\n });\n\n pdfDocument.getMetadata().then(({ info, metadata, }) => {\n this.documentInfo = info;\n this.metadata = metadata;\n\n // Provides some basic debug information\n console.log('PDF ' + pdfDocument.fingerprint + ' [' +\n info.PDFFormatVersion + ' ' + (info.Producer || '-').trim() +\n ' / ' + (info.Creator || '-').trim() + ']' +\n ' (PDF.js: ' + (version || '-') +\n (!PDFJS.disableWebGL ? ' [WebGL]' : '') + ')');\n\n let pdfTitle;\n if (metadata && metadata.has('dc:title')) {\n let title = metadata.get('dc:title');\n // Ghostscript sometimes return 'Untitled', sets the title to 'Untitled'\n if (title !== 'Untitled') {\n pdfTitle = title;\n }\n }\n\n if (!pdfTitle && info && info['Title']) {\n pdfTitle = info['Title'];\n }\n\n if (pdfTitle) {\n this.setTitle(pdfTitle + ' - ' + document.title);\n }\n\n if (info.IsAcroFormPresent) {\n console.warn('Warning: AcroForm/XFA is not supported');\n this.fallback(UNSUPPORTED_FEATURES.forms);\n }\n\n if (typeof PDFJSDev !== 'undefined' &&\n PDFJSDev.test('FIREFOX || MOZCENTRAL')) {\n let versionId = String(info.PDFFormatVersion).slice(-1) | 0;\n let generatorId = 0;\n const KNOWN_GENERATORS = [\n 'acrobat distiller', 'acrobat pdfwriter', 'adobe livecycle',\n 'adobe pdf library', 'adobe photoshop', 'ghostscript', 'tcpdf',\n 'cairo', 'dvipdfm', 'dvips', 'pdftex', 'pdfkit', 'itext', 'prince',\n 'quarkxpress', 'mac os x', 'microsoft', 'openoffice', 'oracle',\n 'luradocument', 'pdf-xchange', 'antenna house', 'aspose.cells', 'fpdf'\n ];\n if (info.Producer) {\n KNOWN_GENERATORS.some(function (generator, s, i) {\n if (generator.indexOf(s) < 0) {\n return false;\n }\n generatorId = i + 1;\n return true;\n }.bind(null, info.Producer.toLowerCase()));\n }\n let formType = !info.IsAcroFormPresent ? null : info.IsXFAPresent ?\n 'xfa' : 'acroform';\n this.externalServices.reportTelemetry({\n type: 'documentInfo',\n version: versionId,\n generator: generatorId,\n formType,\n });\n }\n });\n },\n\n setInitialView(storedHash, { rotation, sidebarView, } = {}) {\n let setRotation = (angle) => {\n if (isValidRotation(angle)) {\n this.pdfViewer.pagesRotation = angle;\n }\n };\n this.isInitialViewSet = true;\n this.pdfSidebar.setInitialView(sidebarView);\n\n if (this.initialBookmark) {\n setRotation(this.initialRotation);\n delete this.initialRotation;\n\n this.pdfLinkService.setHash(this.initialBookmark);\n this.initialBookmark = null;\n } else if (storedHash) {\n setRotation(rotation);\n\n this.pdfLinkService.setHash(storedHash);\n }\n\n // Ensure that the correct page number is displayed in the UI,\n // even if the active page didn't change during document load.\n this.toolbar.setPageNumber(this.pdfViewer.currentPageNumber,\n this.pdfViewer.currentPageLabel);\n this.secondaryToolbar.setPageNumber(this.pdfViewer.currentPageNumber);\n\n if (!this.pdfViewer.currentScaleValue) {\n // Scale was not initialized: invalid bookmark or scale was not specified.\n // Setting the default one.\n this.pdfViewer.currentScaleValue = DEFAULT_SCALE_VALUE;\n }\n },\n\n cleanup() {\n if (!this.pdfDocument) {\n return; // run cleanup when document is loaded\n }\n this.pdfViewer.cleanup();\n this.pdfThumbnailViewer.cleanup();\n\n // We don't want to remove fonts used by active page SVGs.\n if (this.pdfViewer.renderer !== RendererType.SVG) {\n this.pdfDocument.cleanup();\n }\n },\n\n forceRendering() {\n this.pdfRenderingQueue.printing = this.printing;\n this.pdfRenderingQueue.isThumbnailViewEnabled =\n this.pdfSidebar.isThumbnailViewVisible;\n this.pdfRenderingQueue.renderHighestPriority();\n },\n\n beforePrint() {\n if (this.printService) {\n // There is no way to suppress beforePrint/afterPrint events,\n // but PDFPrintService may generate double events -- this will ignore\n // the second event that will be coming from native window.print().\n return;\n }\n\n if (!this.supportsPrinting) {\n this.l10n.get('printing_not_supported', null,\n 'Warning: Printing is not fully supported by ' +\n 'this browser.').then((printMessage) => {\n this.error(printMessage);\n });\n return;\n }\n\n // The beforePrint is a sync method and we need to know layout before\n // returning from this method. Ensure that we can get sizes of the pages.\n if (!this.pdfViewer.pageViewsReady) {\n this.l10n.get('printing_not_ready', null,\n 'Warning: The PDF is not fully loaded for printing.').\n then((notReadyMessage) => {\n window.alert(notReadyMessage);\n });\n return;\n }\n\n let pagesOverview = this.pdfViewer.getPagesOverview();\n let printContainer = this.appConfig.printContainer;\n let printService = PDFPrintServiceFactory.instance.createPrintService(\n this.pdfDocument, pagesOverview, printContainer, this.l10n);\n this.printService = printService;\n this.forceRendering();\n\n printService.layout();\n\n if (typeof PDFJSDev !== 'undefined' &&\n PDFJSDev.test('FIREFOX || MOZCENTRAL')) {\n this.externalServices.reportTelemetry({\n type: 'print',\n });\n }\n },\n\n afterPrint: function pdfViewSetupAfterPrint() {\n if (this.printService) {\n this.printService.destroy();\n this.printService = null;\n }\n this.forceRendering();\n },\n\n rotatePages(delta) {\n if (!this.pdfDocument) {\n return;\n }\n let newRotation = (this.pdfViewer.pagesRotation + 360 + delta) % 360;\n this.pdfViewer.pagesRotation = newRotation;\n // Note that the thumbnail viewer is updated, and rendering is triggered,\n // in the 'rotationchanging' event handler.\n },\n\n requestPresentationMode() {\n if (!this.pdfPresentationMode) {\n return;\n }\n this.pdfPresentationMode.request();\n },\n\n bindEvents() {\n let { eventBus, _boundEvents, } = this;\n\n _boundEvents.beforePrint = this.beforePrint.bind(this);\n _boundEvents.afterPrint = this.afterPrint.bind(this);\n\n eventBus.on('resize', webViewerResize);\n eventBus.on('hashchange', webViewerHashchange);\n eventBus.on('beforeprint', _boundEvents.beforePrint);\n eventBus.on('afterprint', _boundEvents.afterPrint);\n eventBus.on('pagerendered', webViewerPageRendered);\n eventBus.on('textlayerrendered', webViewerTextLayerRendered);\n eventBus.on('updateviewarea', webViewerUpdateViewarea);\n eventBus.on('pagechanging', webViewerPageChanging);\n eventBus.on('scalechanging', webViewerScaleChanging);\n eventBus.on('rotationchanging', webViewerRotationChanging);\n eventBus.on('sidebarviewchanged', webViewerSidebarViewChanged);\n eventBus.on('pagemode', webViewerPageMode);\n eventBus.on('namedaction', webViewerNamedAction);\n eventBus.on('presentationmodechanged', webViewerPresentationModeChanged);\n eventBus.on('presentationmode', webViewerPresentationMode);\n eventBus.on('openfile', webViewerOpenFile);\n eventBus.on('print', webViewerPrint);\n eventBus.on('download', webViewerDownload);\n eventBus.on('firstpage', webViewerFirstPage);\n eventBus.on('lastpage', webViewerLastPage);\n eventBus.on('nextpage', webViewerNextPage);\n eventBus.on('previouspage', webViewerPreviousPage);\n eventBus.on('zoomin', webViewerZoomIn);\n eventBus.on('zoomout', webViewerZoomOut);\n eventBus.on('pagenumberchanged', webViewerPageNumberChanged);\n eventBus.on('scalechanged', webViewerScaleChanged);\n eventBus.on('rotatecw', webViewerRotateCw);\n eventBus.on('rotateccw', webViewerRotateCcw);\n eventBus.on('documentproperties', webViewerDocumentProperties);\n eventBus.on('find', webViewerFind);\n eventBus.on('findfromurlhash', webViewerFindFromUrlHash);\n if (typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC')) {\n eventBus.on('fileinputchange', webViewerFileInputChange);\n }\n },\n\n bindWindowEvents() {\n let { eventBus, _boundEvents, } = this;\n\n _boundEvents.windowResize = () => {\n eventBus.dispatch('resize');\n };\n _boundEvents.windowHashChange = () => {\n eventBus.dispatch('hashchange', {\n hash: document.location.hash.substring(1),\n });\n };\n _boundEvents.windowBeforePrint = () => {\n eventBus.dispatch('beforeprint');\n };\n _boundEvents.windowAfterPrint = () => {\n eventBus.dispatch('afterprint');\n };\n\n window.addEventListener('wheel', webViewerWheel);\n window.addEventListener('click', webViewerClick);\n window.addEventListener('keydown', webViewerKeyDown);\n window.addEventListener('resize', _boundEvents.windowResize);\n window.addEventListener('hashchange', _boundEvents.windowHashChange);\n window.addEventListener('beforeprint', _boundEvents.windowBeforePrint);\n window.addEventListener('afterprint', _boundEvents.windowAfterPrint);\n },\n\n unbindEvents() {\n let { eventBus, _boundEvents, } = this;\n\n eventBus.off('resize', webViewerResize);\n eventBus.off('hashchange', webViewerHashchange);\n eventBus.off('beforeprint', _boundEvents.beforePrint);\n eventBus.off('afterprint', _boundEvents.afterPrint);\n eventBus.off('pagerendered', webViewerPageRendered);\n eventBus.off('textlayerrendered', webViewerTextLayerRendered);\n eventBus.off('updateviewarea', webViewerUpdateViewarea);\n eventBus.off('pagechanging', webViewerPageChanging);\n eventBus.off('scalechanging', webViewerScaleChanging);\n eventBus.off('rotationchanging', webViewerRotationChanging);\n eventBus.off('sidebarviewchanged', webViewerSidebarViewChanged);\n eventBus.off('pagemode', webViewerPageMode);\n eventBus.off('namedaction', webViewerNamedAction);\n eventBus.off('presentationmodechanged', webViewerPresentationModeChanged);\n eventBus.off('presentationmode', webViewerPresentationMode);\n eventBus.off('openfile', webViewerOpenFile);\n eventBus.off('print', webViewerPrint);\n eventBus.off('download', webViewerDownload);\n eventBus.off('firstpage', webViewerFirstPage);\n eventBus.off('lastpage', webViewerLastPage);\n eventBus.off('nextpage', webViewerNextPage);\n eventBus.off('previouspage', webViewerPreviousPage);\n eventBus.off('zoomin', webViewerZoomIn);\n eventBus.off('zoomout', webViewerZoomOut);\n eventBus.off('pagenumberchanged', webViewerPageNumberChanged);\n eventBus.off('scalechanged', webViewerScaleChanged);\n eventBus.off('rotatecw', webViewerRotateCw);\n eventBus.off('rotateccw', webViewerRotateCcw);\n eventBus.off('documentproperties', webViewerDocumentProperties);\n eventBus.off('find', webViewerFind);\n eventBus.off('findfromurlhash', webViewerFindFromUrlHash);\n if (typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC')) {\n eventBus.off('fileinputchange', webViewerFileInputChange);\n }\n\n _boundEvents.beforePrint = null;\n _boundEvents.afterPrint = null;\n },\n\n unbindWindowEvents() {\n let { _boundEvents, } = this;\n\n window.removeEventListener('wheel', webViewerWheel);\n window.removeEventListener('click', webViewerClick);\n window.removeEventListener('keydown', webViewerKeyDown);\n window.removeEventListener('resize', _boundEvents.windowResize);\n window.removeEventListener('hashchange', _boundEvents.windowHashChange);\n window.removeEventListener('beforeprint', _boundEvents.windowBeforePrint);\n window.removeEventListener('afterprint', _boundEvents.windowAfterPrint);\n\n _boundEvents.windowResize = null;\n _boundEvents.windowHashChange = null;\n _boundEvents.windowBeforePrint = null;\n _boundEvents.windowAfterPrint = null;\n },\n};\n\nlet validateFileURL;\nif (typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC')) {\n const HOSTED_VIEWER_ORIGINS = ['null',\n 'http://mozilla.github.io', 'https://mozilla.github.io'];\n validateFileURL = function validateFileURL(file) {\n if (file === undefined) {\n return;\n }\n try {\n let viewerOrigin = new URL(window.location.href).origin || 'null';\n if (HOSTED_VIEWER_ORIGINS.indexOf(viewerOrigin) >= 0) {\n // Hosted or local viewer, allow for any file locations\n return;\n }\n let fileOrigin = new URL(file, window.location.href).origin;\n // Removing of the following line will not guarantee that the viewer will\n // start accepting URLs from foreign origin -- CORS headers on the remote\n // server must be properly configured.\n if (fileOrigin !== viewerOrigin) {\n throw new Error('file origin does not match viewer\\'s');\n }\n } catch (ex) {\n let message = ex && ex.message;\n PDFViewerApplication.l10n.get('loading_error', null,\n 'An error occurred while loading the PDF.').\n then((loadingErrorMessage) => {\n PDFViewerApplication.error(loadingErrorMessage, { message, });\n });\n throw ex;\n }\n };\n}\n\nfunction loadAndEnablePDFBug(enabledTabs) {\n return new Promise(function (resolve, reject) {\n let appConfig = PDFViewerApplication.appConfig;\n let script = document.createElement('script');\n script.src = appConfig.debuggerScriptPath;\n script.onload = function () {\n PDFBug.enable(enabledTabs);\n PDFBug.init({\n PDFJS,\n OPS,\n }, appConfig.mainContainer);\n resolve();\n };\n script.onerror = function () {\n reject(new Error('Cannot load debugger at ' + script.src));\n };\n (document.getElementsByTagName('head')[0] || document.body).\n appendChild(script);\n });\n}\n\nfunction webViewerInitialized() {\n let appConfig = PDFViewerApplication.appConfig;\n let file;\n if (typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC')) {\n let queryString = document.location.search.substring(1);\n let params = parseQueryString(queryString);\n file = 'file' in params ? params.file : appConfig.defaultUrl;\n validateFileURL(file);\n } else if (PDFJSDev.test('FIREFOX || MOZCENTRAL')) {\n file = window.location.href.split('#')[0];\n } else if (PDFJSDev.test('CHROME')) {\n file = appConfig.defaultUrl;\n }\n\n let waitForBeforeOpening = [];\n if (typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC')) {\n let fileInput = document.createElement('input');\n fileInput.id = appConfig.openFileInputName;\n fileInput.className = 'fileInput';\n fileInput.setAttribute('type', 'file');\n fileInput.oncontextmenu = noContextMenuHandler;\n document.body.appendChild(fileInput);\n\n if (!window.File || !window.FileReader ||\n !window.FileList || !window.Blob) {\n appConfig.toolbar.openFile.setAttribute('hidden', 'true');\n appConfig.secondaryToolbar.openFileButton.setAttribute('hidden', 'true');\n } else {\n fileInput.value = null;\n }\n\n fileInput.addEventListener('change', function(evt) {\n let files = evt.target.files;\n if (!files || files.length === 0) {\n return;\n }\n PDFViewerApplication.eventBus.dispatch('fileinputchange', {\n fileInput: evt.target,\n });\n });\n } else {\n appConfig.toolbar.openFile.setAttribute('hidden', 'true');\n appConfig.secondaryToolbar.openFileButton.setAttribute('hidden', 'true');\n }\n\n if ((typeof PDFJSDev === 'undefined' || !PDFJSDev.test('PRODUCTION')) ||\n PDFViewerApplication.viewerPrefs['pdfBugEnabled']) {\n // Special debugging flags in the hash section of the URL.\n let hash = document.location.hash.substring(1);\n let hashParams = parseQueryString(hash);\n\n if ('disableworker' in hashParams) {\n PDFJS.disableWorker = (hashParams['disableworker'] === 'true');\n }\n if ('disablerange' in hashParams) {\n PDFJS.disableRange = (hashParams['disablerange'] === 'true');\n }\n if ('disablestream' in hashParams) {\n PDFJS.disableStream = (hashParams['disablestream'] === 'true');\n }\n if ('disableautofetch' in hashParams) {\n PDFJS.disableAutoFetch = (hashParams['disableautofetch'] === 'true');\n }\n if ('disablefontface' in hashParams) {\n PDFJS.disableFontFace = (hashParams['disablefontface'] === 'true');\n }\n if ('disablehistory' in hashParams) {\n PDFJS.disableHistory = (hashParams['disablehistory'] === 'true');\n }\n if ('webgl' in hashParams) {\n PDFJS.disableWebGL = (hashParams['webgl'] !== 'true');\n }\n if ('useonlycsszoom' in hashParams) {\n PDFJS.useOnlyCssZoom = (hashParams['useonlycsszoom'] === 'true');\n }\n if ('verbosity' in hashParams) {\n PDFJS.verbosity = hashParams['verbosity'] | 0;\n }\n if ('ignorecurrentpositiononzoom' in hashParams) {\n PDFJS.ignoreCurrentPositionOnZoom =\n (hashParams['ignorecurrentpositiononzoom'] === 'true');\n }\n if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('PRODUCTION')) {\n if ('disablebcmaps' in hashParams && hashParams['disablebcmaps']) {\n PDFJS.cMapUrl = '../external/cmaps/';\n PDFJS.cMapPacked = false;\n }\n }\n if ('textlayer' in hashParams) {\n switch (hashParams['textlayer']) {\n case 'off':\n PDFJS.disableTextLayer = true;\n break;\n case 'visible':\n case 'shadow':\n case 'hover':\n let viewer = appConfig.viewerContainer;\n viewer.classList.add('textLayer-' + hashParams['textlayer']);\n break;\n }\n }\n if ('pdfbug' in hashParams) {\n PDFJS.pdfBug = true;\n let pdfBug = hashParams['pdfbug'];\n let enabled = pdfBug.split(',');\n waitForBeforeOpening.push(loadAndEnablePDFBug(enabled));\n }\n }\n\n if (typeof PDFJSDev !== 'undefined' &&\n PDFJSDev.test('FIREFOX || MOZCENTRAL') &&\n !PDFViewerApplication.supportsDocumentFonts) {\n PDFJS.disableFontFace = true;\n PDFViewerApplication.l10n.get('web_fonts_disabled', null,\n 'Web fonts are disabled: unable to use embedded PDF fonts.').\n then((msg) => {\n console.warn(msg);\n });\n }\n\n if (!PDFViewerApplication.supportsPrinting) {\n appConfig.toolbar.print.classList.add('hidden');\n appConfig.secondaryToolbar.printButton.classList.add('hidden');\n }\n\n if (!PDFViewerApplication.supportsFullscreen) {\n appConfig.toolbar.presentationModeButton.classList.add('hidden');\n appConfig.secondaryToolbar.presentationModeButton.classList.add('hidden');\n }\n\n if (PDFViewerApplication.supportsIntegratedFind) {\n appConfig.toolbar.viewFind.classList.add('hidden');\n }\n\n appConfig.sidebar.mainContainer.addEventListener('transitionend',\n function(evt) {\n if (evt.target === /* mainContainer */ this) {\n PDFViewerApplication.eventBus.dispatch('resize');\n }\n }, true);\n\n appConfig.sidebar.toggleButton.addEventListener('click', function() {\n PDFViewerApplication.pdfSidebar.toggle();\n });\n\n Promise.all(waitForBeforeOpening).then(function () {\n webViewerOpenFileViaURL(file);\n }).catch(function (reason) {\n PDFViewerApplication.l10n.get('loading_error', null,\n 'An error occurred while opening.').then((msg) => {\n PDFViewerApplication.error(msg, reason);\n });\n });\n}\n\nlet webViewerOpenFileViaURL;\nif (typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC')) {\n webViewerOpenFileViaURL = function webViewerOpenFileViaURL(file) {\n if (file && file.lastIndexOf('file:', 0) === 0) {\n // file:-scheme. Load the contents in the main thread because QtWebKit\n // cannot load file:-URLs in a Web Worker. file:-URLs are usually loaded\n // very quickly, so there is no need to set up progress event listeners.\n PDFViewerApplication.setTitleUsingUrl(file);\n let xhr = new XMLHttpRequest();\n xhr.onload = function() {\n PDFViewerApplication.open(new Uint8Array(xhr.response));\n };\n try {\n xhr.open('GET', file);\n xhr.responseType = 'arraybuffer';\n xhr.send();\n } catch (ex) {\n PDFViewerApplication.l10n.get('loading_error', null,\n 'An error occurred while loading the PDF.').then((msg) => {\n PDFViewerApplication.error(msg, ex);\n });\n }\n return;\n }\n\n if (file) {\n PDFViewerApplication.open(file);\n }\n };\n} else if (PDFJSDev.test('FIREFOX || MOZCENTRAL || CHROME')) {\n webViewerOpenFileViaURL = function webViewerOpenFileViaURL(file) {\n PDFViewerApplication.setTitleUsingUrl(file);\n PDFViewerApplication.initPassiveLoading();\n };\n} else {\n webViewerOpenFileViaURL = function webViewerOpenFileURL(file) {\n if (file) {\n throw new Error('Not implemented: webViewerOpenFileURL');\n }\n };\n}\n\nfunction webViewerPageRendered(evt) {\n let pageNumber = evt.pageNumber;\n let pageIndex = pageNumber - 1;\n let pageView = PDFViewerApplication.pdfViewer.getPageView(pageIndex);\n\n // If the page is still visible when it has finished rendering,\n // ensure that the page number input loading indicator is hidden.\n if (pageNumber === PDFViewerApplication.page) {\n PDFViewerApplication.toolbar.updateLoadingIndicatorState(false);\n }\n\n // Prevent errors in the edge-case where the PDF document is removed *before*\n // the 'pagerendered' event handler is invoked.\n if (!pageView) {\n return;\n }\n\n // Use the rendered page to set the corresponding thumbnail image.\n if (PDFViewerApplication.pdfSidebar.isThumbnailViewVisible) {\n let thumbnailView = PDFViewerApplication.pdfThumbnailViewer.\n getThumbnail(pageIndex);\n thumbnailView.setImage(pageView);\n }\n\n if (PDFJS.pdfBug && Stats.enabled && pageView.stats) {\n Stats.add(pageNumber, pageView.stats);\n }\n\n if (pageView.error) {\n PDFViewerApplication.l10n.get('rendering_error', null,\n 'An error occurred while rendering the page.').then((msg) => {\n PDFViewerApplication.error(msg, pageView.error);\n });\n }\n\n if (typeof PDFJSDev !== 'undefined' &&\n PDFJSDev.test('FIREFOX || MOZCENTRAL')) {\n PDFViewerApplication.externalServices.reportTelemetry({\n type: 'pageInfo',\n });\n // It is a good time to report stream and font types.\n PDFViewerApplication.pdfDocument.getStats().then(function (stats) {\n PDFViewerApplication.externalServices.reportTelemetry({\n type: 'documentStats',\n stats,\n });\n });\n }\n}\n\nfunction webViewerTextLayerRendered(evt) {\n if (typeof PDFJSDev !== 'undefined' &&\n PDFJSDev.test('FIREFOX || MOZCENTRAL') &&\n evt.numTextDivs > 0 && !PDFViewerApplication.supportsDocumentColors) {\n PDFViewerApplication.l10n.get('document_colors_not_allowed', null,\n 'PDF documents are not allowed to use their own colors: ' +\n '\\'Allow pages to choose their own colors\\' ' +\n 'is deactivated in the browser.').\n then((msg) => {\n console.error(msg);\n });\n PDFViewerApplication.fallback();\n }\n}\n\nfunction webViewerPageMode(evt) {\n // Handle the 'pagemode' hash parameter, see also `PDFLinkService_setHash`.\n let mode = evt.mode, view;\n switch (mode) {\n case 'thumbs':\n view = SidebarView.THUMBS;\n break;\n case 'bookmarks':\n case 'outline':\n view = SidebarView.OUTLINE;\n break;\n case 'attachments':\n view = SidebarView.ATTACHMENTS;\n break;\n case 'none':\n view = SidebarView.NONE;\n break;\n default:\n console.error('Invalid \"pagemode\" hash parameter: ' + mode);\n return;\n }\n PDFViewerApplication.pdfSidebar.switchView(view, /* forceOpen = */ true);\n}\n\nfunction webViewerNamedAction(evt) {\n // Processing couple of named actions that might be useful.\n // See also PDFLinkService.executeNamedAction\n let action = evt.action;\n switch (action) {\n case 'GoToPage':\n PDFViewerApplication.appConfig.toolbar.pageNumber.select();\n break;\n\n case 'Find':\n if (!PDFViewerApplication.supportsIntegratedFind) {\n PDFViewerApplication.findBar.toggle();\n }\n break;\n }\n}\n\nfunction webViewerPresentationModeChanged(evt) {\n let { active, switchInProgress, } = evt;\n PDFViewerApplication.pdfViewer.presentationModeState =\n switchInProgress ? PresentationModeState.CHANGING :\n active ? PresentationModeState.FULLSCREEN : PresentationModeState.NORMAL;\n}\n\nfunction webViewerSidebarViewChanged(evt) {\n PDFViewerApplication.pdfRenderingQueue.isThumbnailViewEnabled =\n PDFViewerApplication.pdfSidebar.isThumbnailViewVisible;\n\n let store = PDFViewerApplication.store;\n if (store && PDFViewerApplication.isInitialViewSet) {\n // Only update the storage when the document has been loaded *and* rendered.\n store.set('sidebarView', evt.view).catch(function() { });\n }\n}\n\nfunction webViewerUpdateViewarea(evt) {\n let location = evt.location, store = PDFViewerApplication.store;\n\n if (store && PDFViewerApplication.isInitialViewSet) {\n store.setMultiple({\n 'exists': true,\n 'page': location.pageNumber,\n 'zoom': location.scale,\n 'scrollLeft': location.left,\n 'scrollTop': location.top,\n 'rotation': location.rotation,\n }).catch(function() { /* unable to write to storage */ });\n }\n let href =\n PDFViewerApplication.pdfLinkService.getAnchorUrl(location.pdfOpenParams);\n PDFViewerApplication.appConfig.toolbar.viewBookmark.href = href;\n PDFViewerApplication.appConfig.secondaryToolbar.viewBookmarkButton.href =\n href;\n\n // Show/hide the loading indicator in the page number input element.\n let currentPage =\n PDFViewerApplication.pdfViewer.getPageView(PDFViewerApplication.page - 1);\n let loading = currentPage.renderingState !== RenderingStates.FINISHED;\n PDFViewerApplication.toolbar.updateLoadingIndicatorState(loading);\n}\n\nfunction webViewerResize() {\n let { pdfDocument, pdfViewer, } = PDFViewerApplication;\n if (!pdfDocument) {\n return;\n }\n let currentScaleValue = pdfViewer.currentScaleValue;\n if (currentScaleValue === 'auto' ||\n currentScaleValue === 'page-fit' ||\n currentScaleValue === 'page-width') {\n // Note: the scale is constant for 'page-actual'.\n pdfViewer.currentScaleValue = currentScaleValue;\n }\n pdfViewer.update();\n}\n\nfunction webViewerHashchange(evt) {\n let hash = evt.hash;\n if (!hash) {\n return;\n }\n if (!PDFViewerApplication.isInitialViewSet) {\n PDFViewerApplication.initialBookmark = hash;\n } else if (!PDFViewerApplication.pdfHistory.popStateInProgress) {\n PDFViewerApplication.pdfLinkService.setHash(hash);\n }\n}\n\nlet webViewerFileInputChange;\nif (typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC')) {\n webViewerFileInputChange = function webViewerFileInputChange(evt) {\n let file = evt.fileInput.files[0];\n\n if (!PDFJS.disableCreateObjectURL && URL.createObjectURL) {\n PDFViewerApplication.open(URL.createObjectURL(file));\n } else {\n // Read the local file into a Uint8Array.\n let fileReader = new FileReader();\n fileReader.onload = function webViewerChangeFileReaderOnload(evt) {\n let buffer = evt.target.result;\n PDFViewerApplication.open(new Uint8Array(buffer));\n };\n fileReader.readAsArrayBuffer(file);\n }\n\n PDFViewerApplication.setTitleUsingUrl(file.name);\n\n // URL does not reflect proper document location - hiding some icons.\n let appConfig = PDFViewerApplication.appConfig;\n appConfig.toolbar.viewBookmark.setAttribute('hidden', 'true');\n appConfig.secondaryToolbar.viewBookmarkButton.setAttribute('hidden',\n 'true');\n appConfig.toolbar.download.setAttribute('hidden', 'true');\n appConfig.secondaryToolbar.downloadButton.setAttribute('hidden', 'true');\n };\n}\n\nfunction webViewerPresentationMode() {\n PDFViewerApplication.requestPresentationMode();\n}\nfunction webViewerOpenFile() {\n if (typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC')) {\n let openFileInputName = PDFViewerApplication.appConfig.openFileInputName;\n document.getElementById(openFileInputName).click();\n }\n}\nfunction webViewerPrint() {\n window.print();\n}\nfunction webViewerDownload() {\n PDFViewerApplication.download();\n}\nfunction webViewerFirstPage() {\n if (PDFViewerApplication.pdfDocument) {\n PDFViewerApplication.page = 1;\n }\n}\nfunction webViewerLastPage() {\n if (PDFViewerApplication.pdfDocument) {\n PDFViewerApplication.page = PDFViewerApplication.pagesCount;\n }\n}\nfunction webViewerNextPage() {\n PDFViewerApplication.page++;\n}\nfunction webViewerPreviousPage() {\n PDFViewerApplication.page--;\n}\nfunction webViewerZoomIn() {\n PDFViewerApplication.zoomIn();\n}\nfunction webViewerZoomOut() {\n PDFViewerApplication.zoomOut();\n}\nfunction webViewerPageNumberChanged(evt) {\n let pdfViewer = PDFViewerApplication.pdfViewer;\n pdfViewer.currentPageLabel = evt.value;\n\n // Ensure that the page number input displays the correct value, even if the\n // value entered by the user was invalid (e.g. a floating point number).\n if (evt.value !== pdfViewer.currentPageNumber.toString() &&\n evt.value !== pdfViewer.currentPageLabel) {\n PDFViewerApplication.toolbar.setPageNumber(\n pdfViewer.currentPageNumber, pdfViewer.currentPageLabel);\n }\n}\nfunction webViewerScaleChanged(evt) {\n PDFViewerApplication.pdfViewer.currentScaleValue = evt.value;\n}\nfunction webViewerRotateCw() {\n PDFViewerApplication.rotatePages(90);\n}\nfunction webViewerRotateCcw() {\n PDFViewerApplication.rotatePages(-90);\n}\nfunction webViewerDocumentProperties() {\n PDFViewerApplication.pdfDocumentProperties.open();\n}\n\nfunction webViewerFind(evt) {\n PDFViewerApplication.findController.executeCommand('find' + evt.type, {\n query: evt.query,\n phraseSearch: evt.phraseSearch,\n caseSensitive: evt.caseSensitive,\n highlightAll: evt.highlightAll,\n findPrevious: evt.findPrevious,\n });\n}\n\nfunction webViewerFindFromUrlHash(evt) {\n PDFViewerApplication.findController.executeCommand('find', {\n query: evt.query,\n phraseSearch: evt.phraseSearch,\n caseSensitive: false,\n highlightAll: true,\n findPrevious: false,\n });\n}\n\nfunction webViewerScaleChanging(evt) {\n PDFViewerApplication.toolbar.setPageScale(evt.presetValue, evt.scale);\n\n PDFViewerApplication.pdfViewer.update();\n}\n\nfunction webViewerRotationChanging(evt) {\n PDFViewerApplication.pdfThumbnailViewer.pagesRotation = evt.pagesRotation;\n\n PDFViewerApplication.forceRendering();\n // Ensure that the active page doesn't change during rotation.\n PDFViewerApplication.pdfViewer.currentPageNumber = evt.pageNumber;\n}\n\nfunction webViewerPageChanging(evt) {\n let page = evt.pageNumber;\n\n PDFViewerApplication.toolbar.setPageNumber(page, evt.pageLabel || null);\n PDFViewerApplication.secondaryToolbar.setPageNumber(page);\n\n if (PDFViewerApplication.pdfSidebar.isThumbnailViewVisible) {\n PDFViewerApplication.pdfThumbnailViewer.scrollThumbnailIntoView(page);\n }\n\n // we need to update stats\n if (PDFJS.pdfBug && Stats.enabled) {\n let pageView = PDFViewerApplication.pdfViewer.getPageView(page - 1);\n if (pageView.stats) {\n Stats.add(page, pageView.stats);\n }\n }\n}\n\nlet zoomDisabled = false, zoomDisabledTimeout;\nfunction webViewerWheel(evt) {\n let pdfViewer = PDFViewerApplication.pdfViewer;\n if (pdfViewer.isInPresentationMode) {\n return;\n }\n\n if (evt.ctrlKey || evt.metaKey) {\n let support = PDFViewerApplication.supportedMouseWheelZoomModifierKeys;\n if ((evt.ctrlKey && !support.ctrlKey) ||\n (evt.metaKey && !support.metaKey)) {\n return;\n }\n // Only zoom the pages, not the entire viewer.\n evt.preventDefault();\n // NOTE: this check must be placed *after* preventDefault.\n if (zoomDisabled) {\n return;\n }\n\n let previousScale = pdfViewer.currentScale;\n\n let delta = normalizeWheelEventDelta(evt);\n\n const MOUSE_WHEEL_DELTA_PER_PAGE_SCALE = 3.0;\n let ticks = delta * MOUSE_WHEEL_DELTA_PER_PAGE_SCALE;\n if (ticks < 0) {\n PDFViewerApplication.zoomOut(-ticks);\n } else {\n PDFViewerApplication.zoomIn(ticks);\n }\n\n let currentScale = pdfViewer.currentScale;\n if (previousScale !== currentScale) {\n // After scaling the page via zoomIn/zoomOut, the position of the upper-\n // left corner is restored. When the mouse wheel is used, the position\n // under the cursor should be restored instead.\n let scaleCorrectionFactor = currentScale / previousScale - 1;\n let rect = pdfViewer.container.getBoundingClientRect();\n let dx = evt.clientX - rect.left;\n let dy = evt.clientY - rect.top;\n pdfViewer.container.scrollLeft += dx * scaleCorrectionFactor;\n pdfViewer.container.scrollTop += dy * scaleCorrectionFactor;\n }\n } else {\n zoomDisabled = true;\n clearTimeout(zoomDisabledTimeout);\n zoomDisabledTimeout = setTimeout(function () {\n zoomDisabled = false;\n }, 1000);\n }\n}\n\nfunction webViewerClick(evt) {\n if (!PDFViewerApplication.secondaryToolbar.isOpen) {\n return;\n }\n let appConfig = PDFViewerApplication.appConfig;\n if (PDFViewerApplication.pdfViewer.containsElement(evt.target) ||\n (appConfig.toolbar.container.contains(evt.target) &&\n evt.target !== appConfig.secondaryToolbar.toggleButton)) {\n PDFViewerApplication.secondaryToolbar.close();\n }\n}\n\nfunction webViewerKeyDown(evt) {\n if (PDFViewerApplication.overlayManager.active) {\n return;\n }\n\n let handled = false, ensureViewerFocused = false;\n let cmd = (evt.ctrlKey ? 1 : 0) |\n (evt.altKey ? 2 : 0) |\n (evt.shiftKey ? 4 : 0) |\n (evt.metaKey ? 8 : 0);\n\n let pdfViewer = PDFViewerApplication.pdfViewer;\n let isViewerInPresentationMode = pdfViewer && pdfViewer.isInPresentationMode;\n\n // First, handle the key bindings that are independent whether an input\n // control is selected or not.\n if (cmd === 1 || cmd === 8 || cmd === 5 || cmd === 12) {\n // either CTRL or META key with optional SHIFT.\n switch (evt.keyCode) {\n case 70: // f\n if (!PDFViewerApplication.supportsIntegratedFind) {\n PDFViewerApplication.findBar.open();\n handled = true;\n }\n break;\n case 71: // g\n if (!PDFViewerApplication.supportsIntegratedFind) {\n let findState = PDFViewerApplication.findController.state;\n if (findState) {\n PDFViewerApplication.findController.executeCommand('findagain', {\n query: findState.query,\n phraseSearch: findState.phraseSearch,\n caseSensitive: findState.caseSensitive,\n highlightAll: findState.highlightAll,\n findPrevious: cmd === 5 || cmd === 12,\n });\n }\n handled = true;\n }\n break;\n case 61: // FF/Mac '='\n case 107: // FF '+' and '='\n case 187: // Chrome '+'\n case 171: // FF with German keyboard\n if (!isViewerInPresentationMode) {\n PDFViewerApplication.zoomIn();\n }\n handled = true;\n break;\n case 173: // FF/Mac '-'\n case 109: // FF '-'\n case 189: // Chrome '-'\n if (!isViewerInPresentationMode) {\n PDFViewerApplication.zoomOut();\n }\n handled = true;\n break;\n case 48: // '0'\n case 96: // '0' on Numpad of Swedish keyboard\n if (!isViewerInPresentationMode) {\n // keeping it unhandled (to restore page zoom to 100%)\n setTimeout(function () {\n // ... and resetting the scale after browser adjusts its scale\n pdfViewer.currentScaleValue = DEFAULT_SCALE_VALUE;\n });\n handled = false;\n }\n break;\n\n case 38: // up arrow\n if (isViewerInPresentationMode || PDFViewerApplication.page > 1) {\n PDFViewerApplication.page = 1;\n handled = true;\n ensureViewerFocused = true;\n }\n break;\n case 40: // down arrow\n if (isViewerInPresentationMode ||\n PDFViewerApplication.page < PDFViewerApplication.pagesCount) {\n PDFViewerApplication.page = PDFViewerApplication.pagesCount;\n handled = true;\n ensureViewerFocused = true;\n }\n break;\n }\n }\n\n if (typeof PDFJSDev === 'undefined' ||\n !PDFJSDev.test('FIREFOX || MOZCENTRAL')) {\n // CTRL or META without shift\n if (cmd === 1 || cmd === 8) {\n switch (evt.keyCode) {\n case 83: // s\n PDFViewerApplication.download();\n handled = true;\n break;\n }\n }\n }\n\n // CTRL+ALT or Option+Command\n if (cmd === 3 || cmd === 10) {\n switch (evt.keyCode) {\n case 80: // p\n PDFViewerApplication.requestPresentationMode();\n handled = true;\n break;\n case 71: // g\n // focuses input#pageNumber field\n PDFViewerApplication.appConfig.toolbar.pageNumber.select();\n handled = true;\n break;\n }\n }\n\n if (handled) {\n if (ensureViewerFocused && !isViewerInPresentationMode) {\n pdfViewer.focus();\n }\n evt.preventDefault();\n return;\n }\n\n // Some shortcuts should not get handled if a control/input element\n // is selected.\n let curElement = document.activeElement || document.querySelector(':focus');\n let curElementTagName = curElement && curElement.tagName.toUpperCase();\n if (curElementTagName === 'INPUT' ||\n curElementTagName === 'TEXTAREA' ||\n curElementTagName === 'SELECT') {\n // Make sure that the secondary toolbar is closed when Escape is pressed.\n if (evt.keyCode !== 27) { // 'Esc'\n return;\n }\n }\n\n if (cmd === 0) { // no control key pressed at all.\n switch (evt.keyCode) {\n case 38: // up arrow\n case 33: // pg up\n case 8: // backspace\n if (!isViewerInPresentationMode &&\n pdfViewer.currentScaleValue !== 'page-fit') {\n break;\n }\n /* in presentation mode */\n /* falls through */\n case 37: // left arrow\n // horizontal scrolling using arrow keys\n if (pdfViewer.isHorizontalScrollbarEnabled) {\n break;\n }\n /* falls through */\n case 75: // 'k'\n case 80: // 'p'\n if (PDFViewerApplication.page > 1) {\n PDFViewerApplication.page--;\n }\n handled = true;\n break;\n case 27: // esc key\n if (PDFViewerApplication.secondaryToolbar.isOpen) {\n PDFViewerApplication.secondaryToolbar.close();\n handled = true;\n }\n if (!PDFViewerApplication.supportsIntegratedFind &&\n PDFViewerApplication.findBar.opened) {\n PDFViewerApplication.findBar.close();\n handled = true;\n }\n break;\n case 40: // down arrow\n case 34: // pg down\n case 32: // spacebar\n if (!isViewerInPresentationMode &&\n pdfViewer.currentScaleValue !== 'page-fit') {\n break;\n }\n /* falls through */\n case 39: // right arrow\n // horizontal scrolling using arrow keys\n if (pdfViewer.isHorizontalScrollbarEnabled) {\n break;\n }\n /* falls through */\n case 74: // 'j'\n case 78: // 'n'\n if (PDFViewerApplication.page < PDFViewerApplication.pagesCount) {\n PDFViewerApplication.page++;\n }\n handled = true;\n break;\n\n case 36: // home\n if (isViewerInPresentationMode || PDFViewerApplication.page > 1) {\n PDFViewerApplication.page = 1;\n handled = true;\n ensureViewerFocused = true;\n }\n break;\n case 35: // end\n if (isViewerInPresentationMode ||\n PDFViewerApplication.page < PDFViewerApplication.pagesCount) {\n PDFViewerApplication.page = PDFViewerApplication.pagesCount;\n handled = true;\n ensureViewerFocused = true;\n }\n break;\n\n case 83: // 's'\n PDFViewerApplication.pdfCursorTools.switchTool(CursorTool.SELECT);\n break;\n case 72: // 'h'\n PDFViewerApplication.pdfCursorTools.switchTool(CursorTool.HAND);\n break;\n\n case 82: // 'r'\n PDFViewerApplication.rotatePages(90);\n break;\n }\n }\n\n if (cmd === 4) { // shift-key\n switch (evt.keyCode) {\n case 32: // spacebar\n if (!isViewerInPresentationMode &&\n pdfViewer.currentScaleValue !== 'page-fit') {\n break;\n }\n if (PDFViewerApplication.page > 1) {\n PDFViewerApplication.page--;\n }\n handled = true;\n break;\n\n case 82: // 'r'\n PDFViewerApplication.rotatePages(-90);\n break;\n }\n }\n\n if (!handled && !isViewerInPresentationMode) {\n // 33=Page Up 34=Page Down 35=End 36=Home\n // 37=Left 38=Up 39=Right 40=Down\n // 32=Spacebar\n if ((evt.keyCode >= 33 && evt.keyCode <= 40) ||\n (evt.keyCode === 32 && curElementTagName !== 'BUTTON')) {\n ensureViewerFocused = true;\n }\n }\n\n if (ensureViewerFocused && !pdfViewer.containsElement(curElement)) {\n // The page container is not focused, but a page navigation key has been\n // pressed. Change the focus to the viewer container to make sure that\n // navigation by keyboard works as expected.\n pdfViewer.focus();\n }\n\n if (handled) {\n evt.preventDefault();\n }\n}\n\n/**\n * Converts API PageMode values to the format used by `PDFSidebar`.\n * NOTE: There's also a \"FullScreen\" parameter which is not possible to support,\n * since the Fullscreen API used in browsers requires that entering\n * fullscreen mode only occurs as a result of a user-initiated event.\n * @param {string} mode - The API PageMode value.\n * @returns {number} A value from {SidebarView}.\n */\nfunction apiPageModeToSidebarView(mode) {\n switch (mode) {\n case 'UseNone':\n return SidebarView.NONE;\n case 'UseThumbs':\n return SidebarView.THUMBS;\n case 'UseOutlines':\n return SidebarView.OUTLINE;\n case 'UseAttachments':\n return SidebarView.ATTACHMENTS;\n case 'UseOC':\n // Not implemented, since we don't support Optional Content Groups yet.\n }\n return SidebarView.NONE; // Default value.\n}\n\n/* Abstract factory for the print service. */\nlet PDFPrintServiceFactory = {\n instance: {\n supportsPrinting: false,\n createPrintService() {\n throw new Error('Not implemented: createPrintService');\n },\n },\n};\n\nexport {\n PDFViewerApplication,\n DefaultExternalServices,\n PDFPrintServiceFactory,\n};\n\n\n\n// WEBPACK FOOTER //\n// web/app.js","/* Copyright 2015 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getGlobalEventBus } from './dom_events';\nimport { parseQueryString } from './ui_utils';\n\n/**\n * @typedef {Object} PDFLinkServiceOptions\n * @property {EventBus} eventBus - The application event bus.\n */\n\n/**\n * Performs navigation functions inside PDF, such as opening specified page,\n * or destination.\n * @implements {IPDFLinkService}\n */\nclass PDFLinkService {\n /**\n * @param {PDFLinkServiceOptions} options\n */\n constructor({ eventBus, } = {}) {\n this.eventBus = eventBus || getGlobalEventBus();\n this.baseUrl = null;\n this.pdfDocument = null;\n this.pdfViewer = null;\n this.pdfHistory = null;\n\n this._pagesRefCache = null;\n }\n\n setDocument(pdfDocument, baseUrl) {\n this.baseUrl = baseUrl;\n this.pdfDocument = pdfDocument;\n this._pagesRefCache = Object.create(null);\n }\n\n setViewer(pdfViewer) {\n this.pdfViewer = pdfViewer;\n }\n\n setHistory(pdfHistory) {\n this.pdfHistory = pdfHistory;\n }\n\n /**\n * @returns {number}\n */\n get pagesCount() {\n return this.pdfDocument ? this.pdfDocument.numPages : 0;\n }\n\n /**\n * @returns {number}\n */\n get page() {\n return this.pdfViewer.currentPageNumber;\n }\n\n /**\n * @param {number} value\n */\n set page(value) {\n this.pdfViewer.currentPageNumber = value;\n }\n\n /**\n * @returns {number}\n */\n get rotation() {\n return this.pdfViewer.pagesRotation;\n }\n\n /**\n * @param {number} value\n */\n set rotation(value) {\n this.pdfViewer.pagesRotation = value;\n }\n\n /**\n * @param {string|Array} dest - The named, or explicit, PDF destination.\n */\n navigateTo(dest) {\n let goToDestination = ({ namedDest, explicitDest, }) => {\n // Dest array looks like that: \n let destRef = explicitDest[0], pageNumber;\n\n if (destRef instanceof Object) {\n pageNumber = this._cachedPageNumber(destRef);\n\n if (pageNumber === null) {\n // Fetch the page reference if it's not yet available. This could\n // only occur during loading, before all pages have been resolved.\n this.pdfDocument.getPageIndex(destRef).then((pageIndex) => {\n this.cachePageRef(pageIndex + 1, destRef);\n goToDestination({ namedDest, explicitDest, });\n }).catch(() => {\n console.error(`PDFLinkService.navigateTo: \"${destRef}\" is not ` +\n `a valid page reference, for dest=\"${dest}\".`);\n });\n return;\n }\n } else if (Number.isInteger(destRef)) {\n pageNumber = destRef + 1;\n } else {\n console.error(`PDFLinkService.navigateTo: \"${destRef}\" is not ` +\n `a valid destination reference, for dest=\"${dest}\".`);\n return;\n }\n if (!pageNumber || pageNumber < 1 || pageNumber > this.pagesCount) {\n console.error(`PDFLinkService.navigateTo: \"${pageNumber}\" is not ` +\n `a valid page number, for dest=\"${dest}\".`);\n return;\n }\n\n if (this.pdfHistory) {\n // Update the browser history before scrolling the new destination into\n // view, to be able to accurately capture the current document position.\n this.pdfHistory.pushCurrentPosition();\n this.pdfHistory.push({ namedDest, explicitDest, pageNumber, });\n }\n\n this.pdfViewer.scrollPageIntoView({\n pageNumber,\n destArray: explicitDest,\n });\n };\n\n new Promise((resolve, reject) => {\n if (typeof dest === 'string') {\n this.pdfDocument.getDestination(dest).then((destArray) => {\n resolve({\n namedDest: dest,\n explicitDest: destArray,\n });\n });\n return;\n }\n resolve({\n namedDest: '',\n explicitDest: dest,\n });\n }).then((data) => {\n if (!(data.explicitDest instanceof Array)) {\n console.error(`PDFLinkService.navigateTo: \"${data.explicitDest}\" is` +\n ` not a valid destination array, for dest=\"${dest}\".`);\n return;\n }\n goToDestination(data);\n });\n }\n\n /**\n * @param {string|Array} dest - The PDF destination object.\n * @returns {string} The hyperlink to the PDF object.\n */\n getDestinationHash(dest) {\n if (typeof dest === 'string') {\n return this.getAnchorUrl('#' + escape(dest));\n }\n if (dest instanceof Array) {\n let str = JSON.stringify(dest);\n return this.getAnchorUrl('#' + escape(str));\n }\n return this.getAnchorUrl('');\n }\n\n /**\n * Prefix the full url on anchor links to make sure that links are resolved\n * relative to the current URL instead of the one defined in .\n * @param {String} anchor The anchor hash, including the #.\n * @returns {string} The hyperlink to the PDF object.\n */\n getAnchorUrl(anchor) {\n return (this.baseUrl || '') + anchor;\n }\n\n /**\n * @param {string} hash\n */\n setHash(hash) {\n let pageNumber, dest;\n if (hash.indexOf('=') >= 0) {\n let params = parseQueryString(hash);\n if ('search' in params) {\n this.eventBus.dispatch('findfromurlhash', {\n source: this,\n query: params['search'].replace(/\"/g, ''),\n phraseSearch: (params['phrase'] === 'true'),\n });\n }\n // borrowing syntax from \"Parameters for Opening PDF Files\"\n if ('nameddest' in params) {\n this.navigateTo(params.nameddest);\n return;\n }\n if ('page' in params) {\n pageNumber = (params.page | 0) || 1;\n }\n if ('zoom' in params) {\n // Build the destination array.\n let zoomArgs = params.zoom.split(','); // scale,left,top\n let zoomArg = zoomArgs[0];\n let zoomArgNumber = parseFloat(zoomArg);\n\n if (zoomArg.indexOf('Fit') === -1) {\n // If the zoomArg is a number, it has to get divided by 100. If it's\n // a string, it should stay as it is.\n dest = [null, { name: 'XYZ', },\n zoomArgs.length > 1 ? (zoomArgs[1] | 0) : null,\n zoomArgs.length > 2 ? (zoomArgs[2] | 0) : null,\n (zoomArgNumber ? zoomArgNumber / 100 : zoomArg)];\n } else {\n if (zoomArg === 'Fit' || zoomArg === 'FitB') {\n dest = [null, { name: zoomArg, }];\n } else if ((zoomArg === 'FitH' || zoomArg === 'FitBH') ||\n (zoomArg === 'FitV' || zoomArg === 'FitBV')) {\n dest = [null, { name: zoomArg, },\n zoomArgs.length > 1 ? (zoomArgs[1] | 0) : null];\n } else if (zoomArg === 'FitR') {\n if (zoomArgs.length !== 5) {\n console.error(\n 'PDFLinkService.setHash: Not enough parameters for \"FitR\".');\n } else {\n dest = [null, { name: zoomArg, },\n (zoomArgs[1] | 0), (zoomArgs[2] | 0),\n (zoomArgs[3] | 0), (zoomArgs[4] | 0)];\n }\n } else {\n console.error(`PDFLinkService.setHash: \"${zoomArg}\" is not ` +\n 'a valid zoom value.');\n }\n }\n }\n if (dest) {\n this.pdfViewer.scrollPageIntoView({\n pageNumber: pageNumber || this.page,\n destArray: dest,\n allowNegativeOffset: true,\n });\n } else if (pageNumber) {\n this.page = pageNumber; // simple page\n }\n if ('pagemode' in params) {\n this.eventBus.dispatch('pagemode', {\n source: this,\n mode: params.pagemode,\n });\n }\n } else { // Named (or explicit) destination.\n if ((typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC')) &&\n /^\\d+$/.test(hash) && hash <= this.pagesCount) {\n console.warn('PDFLinkService_setHash: specifying a page number ' +\n 'directly after the hash symbol (#) is deprecated, ' +\n `please use the \"#page=${hash}\" form instead.`);\n this.page = hash | 0;\n }\n\n dest = unescape(hash);\n try {\n dest = JSON.parse(dest);\n\n if (!(dest instanceof Array)) {\n // Avoid incorrectly rejecting a valid named destination, such as\n // e.g. \"4.3\" or \"true\", because `JSON.parse` converted its type.\n dest = dest.toString();\n }\n } catch (ex) {}\n\n if (typeof dest === 'string' || isValidExplicitDestination(dest)) {\n this.navigateTo(dest);\n return;\n }\n console.error(`PDFLinkService.setHash: \"${unescape(hash)}\" is not ` +\n 'a valid destination.');\n }\n }\n\n /**\n * @param {string} action\n */\n executeNamedAction(action) {\n // See PDF reference, table 8.45 - Named action\n switch (action) {\n case 'GoBack':\n if (this.pdfHistory) {\n this.pdfHistory.back();\n }\n break;\n\n case 'GoForward':\n if (this.pdfHistory) {\n this.pdfHistory.forward();\n }\n break;\n\n case 'NextPage':\n if (this.page < this.pagesCount) {\n this.page++;\n }\n break;\n\n case 'PrevPage':\n if (this.page > 1) {\n this.page--;\n }\n break;\n\n case 'LastPage':\n this.page = this.pagesCount;\n break;\n\n case 'FirstPage':\n this.page = 1;\n break;\n\n default:\n break; // No action according to spec\n }\n\n this.eventBus.dispatch('namedaction', {\n source: this,\n action,\n });\n }\n\n /**\n * @param {Object} params\n */\n onFileAttachmentAnnotation({ id, filename, content, }) {\n this.eventBus.dispatch('fileattachmentannotation', {\n source: this,\n id,\n filename,\n content,\n });\n }\n\n /**\n * @param {number} pageNum - page number.\n * @param {Object} pageRef - reference to the page.\n */\n cachePageRef(pageNum, pageRef) {\n let refStr = pageRef.num + ' ' + pageRef.gen + ' R';\n this._pagesRefCache[refStr] = pageNum;\n }\n\n _cachedPageNumber(pageRef) {\n let refStr = pageRef.num + ' ' + pageRef.gen + ' R';\n return (this._pagesRefCache && this._pagesRefCache[refStr]) || null;\n }\n}\n\nfunction isValidExplicitDestination(dest) {\n if (!(dest instanceof Array)) {\n return false;\n }\n let destLength = dest.length, allowNull = true;\n if (destLength < 2) {\n return false;\n }\n let page = dest[0];\n if (!(typeof page === 'object' &&\n Number.isInteger(page.num) && Number.isInteger(page.gen)) &&\n !(Number.isInteger(page) && page >= 0)) {\n return false;\n }\n let zoom = dest[1];\n if (!(typeof zoom === 'object' && typeof zoom.name === 'string')) {\n return false;\n }\n switch (zoom.name) {\n case 'XYZ':\n if (destLength !== 5) {\n return false;\n }\n break;\n case 'Fit':\n case 'FitB':\n return destLength === 2;\n case 'FitH':\n case 'FitBH':\n case 'FitV':\n case 'FitBV':\n if (destLength !== 3) {\n return false;\n }\n break;\n case 'FitR':\n if (destLength !== 6) {\n return false;\n }\n allowNull = false;\n break;\n default:\n return false;\n }\n for (let i = 2; i < destLength; i++) {\n let param = dest[i];\n if (!(typeof param === 'number' || (allowNull && param === null))) {\n return false;\n }\n }\n return true;\n}\n\nclass SimpleLinkService {\n /**\n * @returns {number}\n */\n get page() {\n return 0;\n }\n /**\n * @param {number} value\n */\n set page(value) {}\n /**\n * @returns {number}\n */\n get rotation() {\n return 0;\n }\n /**\n * @param {number} value\n */\n set rotation(value) {}\n /**\n * @param dest - The PDF destination object.\n */\n navigateTo(dest) {}\n /**\n * @param dest - The PDF destination object.\n * @returns {string} The hyperlink to the PDF object.\n */\n getDestinationHash(dest) {\n return '#';\n }\n /**\n * @param hash - The PDF parameters/hash.\n * @returns {string} The hyperlink to the PDF object.\n */\n getAnchorUrl(hash) {\n return '#';\n }\n /**\n * @param {string} hash\n */\n setHash(hash) {}\n /**\n * @param {string} action\n */\n executeNamedAction(action) {}\n /**\n * @param {Object} params\n */\n onFileAttachmentAnnotation({ id, filename, content, }) {}\n /**\n * @param {number} pageNum - page number.\n * @param {Object} pageRef - reference to the page.\n */\n cachePageRef(pageNum, pageRef) {}\n}\n\nexport {\n PDFLinkService,\n SimpleLinkService,\n};\n\n\n\n// WEBPACK FOOTER //\n// web/pdf_link_service.js","/* Copyright 2017 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { GrabToPan } from './grab_to_pan';\n\nconst CursorTool = {\n SELECT: 0, // The default value.\n HAND: 1,\n ZOOM: 2,\n};\n\n/**\n * @typedef {Object} PDFCursorToolsOptions\n * @property {HTMLDivElement} container - The document container.\n * @property {EventBus} eventBus - The application event bus.\n * @property {BasePreferences} preferences - Object for reading/writing\n * persistent settings.\n */\n\nclass PDFCursorTools {\n /**\n * @param {PDFCursorToolsOptions} options\n */\n constructor({ container, eventBus, preferences, }) {\n this.container = container;\n this.eventBus = eventBus;\n\n this.active = CursorTool.SELECT;\n this.activeBeforePresentationMode = null;\n\n this.handTool = new GrabToPan({\n element: this.container,\n });\n\n this._addEventListeners();\n\n Promise.all([\n preferences.get('cursorToolOnLoad'),\n preferences.get('enableHandToolOnLoad')\n ]).then(([cursorToolPref, handToolPref]) => {\n // If the 'cursorToolOnLoad' preference has not been set to a non-default\n // value, attempt to convert the old 'enableHandToolOnLoad' preference.\n // TODO: Remove this conversion after a suitable number of releases.\n if (handToolPref === true) {\n preferences.set('enableHandToolOnLoad', false);\n\n if (cursorToolPref === CursorTool.SELECT) {\n cursorToolPref = CursorTool.HAND;\n preferences.set('cursorToolOnLoad', cursorToolPref).catch(() => { });\n }\n }\n this.switchTool(cursorToolPref);\n }).catch(() => { });\n }\n\n /**\n * @returns {number} One of the values in {CursorTool}.\n */\n get activeTool() {\n return this.active;\n }\n\n /**\n * NOTE: This method is ignored while Presentation Mode is active.\n * @param {number} tool - The cursor mode that should be switched to,\n * must be one of the values in {CursorTool}.\n */\n switchTool(tool) {\n if (this.activeBeforePresentationMode !== null) {\n return; // Cursor tools cannot be used in Presentation Mode.\n }\n if (tool === this.active) {\n return; // The requested tool is already active.\n }\n\n let disableActiveTool = () => {\n switch (this.active) {\n case CursorTool.SELECT:\n break;\n case CursorTool.HAND:\n this.handTool.deactivate();\n break;\n case CursorTool.ZOOM:\n /* falls through */\n }\n };\n\n switch (tool) { // Enable the new cursor tool.\n case CursorTool.SELECT:\n disableActiveTool();\n break;\n case CursorTool.HAND:\n disableActiveTool();\n this.handTool.activate();\n break;\n case CursorTool.ZOOM:\n /* falls through */\n default:\n console.error(`switchTool: \"${tool}\" is an unsupported value.`);\n return;\n }\n // Update the active tool *after* it has been validated above,\n // in order to prevent setting it to an invalid state.\n this.active = tool;\n\n this._dispatchEvent();\n }\n\n /**\n * @private\n */\n _dispatchEvent() {\n this.eventBus.dispatch('cursortoolchanged', {\n source: this,\n tool: this.active,\n });\n }\n\n /**\n * @private\n */\n _addEventListeners() {\n this.eventBus.on('switchcursortool', (evt) => {\n this.switchTool(evt.tool);\n });\n\n this.eventBus.on('presentationmodechanged', (evt) => {\n if (evt.switchInProgress) {\n return;\n }\n let previouslyActive;\n\n if (evt.active) {\n previouslyActive = this.active;\n\n this.switchTool(CursorTool.SELECT);\n this.activeBeforePresentationMode = previouslyActive;\n } else {\n previouslyActive = this.activeBeforePresentationMode;\n\n this.activeBeforePresentationMode = null;\n this.switchTool(previouslyActive);\n }\n });\n }\n}\n\nexport {\n CursorTool,\n PDFCursorTools,\n};\n\n\n\n// WEBPACK FOOTER //\n// web/pdf_cursor_tools.js","/* Copyright 2012 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { createPromiseCapability } from 'pdfjs-lib';\nimport { scrollIntoView } from './ui_utils';\n\nconst FindState = {\n FOUND: 0,\n NOT_FOUND: 1,\n WRAPPED: 2,\n PENDING: 3,\n};\n\nconst FIND_SCROLL_OFFSET_TOP = -50;\nconst FIND_SCROLL_OFFSET_LEFT = -400;\nconst FIND_TIMEOUT = 250; // ms\n\nconst CHARACTERS_TO_NORMALIZE = {\n '\\u2018': '\\'', // Left single quotation mark\n '\\u2019': '\\'', // Right single quotation mark\n '\\u201A': '\\'', // Single low-9 quotation mark\n '\\u201B': '\\'', // Single high-reversed-9 quotation mark\n '\\u201C': '\"', // Left double quotation mark\n '\\u201D': '\"', // Right double quotation mark\n '\\u201E': '\"', // Double low-9 quotation mark\n '\\u201F': '\"', // Double high-reversed-9 quotation mark\n '\\u00BC': '1/4', // Vulgar fraction one quarter\n '\\u00BD': '1/2', // Vulgar fraction one half\n '\\u00BE': '3/4', // Vulgar fraction three quarters\n};\n\n/**\n * Provides search functionality to find a given string in a PDF document.\n */\nclass PDFFindController {\n constructor({ pdfViewer, }) {\n this.pdfViewer = pdfViewer;\n\n this.onUpdateResultsCount = null;\n this.onUpdateState = null;\n\n this.reset();\n\n // Compile the regular expression for text normalization once.\n let replace = Object.keys(CHARACTERS_TO_NORMALIZE).join('');\n this.normalizationRegex = new RegExp('[' + replace + ']', 'g');\n }\n\n reset() {\n this.startedTextExtraction = false;\n this.extractTextPromises = [];\n this.pendingFindMatches = Object.create(null);\n this.active = false; // If active, find results will be highlighted.\n this.pageContents = []; // Stores the text for each page.\n this.pageMatches = [];\n this.pageMatchesLength = null;\n this.matchCount = 0;\n this.selected = { // Currently selected match.\n pageIdx: -1,\n matchIdx: -1,\n };\n this.offset = { // Where the find algorithm currently is in the document.\n pageIdx: null,\n matchIdx: null,\n };\n this.pagesToSearch = null;\n this.resumePageIdx = null;\n this.state = null;\n this.dirtyMatch = false;\n this.findTimeout = null;\n\n this._firstPagePromise = new Promise((resolve) => {\n this.resolveFirstPage = resolve;\n });\n }\n\n normalize(text) {\n return text.replace(this.normalizationRegex, function (ch) {\n return CHARACTERS_TO_NORMALIZE[ch];\n });\n }\n\n /**\n * Helper for multi-term search that fills the `matchesWithLength` array\n * and handles cases where one search term includes another search term (for\n * example, \"tamed tame\" or \"this is\"). It looks for intersecting terms in\n * the `matches` and keeps elements with a longer match length.\n */\n _prepareMatches(matchesWithLength, matches, matchesLength) {\n function isSubTerm(matchesWithLength, currentIndex) {\n let currentElem = matchesWithLength[currentIndex];\n let nextElem = matchesWithLength[currentIndex + 1];\n\n // Check for cases like \"TAMEd TAME\".\n if (currentIndex < matchesWithLength.length - 1 &&\n currentElem.match === nextElem.match) {\n currentElem.skipped = true;\n return true;\n }\n\n // Check for cases like \"thIS IS\".\n for (let i = currentIndex - 1; i >= 0; i--) {\n let prevElem = matchesWithLength[i];\n if (prevElem.skipped) {\n continue;\n }\n if (prevElem.match + prevElem.matchLength < currentElem.match) {\n break;\n }\n if (prevElem.match + prevElem.matchLength >=\n currentElem.match + currentElem.matchLength) {\n currentElem.skipped = true;\n return true;\n }\n }\n return false;\n }\n\n // Sort the array of `{ match: , matchLength: }`\n // objects on increasing index first and on the length otherwise.\n matchesWithLength.sort(function(a, b) {\n return a.match === b.match ? a.matchLength - b.matchLength :\n a.match - b.match;\n });\n for (let i = 0, len = matchesWithLength.length; i < len; i++) {\n if (isSubTerm(matchesWithLength, i)) {\n continue;\n }\n matches.push(matchesWithLength[i].match);\n matchesLength.push(matchesWithLength[i].matchLength);\n }\n }\n\n calcFindPhraseMatch(query, pageIndex, pageContent) {\n let matches = [];\n let queryLen = query.length;\n let matchIdx = -queryLen;\n while (true) {\n matchIdx = pageContent.indexOf(query, matchIdx + queryLen);\n if (matchIdx === -1) {\n break;\n }\n matches.push(matchIdx);\n }\n this.pageMatches[pageIndex] = matches;\n }\n\n calcFindWordMatch(query, pageIndex, pageContent) {\n let matchesWithLength = [];\n // Divide the query into pieces and search for text in each piece.\n let queryArray = query.match(/\\S+/g);\n for (let i = 0, len = queryArray.length; i < len; i++) {\n let subquery = queryArray[i];\n let subqueryLen = subquery.length;\n let matchIdx = -subqueryLen;\n while (true) {\n matchIdx = pageContent.indexOf(subquery, matchIdx + subqueryLen);\n if (matchIdx === -1) {\n break;\n }\n // Other searches do not, so we store the length.\n matchesWithLength.push({\n match: matchIdx,\n matchLength: subqueryLen,\n skipped: false,\n });\n }\n }\n\n // Prepare arrays for storing the matches.\n if (!this.pageMatchesLength) {\n this.pageMatchesLength = [];\n }\n this.pageMatchesLength[pageIndex] = [];\n this.pageMatches[pageIndex] = [];\n\n // Sort `matchesWithLength`, remove intersecting terms and put the result\n // into the two arrays.\n this._prepareMatches(matchesWithLength, this.pageMatches[pageIndex],\n this.pageMatchesLength[pageIndex]);\n }\n\n calcFindMatch(pageIndex) {\n let pageContent = this.normalize(this.pageContents[pageIndex]);\n let query = this.normalize(this.state.query);\n let caseSensitive = this.state.caseSensitive;\n let phraseSearch = this.state.phraseSearch;\n let queryLen = query.length;\n\n if (queryLen === 0) {\n // Do nothing: the matches should be wiped out already.\n return;\n }\n\n if (!caseSensitive) {\n pageContent = pageContent.toLowerCase();\n query = query.toLowerCase();\n }\n\n if (phraseSearch) {\n this.calcFindPhraseMatch(query, pageIndex, pageContent);\n } else {\n this.calcFindWordMatch(query, pageIndex, pageContent);\n }\n\n this.updatePage(pageIndex);\n if (this.resumePageIdx === pageIndex) {\n this.resumePageIdx = null;\n this.nextPageMatch();\n }\n\n // Update the match count.\n if (this.pageMatches[pageIndex].length > 0) {\n this.matchCount += this.pageMatches[pageIndex].length;\n this.updateUIResultsCount();\n }\n }\n\n extractText() {\n if (this.startedTextExtraction) {\n return;\n }\n this.startedTextExtraction = true;\n this.pageContents.length = 0;\n\n let promise = Promise.resolve();\n for (let i = 0, ii = this.pdfViewer.pagesCount; i < ii; i++) {\n let extractTextCapability = createPromiseCapability();\n this.extractTextPromises[i] = extractTextCapability.promise;\n\n promise = promise.then(() => {\n return this.pdfViewer.getPageTextContent(i).then((textContent) => {\n let textItems = textContent.items;\n let strBuf = [];\n\n for (let j = 0, jj = textItems.length; j < jj; j++) {\n strBuf.push(textItems[j].str);\n }\n // Store the pageContent as a string.\n this.pageContents[i] = strBuf.join('');\n extractTextCapability.resolve(i);\n }, (reason) => {\n console.error(`Unable to get page ${i + 1} text content`, reason);\n // Page error -- assuming no text content.\n this.pageContents[i] = '';\n extractTextCapability.resolve(i);\n });\n });\n }\n }\n\n executeCommand(cmd, state) {\n if (this.state === null || cmd !== 'findagain') {\n this.dirtyMatch = true;\n }\n this.state = state;\n this.updateUIState(FindState.PENDING);\n\n this._firstPagePromise.then(() => {\n this.extractText();\n\n clearTimeout(this.findTimeout);\n if (cmd === 'find') {\n // Trigger the find action with a small delay to avoid starting the\n // search when the user is still typing (saving resources).\n this.findTimeout = setTimeout(this.nextMatch.bind(this), FIND_TIMEOUT);\n } else {\n this.nextMatch();\n }\n });\n }\n\n updatePage(index) {\n if (this.selected.pageIdx === index) {\n // If the page is selected, scroll the page into view, which triggers\n // rendering the page, which adds the textLayer. Once the textLayer is\n // build, it will scroll onto the selected match.\n this.pdfViewer.currentPageNumber = index + 1;\n }\n\n let page = this.pdfViewer.getPageView(index);\n if (page.textLayer) {\n page.textLayer.updateMatches();\n }\n }\n\n nextMatch() {\n let previous = this.state.findPrevious;\n let currentPageIndex = this.pdfViewer.currentPageNumber - 1;\n let numPages = this.pdfViewer.pagesCount;\n\n this.active = true;\n\n if (this.dirtyMatch) {\n // Need to recalculate the matches, reset everything.\n this.dirtyMatch = false;\n this.selected.pageIdx = this.selected.matchIdx = -1;\n this.offset.pageIdx = currentPageIndex;\n this.offset.matchIdx = null;\n this.hadMatch = false;\n this.resumePageIdx = null;\n this.pageMatches = [];\n this.matchCount = 0;\n this.pageMatchesLength = null;\n\n for (let i = 0; i < numPages; i++) {\n // Wipe out any previously highlighted matches.\n this.updatePage(i);\n\n // Start finding the matches as soon as the text is extracted.\n if (!(i in this.pendingFindMatches)) {\n this.pendingFindMatches[i] = true;\n this.extractTextPromises[i].then((pageIdx) => {\n delete this.pendingFindMatches[pageIdx];\n this.calcFindMatch(pageIdx);\n });\n }\n }\n }\n\n // If there's no query there's no point in searching.\n if (this.state.query === '') {\n this.updateUIState(FindState.FOUND);\n return;\n }\n\n // If we're waiting on a page, we return since we can't do anything else.\n if (this.resumePageIdx) {\n return;\n }\n\n let offset = this.offset;\n // Keep track of how many pages we should maximally iterate through.\n this.pagesToSearch = numPages;\n // If there's already a `matchIdx` that means we are iterating through a\n // page's matches.\n if (offset.matchIdx !== null) {\n let numPageMatches = this.pageMatches[offset.pageIdx].length;\n if ((!previous && offset.matchIdx + 1 < numPageMatches) ||\n (previous && offset.matchIdx > 0)) {\n // The simple case; we just have advance the matchIdx to select\n // the next match on the page.\n this.hadMatch = true;\n offset.matchIdx = (previous ? offset.matchIdx - 1 :\n offset.matchIdx + 1);\n this.updateMatch(true);\n return;\n }\n // We went beyond the current page's matches, so we advance to\n // the next page.\n this.advanceOffsetPage(previous);\n }\n // Start searching through the page.\n this.nextPageMatch();\n }\n\n matchesReady(matches) {\n let offset = this.offset;\n let numMatches = matches.length;\n let previous = this.state.findPrevious;\n\n if (numMatches) {\n // There were matches for the page, so initialize `matchIdx`.\n this.hadMatch = true;\n offset.matchIdx = (previous ? numMatches - 1 : 0);\n this.updateMatch(true);\n return true;\n }\n // No matches, so attempt to search the next page.\n this.advanceOffsetPage(previous);\n if (offset.wrapped) {\n offset.matchIdx = null;\n if (this.pagesToSearch < 0) {\n // No point in wrapping again, there were no matches.\n this.updateMatch(false);\n // While matches were not found, searching for a page\n // with matches should nevertheless halt.\n return true;\n }\n }\n // Matches were not found (and searching is not done).\n return false;\n }\n\n /**\n * Called from the text layer when match presentation is updated.\n *\n * @param {number} pageIndex - The index of the page.\n * @param {number} matchIndex - The index of the match.\n * @param {Array} elements - Text layer `div` elements.\n * @param {number} beginIdx - Start index of the `div` array for the match.\n */\n updateMatchPosition(pageIndex, matchIndex, elements, beginIdx) {\n if (this.selected.matchIdx === matchIndex &&\n this.selected.pageIdx === pageIndex) {\n let spot = {\n top: FIND_SCROLL_OFFSET_TOP,\n left: FIND_SCROLL_OFFSET_LEFT,\n };\n scrollIntoView(elements[beginIdx], spot,\n /* skipOverflowHiddenElements = */ true);\n }\n }\n\n nextPageMatch() {\n if (this.resumePageIdx !== null) {\n console.error('There can only be one pending page.');\n }\n\n let matches = null;\n do {\n let pageIdx = this.offset.pageIdx;\n matches = this.pageMatches[pageIdx];\n if (!matches) {\n // The matches don't exist yet for processing by `matchesReady`,\n // so set a resume point for when they do exist.\n this.resumePageIdx = pageIdx;\n break;\n }\n } while (!this.matchesReady(matches));\n }\n\n advanceOffsetPage(previous) {\n let offset = this.offset;\n let numPages = this.extractTextPromises.length;\n offset.pageIdx = (previous ? offset.pageIdx - 1 : offset.pageIdx + 1);\n offset.matchIdx = null;\n\n this.pagesToSearch--;\n\n if (offset.pageIdx >= numPages || offset.pageIdx < 0) {\n offset.pageIdx = (previous ? numPages - 1 : 0);\n offset.wrapped = true;\n }\n }\n\n updateMatch(found = false) {\n let state = FindState.NOT_FOUND;\n let wrapped = this.offset.wrapped;\n this.offset.wrapped = false;\n\n if (found) {\n let previousPage = this.selected.pageIdx;\n this.selected.pageIdx = this.offset.pageIdx;\n this.selected.matchIdx = this.offset.matchIdx;\n state = (wrapped ? FindState.WRAPPED : FindState.FOUND);\n\n // Update the currently selected page to wipe out any selected matches.\n if (previousPage !== -1 && previousPage !== this.selected.pageIdx) {\n this.updatePage(previousPage);\n }\n }\n\n this.updateUIState(state, this.state.findPrevious);\n if (this.selected.pageIdx !== -1) {\n this.updatePage(this.selected.pageIdx);\n }\n }\n\n updateUIResultsCount() {\n if (this.onUpdateResultsCount) {\n this.onUpdateResultsCount(this.matchCount);\n }\n }\n\n updateUIState(state, previous) {\n if (this.onUpdateState) {\n this.onUpdateState(state, previous, this.matchCount);\n }\n }\n}\n\nexport {\n FindState,\n PDFFindController,\n};\n\n\n\n// WEBPACK FOOTER //\n// web/pdf_find_controller.js","/* Copyright 2016 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/* globals chrome */\n\n'use strict';\n\nlet DEFAULT_URL = 'compressed.tracemonkey-pldi-09.pdf';\n\nif (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('CHROME')) {\n (function rewriteUrlClosure() {\n // Run this code outside DOMContentLoaded to make sure that the URL\n // is rewritten as soon as possible.\n let queryString = document.location.search.slice(1);\n let m = /(^|&)file=([^&]*)/.exec(queryString);\n DEFAULT_URL = m ? decodeURIComponent(m[2]) : '';\n\n // Example: chrome-extension://.../http://example.com/file.pdf\n let humanReadableUrl = '/' + DEFAULT_URL + location.hash;\n history.replaceState(history.state, '', humanReadableUrl);\n if (top === window) {\n chrome.runtime.sendMessage('showPageAction');\n }\n })();\n}\n\nlet pdfjsWebApp;\nif (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('PRODUCTION')) {\n pdfjsWebApp = require('./app.js');\n}\n\nif (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('FIREFOX || MOZCENTRAL')) {\n require('./firefoxcom.js');\n require('./firefox_print_service.js');\n}\nif (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('GENERIC')) {\n require('./genericcom.js');\n}\nif (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('CHROME')) {\n require('./chromecom.js');\n}\nif (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('CHROME || GENERIC')) {\n require('./pdf_print_service.js');\n}\n\nfunction getViewerConfiguration() {\n return {\n appContainer: document.body,\n mainContainer: document.getElementById('viewerContainer'),\n viewerContainer: document.getElementById('viewer'),\n eventBus: null, // using global event bus with DOM events\n toolbar: {\n container: document.getElementById('toolbarViewer'),\n numPages: document.getElementById('numPages'),\n pageNumber: document.getElementById('pageNumber'),\n scaleSelectContainer: document.getElementById('scaleSelectContainer'),\n scaleSelect: document.getElementById('scaleSelect'),\n customScaleOption: document.getElementById('customScaleOption'),\n previous: document.getElementById('previous'),\n next: document.getElementById('next'),\n zoomIn: document.getElementById('zoomIn'),\n zoomOut: document.getElementById('zoomOut'),\n viewFind: document.getElementById('viewFind'),\n openFile: document.getElementById('openFile'),\n print: document.getElementById('print'),\n presentationModeButton: document.getElementById('presentationMode'),\n download: document.getElementById('download'),\n viewBookmark: document.getElementById('viewBookmark'),\n },\n secondaryToolbar: {\n toolbar: document.getElementById('secondaryToolbar'),\n toggleButton: document.getElementById('secondaryToolbarToggle'),\n toolbarButtonContainer:\n document.getElementById('secondaryToolbarButtonContainer'),\n presentationModeButton:\n document.getElementById('secondaryPresentationMode'),\n openFileButton: document.getElementById('secondaryOpenFile'),\n printButton: document.getElementById('secondaryPrint'),\n downloadButton: document.getElementById('secondaryDownload'),\n viewBookmarkButton: document.getElementById('secondaryViewBookmark'),\n firstPageButton: document.getElementById('firstPage'),\n lastPageButton: document.getElementById('lastPage'),\n pageRotateCwButton: document.getElementById('pageRotateCw'),\n pageRotateCcwButton: document.getElementById('pageRotateCcw'),\n cursorSelectToolButton: document.getElementById('cursorSelectTool'),\n cursorHandToolButton: document.getElementById('cursorHandTool'),\n documentPropertiesButton: document.getElementById('documentProperties'),\n },\n fullscreen: {\n contextFirstPage: document.getElementById('contextFirstPage'),\n contextLastPage: document.getElementById('contextLastPage'),\n contextPageRotateCw: document.getElementById('contextPageRotateCw'),\n contextPageRotateCcw: document.getElementById('contextPageRotateCcw'),\n },\n sidebar: {\n // Divs (and sidebar button)\n mainContainer: document.getElementById('mainContainer'),\n outerContainer: document.getElementById('outerContainer'),\n toggleButton: document.getElementById('sidebarToggle'),\n // Buttons\n thumbnailButton: document.getElementById('viewThumbnail'),\n outlineButton: document.getElementById('viewOutline'),\n attachmentsButton: document.getElementById('viewAttachments'),\n // Views\n thumbnailView: document.getElementById('thumbnailView'),\n outlineView: document.getElementById('outlineView'),\n attachmentsView: document.getElementById('attachmentsView'),\n },\n findBar: {\n bar: document.getElementById('findbar'),\n toggleButton: document.getElementById('viewFind'),\n findField: document.getElementById('findInput'),\n highlightAllCheckbox: document.getElementById('findHighlightAll'),\n caseSensitiveCheckbox: document.getElementById('findMatchCase'),\n findMsg: document.getElementById('findMsg'),\n findResultsCount: document.getElementById('findResultsCount'),\n findStatusIcon: document.getElementById('findStatusIcon'),\n findPreviousButton: document.getElementById('findPrevious'),\n findNextButton: document.getElementById('findNext'),\n },\n passwordOverlay: {\n overlayName: 'passwordOverlay',\n container: document.getElementById('passwordOverlay'),\n label: document.getElementById('passwordText'),\n input: document.getElementById('password'),\n submitButton: document.getElementById('passwordSubmit'),\n cancelButton: document.getElementById('passwordCancel'),\n },\n documentProperties: {\n overlayName: 'documentPropertiesOverlay',\n container: document.getElementById('documentPropertiesOverlay'),\n closeButton: document.getElementById('documentPropertiesClose'),\n fields: {\n 'fileName': document.getElementById('fileNameField'),\n 'fileSize': document.getElementById('fileSizeField'),\n 'title': document.getElementById('titleField'),\n 'author': document.getElementById('authorField'),\n 'subject': document.getElementById('subjectField'),\n 'keywords': document.getElementById('keywordsField'),\n 'creationDate': document.getElementById('creationDateField'),\n 'modificationDate': document.getElementById('modificationDateField'),\n 'creator': document.getElementById('creatorField'),\n 'producer': document.getElementById('producerField'),\n 'version': document.getElementById('versionField'),\n 'pageCount': document.getElementById('pageCountField'),\n },\n },\n errorWrapper: {\n container: document.getElementById('errorWrapper'),\n errorMessage: document.getElementById('errorMessage'),\n closeButton: document.getElementById('errorClose'),\n errorMoreInfo: document.getElementById('errorMoreInfo'),\n moreInfoButton: document.getElementById('errorShowMore'),\n lessInfoButton: document.getElementById('errorShowLess'),\n },\n printContainer: document.getElementById('printContainer'),\n openFileInputName: 'fileInput',\n debuggerScriptPath: './debugger.js',\n defaultUrl: DEFAULT_URL,\n };\n}\n\nfunction webViewerLoad() {\n let config = getViewerConfiguration();\n if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('PRODUCTION')) {\n Promise.all([\n SystemJS.import('pdfjs-web/app'),\n SystemJS.import('pdfjs-web/genericcom'),\n SystemJS.import('pdfjs-web/pdf_print_service'),\n ]).then(function([app, ...otherModules]) {\n window.PDFViewerApplication = app.PDFViewerApplication;\n app.PDFViewerApplication.run(config);\n });\n } else {\n window.PDFViewerApplication = pdfjsWebApp.PDFViewerApplication;\n pdfjsWebApp.PDFViewerApplication.run(config);\n }\n}\n\nif (document.readyState === 'interactive' ||\n document.readyState === 'complete') {\n webViewerLoad();\n} else {\n document.addEventListener('DOMContentLoaded', webViewerLoad, true);\n}\n\n\n\n// WEBPACK FOOTER //\n// web/viewer.js","/* Copyright 2013 Rob Wu \n * https://github.com/Rob--W/grab-to-pan.js\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Construct a GrabToPan instance for a given HTML element.\n * @param options.element {Element}\n * @param options.ignoreTarget {function} optional. See `ignoreTarget(node)`\n * @param options.onActiveChanged {function(boolean)} optional. Called\n * when grab-to-pan is (de)activated. The first argument is a boolean that\n * shows whether grab-to-pan is activated.\n */\nfunction GrabToPan(options) {\n this.element = options.element;\n this.document = options.element.ownerDocument;\n if (typeof options.ignoreTarget === 'function') {\n this.ignoreTarget = options.ignoreTarget;\n }\n this.onActiveChanged = options.onActiveChanged;\n\n // Bind the contexts to ensure that `this` always points to\n // the GrabToPan instance.\n this.activate = this.activate.bind(this);\n this.deactivate = this.deactivate.bind(this);\n this.toggle = this.toggle.bind(this);\n this._onmousedown = this._onmousedown.bind(this);\n this._onmousemove = this._onmousemove.bind(this);\n this._endPan = this._endPan.bind(this);\n\n // This overlay will be inserted in the document when the mouse moves during\n // a grab operation, to ensure that the cursor has the desired appearance.\n var overlay = this.overlay = document.createElement('div');\n overlay.className = 'grab-to-pan-grabbing';\n}\nGrabToPan.prototype = {\n /**\n * Class name of element which can be grabbed\n */\n CSS_CLASS_GRAB: 'grab-to-pan-grab',\n\n /**\n * Bind a mousedown event to the element to enable grab-detection.\n */\n activate: function GrabToPan_activate() {\n if (!this.active) {\n this.active = true;\n this.element.addEventListener('mousedown', this._onmousedown, true);\n this.element.classList.add(this.CSS_CLASS_GRAB);\n if (this.onActiveChanged) {\n this.onActiveChanged(true);\n }\n }\n },\n\n /**\n * Removes all events. Any pending pan session is immediately stopped.\n */\n deactivate: function GrabToPan_deactivate() {\n if (this.active) {\n this.active = false;\n this.element.removeEventListener('mousedown', this._onmousedown, true);\n this._endPan();\n this.element.classList.remove(this.CSS_CLASS_GRAB);\n if (this.onActiveChanged) {\n this.onActiveChanged(false);\n }\n }\n },\n\n toggle: function GrabToPan_toggle() {\n if (this.active) {\n this.deactivate();\n } else {\n this.activate();\n }\n },\n\n /**\n * Whether to not pan if the target element is clicked.\n * Override this method to change the default behaviour.\n *\n * @param node {Element} The target of the event\n * @return {boolean} Whether to not react to the click event.\n */\n ignoreTarget: function GrabToPan_ignoreTarget(node) {\n // Use matchesSelector to check whether the clicked element\n // is (a child of) an input element / link\n return node[matchesSelector](\n 'a[href], a[href] *, input, textarea, button, button *, select, option'\n );\n },\n\n /**\n * @private\n */\n _onmousedown: function GrabToPan__onmousedown(event) {\n if (event.button !== 0 || this.ignoreTarget(event.target)) {\n return;\n }\n if (event.originalTarget) {\n try {\n // eslint-disable-next-line no-unused-expressions\n event.originalTarget.tagName;\n } catch (e) {\n // Mozilla-specific: element is a scrollbar (XUL element)\n return;\n }\n }\n\n this.scrollLeftStart = this.element.scrollLeft;\n this.scrollTopStart = this.element.scrollTop;\n this.clientXStart = event.clientX;\n this.clientYStart = event.clientY;\n this.document.addEventListener('mousemove', this._onmousemove, true);\n this.document.addEventListener('mouseup', this._endPan, true);\n // When a scroll event occurs before a mousemove, assume that the user\n // dragged a scrollbar (necessary for Opera Presto, Safari and IE)\n // (not needed for Chrome/Firefox)\n this.element.addEventListener('scroll', this._endPan, true);\n event.preventDefault();\n event.stopPropagation();\n\n var focusedElement = document.activeElement;\n if (focusedElement && !focusedElement.contains(event.target)) {\n focusedElement.blur();\n }\n },\n\n /**\n * @private\n */\n _onmousemove: function GrabToPan__onmousemove(event) {\n this.element.removeEventListener('scroll', this._endPan, true);\n if (isLeftMouseReleased(event)) {\n this._endPan();\n return;\n }\n var xDiff = event.clientX - this.clientXStart;\n var yDiff = event.clientY - this.clientYStart;\n var scrollTop = this.scrollTopStart - yDiff;\n var scrollLeft = this.scrollLeftStart - xDiff;\n if (this.element.scrollTo) {\n this.element.scrollTo({\n top: scrollTop,\n left: scrollLeft,\n behavior: 'instant',\n });\n } else {\n this.element.scrollTop = scrollTop;\n this.element.scrollLeft = scrollLeft;\n }\n if (!this.overlay.parentNode) {\n document.body.appendChild(this.overlay);\n }\n },\n\n /**\n * @private\n */\n _endPan: function GrabToPan__endPan() {\n this.element.removeEventListener('scroll', this._endPan, true);\n this.document.removeEventListener('mousemove', this._onmousemove, true);\n this.document.removeEventListener('mouseup', this._endPan, true);\n // Note: ChildNode.remove doesn't throw if the parentNode is undefined.\n this.overlay.remove();\n },\n};\n\n// Get the correct (vendor-prefixed) name of the matches method.\nvar matchesSelector;\n['webkitM', 'mozM', 'msM', 'oM', 'm'].some(function(prefix) {\n var name = prefix + 'atches';\n if (name in document.documentElement) {\n matchesSelector = name;\n }\n name += 'Selector';\n if (name in document.documentElement) {\n matchesSelector = name;\n }\n return matchesSelector; // If found, then truthy, and [].some() ends.\n});\n\n// Browser sniffing because it's impossible to feature-detect\n// whether event.which for onmousemove is reliable\nvar isNotIEorIsIE10plus = !document.documentMode || document.documentMode > 9;\nvar chrome = window.chrome;\nvar isChrome15OrOpera15plus = chrome && (chrome.webstore || chrome.app);\n// ^ Chrome 15+ ^ Opera 15+\nvar isSafari6plus = /Apple/.test(navigator.vendor) &&\n /Version\\/([6-9]\\d*|[1-5]\\d+)/.test(navigator.userAgent);\n\n/**\n * Whether the left mouse is not pressed.\n * @param event {MouseEvent}\n * @return {boolean} True if the left mouse button is not pressed.\n * False if unsure or if the left mouse button is pressed.\n */\nfunction isLeftMouseReleased(event) {\n if ('buttons' in event && isNotIEorIsIE10plus) {\n // http://www.w3.org/TR/DOM-Level-3-Events/#events-MouseEvent-buttons\n // Firefox 15+\n // Internet Explorer 10+\n return !(event.buttons & 1);\n }\n if (isChrome15OrOpera15plus || isSafari6plus) {\n // Chrome 14+\n // Opera 15+\n // Safari 6.0+\n return event.which === 0;\n }\n}\n\nexport {\n GrabToPan,\n};\n\n\n\n// WEBPACK FOOTER //\n// web/grab_to_pan.js","/* Copyright 2016 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { NullL10n } from './ui_utils';\nimport { RenderingStates } from './pdf_rendering_queue';\n\nconst UI_NOTIFICATION_CLASS = 'pdfSidebarNotification';\n\nconst SidebarView = {\n NONE: 0,\n THUMBS: 1,\n OUTLINE: 2,\n ATTACHMENTS: 3,\n};\n\n/**\n * @typedef {Object} PDFSidebarOptions\n * @property {PDFViewer} pdfViewer - The document viewer.\n * @property {PDFThumbnailViewer} pdfThumbnailViewer - The thumbnail viewer.\n * @property {PDFOutlineViewer} pdfOutlineViewer - The outline viewer.\n * @property {HTMLDivElement} mainContainer - The main container\n * (in which the viewer element is placed).\n * @property {HTMLDivElement} outerContainer - The outer container\n * (encasing both the viewer and sidebar elements).\n * @property {EventBus} eventBus - The application event bus.\n * @property {HTMLButtonElement} toggleButton - The button used for\n * opening/closing the sidebar.\n * @property {HTMLButtonElement} thumbnailButton - The button used to show\n * the thumbnail view.\n * @property {HTMLButtonElement} outlineButton - The button used to show\n * the outline view.\n * @property {HTMLButtonElement} attachmentsButton - The button used to show\n * the attachments view.\n * @property {HTMLDivElement} thumbnailView - The container in which\n * the thumbnails are placed.\n * @property {HTMLDivElement} outlineView - The container in which\n * the outline is placed.\n * @property {HTMLDivElement} attachmentsView - The container in which\n * the attachments are placed.\n * @property {boolean} disableNotification - (optional) Disable the notification\n * for documents containing outline/attachments. The default value is `false`.\n */\n\nclass PDFSidebar {\n /**\n * @param {PDFSidebarOptions} options\n * @param {IL10n} l10n - Localization service.\n */\n constructor(options, l10n = NullL10n) {\n this.isOpen = false;\n this.active = SidebarView.THUMBS;\n this.isInitialViewSet = false;\n\n /**\n * Callback used when the sidebar has been opened/closed, to ensure that\n * the viewers (PDFViewer/PDFThumbnailViewer) are updated correctly.\n */\n this.onToggled = null;\n\n this.pdfViewer = options.pdfViewer;\n this.pdfThumbnailViewer = options.pdfThumbnailViewer;\n this.pdfOutlineViewer = options.pdfOutlineViewer;\n\n this.mainContainer = options.mainContainer;\n this.outerContainer = options.outerContainer;\n this.eventBus = options.eventBus;\n this.toggleButton = options.toggleButton;\n\n this.thumbnailButton = options.thumbnailButton;\n this.outlineButton = options.outlineButton;\n this.attachmentsButton = options.attachmentsButton;\n\n this.thumbnailView = options.thumbnailView;\n this.outlineView = options.outlineView;\n this.attachmentsView = options.attachmentsView;\n\n this.disableNotification = options.disableNotification || false;\n\n this.l10n = l10n;\n\n this._addEventListeners();\n }\n\n reset() {\n this.isInitialViewSet = false;\n\n this._hideUINotification(null);\n this.switchView(SidebarView.THUMBS);\n\n this.outlineButton.disabled = false;\n this.attachmentsButton.disabled = false;\n }\n\n /**\n * @returns {number} One of the values in {SidebarView}.\n */\n get visibleView() {\n return (this.isOpen ? this.active : SidebarView.NONE);\n }\n\n get isThumbnailViewVisible() {\n return (this.isOpen && this.active === SidebarView.THUMBS);\n }\n\n get isOutlineViewVisible() {\n return (this.isOpen && this.active === SidebarView.OUTLINE);\n }\n\n get isAttachmentsViewVisible() {\n return (this.isOpen && this.active === SidebarView.ATTACHMENTS);\n }\n\n /**\n * @param {number} view - The sidebar view that should become visible,\n * must be one of the values in {SidebarView}.\n */\n setInitialView(view = SidebarView.NONE) {\n if (this.isInitialViewSet) {\n return;\n }\n this.isInitialViewSet = true;\n\n if (this.isOpen && view === SidebarView.NONE) {\n this._dispatchEvent();\n // If the user has already manually opened the sidebar,\n // immediately closing it would be bad UX.\n return;\n }\n let isViewPreserved = (view === this.visibleView);\n this.switchView(view, /* forceOpen */ true);\n\n if (isViewPreserved) {\n // Prevent dispatching two back-to-back `sidebarviewchanged` events,\n // since `this.switchView` dispatched the event if the view changed.\n this._dispatchEvent();\n }\n }\n\n /**\n * @param {number} view - The sidebar view that should be switched to,\n * must be one of the values in {SidebarView}.\n * @param {boolean} forceOpen - (optional) Ensure that the sidebar is open.\n * The default value is `false`.\n */\n switchView(view, forceOpen = false) {\n if (view === SidebarView.NONE) {\n this.close();\n return;\n }\n let isViewChanged = (view !== this.active);\n let shouldForceRendering = false;\n\n switch (view) {\n case SidebarView.THUMBS:\n this.thumbnailButton.classList.add('toggled');\n this.outlineButton.classList.remove('toggled');\n this.attachmentsButton.classList.remove('toggled');\n\n this.thumbnailView.classList.remove('hidden');\n this.outlineView.classList.add('hidden');\n this.attachmentsView.classList.add('hidden');\n\n if (this.isOpen && isViewChanged) {\n this._updateThumbnailViewer();\n shouldForceRendering = true;\n }\n break;\n case SidebarView.OUTLINE:\n if (this.outlineButton.disabled) {\n return;\n }\n this.thumbnailButton.classList.remove('toggled');\n this.outlineButton.classList.add('toggled');\n this.attachmentsButton.classList.remove('toggled');\n\n this.thumbnailView.classList.add('hidden');\n this.outlineView.classList.remove('hidden');\n this.attachmentsView.classList.add('hidden');\n break;\n case SidebarView.ATTACHMENTS:\n if (this.attachmentsButton.disabled) {\n return;\n }\n this.thumbnailButton.classList.remove('toggled');\n this.outlineButton.classList.remove('toggled');\n this.attachmentsButton.classList.add('toggled');\n\n this.thumbnailView.classList.add('hidden');\n this.outlineView.classList.add('hidden');\n this.attachmentsView.classList.remove('hidden');\n break;\n default:\n console.error('PDFSidebar_switchView: \"' + view +\n '\" is an unsupported value.');\n return;\n }\n // Update the active view *after* it has been validated above,\n // in order to prevent setting it to an invalid state.\n this.active = view | 0;\n\n if (forceOpen && !this.isOpen) {\n this.open();\n return; // NOTE: Opening will trigger rendering, and dispatch the event.\n }\n if (shouldForceRendering) {\n this._forceRendering();\n }\n if (isViewChanged) {\n this._dispatchEvent();\n }\n this._hideUINotification(this.active);\n }\n\n open() {\n if (this.isOpen) {\n return;\n }\n this.isOpen = true;\n this.toggleButton.classList.add('toggled');\n\n this.outerContainer.classList.add('sidebarMoving');\n this.outerContainer.classList.add('sidebarOpen');\n\n if (this.active === SidebarView.THUMBS) {\n this._updateThumbnailViewer();\n }\n this._forceRendering();\n this._dispatchEvent();\n\n this._hideUINotification(this.active);\n }\n\n close() {\n if (!this.isOpen) {\n return;\n }\n this.isOpen = false;\n this.toggleButton.classList.remove('toggled');\n\n this.outerContainer.classList.add('sidebarMoving');\n this.outerContainer.classList.remove('sidebarOpen');\n\n this._forceRendering();\n this._dispatchEvent();\n }\n\n toggle() {\n if (this.isOpen) {\n this.close();\n } else {\n this.open();\n }\n }\n\n /**\n * @private\n */\n _dispatchEvent() {\n this.eventBus.dispatch('sidebarviewchanged', {\n source: this,\n view: this.visibleView,\n });\n }\n\n /**\n * @private\n */\n _forceRendering() {\n if (this.onToggled) {\n this.onToggled();\n } else { // Fallback\n this.pdfViewer.forceRendering();\n this.pdfThumbnailViewer.forceRendering();\n }\n }\n\n /**\n * @private\n */\n _updateThumbnailViewer() {\n let { pdfViewer, pdfThumbnailViewer, } = this;\n\n // Use the rendered pages to set the corresponding thumbnail images.\n let pagesCount = pdfViewer.pagesCount;\n for (let pageIndex = 0; pageIndex < pagesCount; pageIndex++) {\n let pageView = pdfViewer.getPageView(pageIndex);\n if (pageView && pageView.renderingState === RenderingStates.FINISHED) {\n let thumbnailView = pdfThumbnailViewer.getThumbnail(pageIndex);\n thumbnailView.setImage(pageView);\n }\n }\n pdfThumbnailViewer.scrollThumbnailIntoView(pdfViewer.currentPageNumber);\n }\n\n /**\n * @private\n */\n _showUINotification(view) {\n if (this.disableNotification) {\n return;\n }\n\n this.l10n.get('toggle_sidebar_notification.title', null,\n 'Toggle Sidebar (document contains outline/attachments)').\n then((msg) => {\n this.toggleButton.title = msg;\n });\n\n if (!this.isOpen) {\n // Only show the notification on the `toggleButton` if the sidebar is\n // currently closed, to avoid unnecessarily bothering the user.\n this.toggleButton.classList.add(UI_NOTIFICATION_CLASS);\n } else if (view === this.active) {\n // If the sidebar is currently open *and* the `view` is visible, do not\n // bother the user with a notification on the corresponding button.\n return;\n }\n\n switch (view) {\n case SidebarView.OUTLINE:\n this.outlineButton.classList.add(UI_NOTIFICATION_CLASS);\n break;\n case SidebarView.ATTACHMENTS:\n this.attachmentsButton.classList.add(UI_NOTIFICATION_CLASS);\n break;\n }\n }\n\n /**\n * @private\n */\n _hideUINotification(view) {\n if (this.disableNotification) {\n return;\n }\n\n let removeNotification = (view) => {\n switch (view) {\n case SidebarView.OUTLINE:\n this.outlineButton.classList.remove(UI_NOTIFICATION_CLASS);\n break;\n case SidebarView.ATTACHMENTS:\n this.attachmentsButton.classList.remove(UI_NOTIFICATION_CLASS);\n break;\n }\n };\n\n if (!this.isOpen && view !== null) {\n // Only hide the notifications when the sidebar is currently open,\n // or when it is being reset (i.e. `view === null`).\n return;\n }\n this.toggleButton.classList.remove(UI_NOTIFICATION_CLASS);\n\n if (view !== null) {\n removeNotification(view);\n return;\n }\n for (view in SidebarView) { // Remove all sidebar notifications on reset.\n removeNotification(SidebarView[view]);\n }\n\n this.l10n.get('toggle_sidebar.title', null, 'Toggle Sidebar').\n then((msg) => {\n this.toggleButton.title = msg;\n });\n }\n\n /**\n * @private\n */\n _addEventListeners() {\n this.mainContainer.addEventListener('transitionend', (evt) => {\n if (evt.target === this.mainContainer) {\n this.outerContainer.classList.remove('sidebarMoving');\n }\n });\n\n // Buttons for switching views.\n this.thumbnailButton.addEventListener('click', () => {\n this.switchView(SidebarView.THUMBS);\n });\n\n this.outlineButton.addEventListener('click', () => {\n this.switchView(SidebarView.OUTLINE);\n });\n this.outlineButton.addEventListener('dblclick', () => {\n this.pdfOutlineViewer.toggleOutlineTree();\n });\n\n this.attachmentsButton.addEventListener('click', () => {\n this.switchView(SidebarView.ATTACHMENTS);\n });\n\n // Disable/enable views.\n this.eventBus.on('outlineloaded', (evt) => {\n let outlineCount = evt.outlineCount;\n\n this.outlineButton.disabled = !outlineCount;\n\n if (outlineCount) {\n this._showUINotification(SidebarView.OUTLINE);\n } else if (this.active === SidebarView.OUTLINE) {\n // If the outline view was opened during document load, switch away\n // from it if it turns out that the document has no outline.\n this.switchView(SidebarView.THUMBS);\n }\n });\n\n this.eventBus.on('attachmentsloaded', (evt) => {\n if (evt.attachmentsCount) {\n this.attachmentsButton.disabled = false;\n\n this._showUINotification(SidebarView.ATTACHMENTS);\n return;\n }\n\n // Attempt to avoid temporarily disabling, and switching away from, the\n // attachment view for documents that do not contain proper attachments\n // but *only* FileAttachment annotations. Hence we defer those operations\n // slightly to allow time for parsing any FileAttachment annotations that\n // may be present on the *initially* rendered page of the document.\n Promise.resolve().then(() => {\n if (this.attachmentsView.hasChildNodes()) {\n // FileAttachment annotations were appended to the attachment view.\n return;\n }\n this.attachmentsButton.disabled = true;\n\n if (this.active === SidebarView.ATTACHMENTS) {\n // If the attachment view was opened during document load, switch away\n // from it if it turns out that the document has no attachments.\n this.switchView(SidebarView.THUMBS);\n }\n });\n });\n\n // Update the thumbnailViewer, if visible, when exiting presentation mode.\n this.eventBus.on('presentationmodechanged', (evt) => {\n if (!evt.active && !evt.switchInProgress && this.isThumbnailViewVisible) {\n this._updateThumbnailViewer();\n }\n });\n }\n}\n\nexport {\n SidebarView,\n PDFSidebar,\n};\n\n\n\n// WEBPACK FOOTER //\n// web/pdf_sidebar.js","/* Copyright 2014 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nclass OverlayManager {\n constructor() {\n this._overlays = {};\n this._active = null;\n this._keyDownBound = this._keyDown.bind(this);\n }\n\n get active() {\n return this._active;\n }\n\n /**\n * @param {string} name - The name of the overlay that is registered.\n * @param {HTMLDivElement} element - The overlay's DOM element.\n * @param {function} callerCloseMethod - (optional) The method that, if\n * present, calls `OverlayManager.close` from the object\n * registering the overlay. Access to this method is\n * necessary in order to run cleanup code when e.g.\n * the overlay is force closed. The default is `null`.\n * @param {boolean} canForceClose - (optional) Indicates if opening the\n * overlay closes an active overlay. The default is `false`.\n * @returns {Promise} A promise that is resolved when the overlay has been\n * registered.\n */\n register(name, element, callerCloseMethod = null, canForceClose = false) {\n return new Promise((resolve) => {\n let container;\n if (!name || !element || !(container = element.parentNode)) {\n throw new Error('Not enough parameters.');\n } else if (this._overlays[name]) {\n throw new Error('The overlay is already registered.');\n }\n this._overlays[name] = {\n element,\n container,\n callerCloseMethod,\n canForceClose,\n };\n resolve();\n });\n }\n\n /**\n * @param {string} name - The name of the overlay that is unregistered.\n * @returns {Promise} A promise that is resolved when the overlay has been\n * unregistered.\n */\n unregister(name) {\n return new Promise((resolve) => {\n if (!this._overlays[name]) {\n throw new Error('The overlay does not exist.');\n } else if (this._active === name) {\n throw new Error('The overlay cannot be removed while it is active.');\n }\n delete this._overlays[name];\n resolve();\n });\n }\n\n /**\n * @param {string} name - The name of the overlay that should be opened.\n * @returns {Promise} A promise that is resolved when the overlay has been\n * opened.\n */\n open(name) {\n return new Promise((resolve) => {\n if (!this._overlays[name]) {\n throw new Error('The overlay does not exist.');\n } else if (this._active) {\n if (this._overlays[name].canForceClose) {\n this._closeThroughCaller();\n } else if (this._active === name) {\n throw new Error('The overlay is already active.');\n } else {\n throw new Error('Another overlay is currently active.');\n }\n }\n this._active = name;\n this._overlays[this._active].element.classList.remove('hidden');\n this._overlays[this._active].container.classList.remove('hidden');\n\n window.addEventListener('keydown', this._keyDownBound);\n resolve();\n });\n }\n\n /**\n * @param {string} name - The name of the overlay that should be closed.\n * @returns {Promise} A promise that is resolved when the overlay has been\n * closed.\n */\n close(name) {\n return new Promise((resolve) => {\n if (!this._overlays[name]) {\n throw new Error('The overlay does not exist.');\n } else if (!this._active) {\n throw new Error('The overlay is currently not active.');\n } else if (this._active !== name) {\n throw new Error('Another overlay is currently active.');\n }\n this._overlays[this._active].container.classList.add('hidden');\n this._overlays[this._active].element.classList.add('hidden');\n this._active = null;\n\n window.removeEventListener('keydown', this._keyDownBound);\n resolve();\n });\n }\n\n /**\n * @private\n */\n _keyDown(evt) {\n if (this._active && evt.keyCode === 27) { // Esc key.\n this._closeThroughCaller();\n evt.preventDefault();\n }\n }\n\n /**\n * @private\n */\n _closeThroughCaller() {\n if (this._overlays[this._active].callerCloseMethod) {\n this._overlays[this._active].callerCloseMethod();\n }\n if (this._active) {\n this.close(this._active);\n }\n }\n}\n\nexport {\n OverlayManager,\n};\n\n\n\n// WEBPACK FOOTER //\n// web/overlay_manager.js","/* Copyright 2012 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { NullL10n } from './ui_utils';\nimport { PasswordResponses } from 'pdfjs-lib';\n\n/**\n * @typedef {Object} PasswordPromptOptions\n * @property {string} overlayName - Name of the overlay for the overlay manager.\n * @property {HTMLDivElement} container - Div container for the overlay.\n * @property {HTMLParagraphElement} label - Label containing instructions for\n * entering the password.\n * @property {HTMLInputElement} input - Input field for entering the password.\n * @property {HTMLButtonElement} submitButton - Button for submitting the\n * password.\n * @property {HTMLButtonElement} cancelButton - Button for cancelling password\n * entry.\n */\n\nclass PasswordPrompt {\n /**\n * @param {PasswordPromptOptions} options\n * @param {OverlayManager} overlayManager - Manager for the viewer overlays.\n * @param {IL10n} l10n - Localization service.\n */\n constructor(options, overlayManager, l10n = NullL10n) {\n this.overlayName = options.overlayName;\n this.container = options.container;\n this.label = options.label;\n this.input = options.input;\n this.submitButton = options.submitButton;\n this.cancelButton = options.cancelButton;\n this.overlayManager = overlayManager;\n this.l10n = l10n;\n\n this.updateCallback = null;\n this.reason = null;\n\n // Attach the event listeners.\n this.submitButton.addEventListener('click', this.verify.bind(this));\n this.cancelButton.addEventListener('click', this.close.bind(this));\n this.input.addEventListener('keydown', (e) => {\n if (e.keyCode === 13) { // Enter key\n this.verify();\n }\n });\n\n this.overlayManager.register(this.overlayName, this.container,\n this.close.bind(this), true);\n }\n\n open() {\n this.overlayManager.open(this.overlayName).then(() => {\n this.input.focus();\n\n let promptString;\n if (this.reason === PasswordResponses.INCORRECT_PASSWORD) {\n promptString = this.l10n.get('password_invalid', null,\n 'Invalid password. Please try again.');\n } else {\n promptString = this.l10n.get('password_label', null,\n 'Enter the password to open this PDF file.');\n }\n\n promptString.then((msg) => {\n this.label.textContent = msg;\n });\n });\n }\n\n close() {\n this.overlayManager.close(this.overlayName).then(() => {\n this.input.value = '';\n });\n }\n\n verify() {\n let password = this.input.value;\n if (password && password.length > 0) {\n this.close();\n return this.updateCallback(password);\n }\n }\n\n setUpdateCallback(updateCallback, reason) {\n this.updateCallback = updateCallback;\n this.reason = reason;\n }\n}\n\nexport {\n PasswordPrompt,\n};\n\n\n\n// WEBPACK FOOTER //\n// web/password_prompt.js","/* Copyright 2012 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n createObjectURL, createPromiseCapability, getFilenameFromUrl, PDFJS,\n removeNullCharacters\n} from 'pdfjs-lib';\n\n/**\n * @typedef {Object} PDFAttachmentViewerOptions\n * @property {HTMLDivElement} container - The viewer element.\n * @property {EventBus} eventBus - The application event bus.\n * @property {DownloadManager} downloadManager - The download manager.\n */\n\n/**\n * @typedef {Object} PDFAttachmentViewerRenderParameters\n * @property {Object|null} attachments - A lookup table of attachment objects.\n */\n\nclass PDFAttachmentViewer {\n /**\n * @param {PDFAttachmentViewerOptions} options\n */\n constructor({ container, eventBus, downloadManager, }) {\n this.container = container;\n this.eventBus = eventBus;\n this.downloadManager = downloadManager;\n\n this.reset();\n\n this.eventBus.on('fileattachmentannotation',\n this._appendAttachment.bind(this));\n }\n\n reset(keepRenderedCapability = false) {\n this.attachments = null;\n\n // Remove the attachments from the DOM.\n this.container.textContent = '';\n\n if (!keepRenderedCapability) {\n // NOTE: The *only* situation in which the `_renderedCapability` should\n // not be replaced is when appending file attachment annotations.\n this._renderedCapability = createPromiseCapability();\n }\n }\n\n /**\n * @private\n */\n _dispatchEvent(attachmentsCount) {\n this._renderedCapability.resolve();\n\n this.eventBus.dispatch('attachmentsloaded', {\n source: this,\n attachmentsCount,\n });\n }\n\n /**\n * @private\n */\n _bindPdfLink(button, content, filename) {\n if (PDFJS.disableCreateObjectURL) {\n throw new Error('bindPdfLink: ' +\n 'Unsupported \"PDFJS.disableCreateObjectURL\" value.');\n }\n let blobUrl;\n button.onclick = function() {\n if (!blobUrl) {\n blobUrl = createObjectURL(content, 'application/pdf');\n }\n let viewerUrl;\n if (typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC')) {\n // The current URL is the viewer, let's use it and append the file.\n viewerUrl = '?file=' + encodeURIComponent(blobUrl + '#' + filename);\n } else if (PDFJSDev.test('CHROME')) {\n // In the Chrome extension, the URL is rewritten using the history API\n // in viewer.js, so an absolute URL must be generated.\n // eslint-disable-next-line no-undef\n viewerUrl = chrome.runtime.getURL('/content/web/viewer.html') +\n '?file=' + encodeURIComponent(blobUrl + '#' + filename);\n } else if (PDFJSDev.test('FIREFOX || MOZCENTRAL')) {\n // Let Firefox's content handler catch the URL and display the PDF.\n viewerUrl = blobUrl + '?' + encodeURIComponent(filename);\n }\n window.open(viewerUrl);\n return false;\n };\n }\n\n /**\n * @private\n */\n _bindLink(button, content, filename) {\n button.onclick = () => {\n this.downloadManager.downloadData(content, filename, '');\n return false;\n };\n }\n\n /**\n * @param {PDFAttachmentViewerRenderParameters} params\n */\n render({ attachments, keepRenderedCapability = false, }) {\n let attachmentsCount = 0;\n\n if (this.attachments) {\n this.reset(keepRenderedCapability === true);\n }\n this.attachments = attachments || null;\n\n if (!attachments) {\n this._dispatchEvent(attachmentsCount);\n return;\n }\n\n let names = Object.keys(attachments).sort(function(a, b) {\n return a.toLowerCase().localeCompare(b.toLowerCase());\n });\n attachmentsCount = names.length;\n\n for (let i = 0; i < attachmentsCount; i++) {\n let item = attachments[names[i]];\n let filename = removeNullCharacters(getFilenameFromUrl(item.filename));\n\n let div = document.createElement('div');\n div.className = 'attachmentsItem';\n let button = document.createElement('button');\n button.textContent = filename;\n if (/\\.pdf$/i.test(filename) && !PDFJS.disableCreateObjectURL) {\n this._bindPdfLink(button, item.content, filename);\n } else {\n this._bindLink(button, item.content, filename);\n }\n\n div.appendChild(button);\n this.container.appendChild(div);\n }\n\n this._dispatchEvent(attachmentsCount);\n }\n\n /**\n * Used to append FileAttachment annotations to the sidebar.\n * @private\n */\n _appendAttachment({ id, filename, content, }) {\n this._renderedCapability.promise.then(() => {\n let attachments = this.attachments;\n\n if (!attachments) {\n attachments = Object.create(null);\n } else {\n for (let name in attachments) {\n if (id === name) {\n return; // Ignore the new attachment if it already exists.\n }\n }\n }\n attachments[id] = {\n filename,\n content,\n };\n this.render({\n attachments,\n keepRenderedCapability: true,\n });\n });\n }\n}\n\nexport {\n PDFAttachmentViewer,\n};\n\n\n\n// WEBPACK FOOTER //\n// web/pdf_attachment_viewer.js","/* Copyright 2012 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { cloneObj, getPDFFileNameFromURL, NullL10n } from './ui_utils';\nimport { createPromiseCapability } from 'pdfjs-lib';\n\nconst DEFAULT_FIELD_CONTENT = '-';\n\n/**\n * @typedef {Object} PDFDocumentPropertiesOptions\n * @property {string} overlayName - Name/identifier for the overlay.\n * @property {Object} fields - Names and elements of the overlay's fields.\n * @property {HTMLDivElement} container - Div container for the overlay.\n * @property {HTMLButtonElement} closeButton - Button for closing the overlay.\n */\n\nclass PDFDocumentProperties {\n /**\n * @param {PDFDocumentPropertiesOptions} options\n * @param {OverlayManager} overlayManager - Manager for the viewer overlays.\n * @param {IL10n} l10n - Localization service.\n */\n constructor({ overlayName, fields, container, closeButton, },\n overlayManager, l10n = NullL10n) {\n this.overlayName = overlayName;\n this.fields = fields;\n this.container = container;\n this.overlayManager = overlayManager;\n this.l10n = l10n;\n\n this._reset();\n\n if (closeButton) { // Bind the event listener for the Close button.\n closeButton.addEventListener('click', this.close.bind(this));\n }\n this.overlayManager.register(this.overlayName, this.container,\n this.close.bind(this));\n }\n\n /**\n * Open the document properties overlay.\n */\n open() {\n let freezeFieldData = (data) => {\n Object.defineProperty(this, 'fieldData', {\n value: Object.freeze(data),\n writable: false,\n enumerable: true,\n configurable: true,\n });\n };\n\n Promise.all([this.overlayManager.open(this.overlayName),\n this._dataAvailableCapability.promise]).then(() => {\n // If the document properties were previously fetched (for this PDF file),\n // just update the dialog immediately to avoid redundant lookups.\n if (this.fieldData) {\n this._updateUI();\n return;\n }\n // Get the document properties.\n this.pdfDocument.getMetadata().then(({ info, metadata, }) => {\n return Promise.all([\n info,\n metadata,\n this._parseFileSize(this.maybeFileSize),\n this._parseDate(info.CreationDate),\n this._parseDate(info.ModDate)\n ]);\n }).then(([info, metadata, fileSize, creationDate, modificationDate]) => {\n freezeFieldData({\n 'fileName': getPDFFileNameFromURL(this.url),\n 'fileSize': fileSize,\n 'title': info.Title,\n 'author': info.Author,\n 'subject': info.Subject,\n 'keywords': info.Keywords,\n 'creationDate': creationDate,\n 'modificationDate': modificationDate,\n 'creator': info.Creator,\n 'producer': info.Producer,\n 'version': info.PDFFormatVersion,\n 'pageCount': this.pdfDocument.numPages,\n });\n this._updateUI();\n\n // Get the correct fileSize, since it may not have been set (if\n // `this.setFileSize` wasn't called) or may be incorrectly set.\n return this.pdfDocument.getDownloadInfo();\n }).then(({ length, }) => {\n return this._parseFileSize(length);\n }).then((fileSize) => {\n let data = cloneObj(this.fieldData);\n data['fileSize'] = fileSize;\n\n freezeFieldData(data);\n this._updateUI();\n });\n });\n }\n\n /**\n * Close the document properties overlay.\n */\n close() {\n this.overlayManager.close(this.overlayName);\n }\n\n /**\n * Set a reference to the PDF document and the URL in order\n * to populate the overlay fields with the document properties.\n * Note that the overlay will contain no information if this method\n * is not called.\n *\n * @param {Object} pdfDocument - A reference to the PDF document.\n * @param {string} url - The URL of the document.\n */\n setDocument(pdfDocument, url) {\n if (this.pdfDocument) {\n this._reset();\n this._updateUI(true);\n }\n if (!pdfDocument) {\n return;\n }\n this.pdfDocument = pdfDocument;\n this.url = url;\n\n this._dataAvailableCapability.resolve();\n }\n\n /**\n * Set the file size of the PDF document. This method is used to\n * update the file size in the document properties overlay once it\n * is known so we do not have to wait until the entire file is loaded.\n *\n * @param {number} fileSize - The file size of the PDF document.\n */\n setFileSize(fileSize) {\n if (typeof fileSize === 'number' && fileSize > 0) {\n this.maybeFileSize = fileSize;\n }\n }\n\n /**\n * @private\n */\n _reset() {\n this.pdfDocument = null;\n this.url = null;\n\n this.maybeFileSize = 0;\n delete this.fieldData;\n this._dataAvailableCapability = createPromiseCapability();\n }\n\n /**\n * Always updates all of the dialog fields, to prevent inconsistent UI state.\n * NOTE: If the contents of a particular field is neither a non-empty string,\n * nor a number, it will fall back to `DEFAULT_FIELD_CONTENT`.\n * @private\n */\n _updateUI(reset = false) {\n if (reset || !this.fieldData) {\n for (let id in this.fields) {\n this.fields[id].textContent = DEFAULT_FIELD_CONTENT;\n }\n return;\n }\n if (this.overlayManager.active !== this.overlayName) {\n // Don't bother updating the dialog if has already been closed,\n // since it will be updated the next time `this.open` is called.\n return;\n }\n for (let id in this.fields) {\n let content = this.fieldData[id];\n this.fields[id].textContent = (content || content === 0) ?\n content : DEFAULT_FIELD_CONTENT;\n }\n }\n\n /**\n * @private\n */\n _parseFileSize(fileSize = 0) {\n let kb = fileSize / 1024;\n if (!kb) {\n return Promise.resolve(undefined);\n } else if (kb < 1024) {\n return this.l10n.get('document_properties_kb', {\n size_kb: (+kb.toPrecision(3)).toLocaleString(),\n size_b: fileSize.toLocaleString(),\n }, '{{size_kb}} KB ({{size_b}} bytes)');\n }\n return this.l10n.get('document_properties_mb', {\n size_mb: (+(kb / 1024).toPrecision(3)).toLocaleString(),\n size_b: fileSize.toLocaleString(),\n }, '{{size_mb}} MB ({{size_b}} bytes)');\n }\n\n /**\n * @private\n */\n _parseDate(inputDate) {\n if (!inputDate) {\n return;\n }\n // This is implemented according to the PDF specification, but note that\n // Adobe Reader doesn't handle changing the date to universal time\n // and doesn't use the user's time zone (they're effectively ignoring\n // the HH' and mm' parts of the date string).\n let dateToParse = inputDate;\n\n // Remove the D: prefix if it is available.\n if (dateToParse.substring(0, 2) === 'D:') {\n dateToParse = dateToParse.substring(2);\n }\n\n // Get all elements from the PDF date string.\n // JavaScript's `Date` object expects the month to be between\n // 0 and 11 instead of 1 and 12, so we're correcting for this.\n let year = parseInt(dateToParse.substring(0, 4), 10);\n let month = parseInt(dateToParse.substring(4, 6), 10) - 1;\n let day = parseInt(dateToParse.substring(6, 8), 10);\n let hours = parseInt(dateToParse.substring(8, 10), 10);\n let minutes = parseInt(dateToParse.substring(10, 12), 10);\n let seconds = parseInt(dateToParse.substring(12, 14), 10);\n let utRel = dateToParse.substring(14, 15);\n let offsetHours = parseInt(dateToParse.substring(15, 17), 10);\n let offsetMinutes = parseInt(dateToParse.substring(18, 20), 10);\n\n // As per spec, utRel = 'Z' means equal to universal time.\n // The other cases ('-' and '+') have to be handled here.\n if (utRel === '-') {\n hours += offsetHours;\n minutes += offsetMinutes;\n } else if (utRel === '+') {\n hours -= offsetHours;\n minutes -= offsetMinutes;\n }\n\n // Return the new date format from the user's locale.\n let date = new Date(Date.UTC(year, month, day, hours, minutes, seconds));\n let dateString = date.toLocaleDateString();\n let timeString = date.toLocaleTimeString();\n return this.l10n.get('document_properties_date_string',\n { date: dateString, time: timeString, },\n '{{date}}, {{time}}');\n }\n}\n\nexport {\n PDFDocumentProperties,\n};\n\n\n\n// WEBPACK FOOTER //\n// web/pdf_document_properties.js","/* Copyright 2012 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FindState } from './pdf_find_controller';\nimport { NullL10n } from './ui_utils';\n\n/**\n * Creates a \"search bar\" given a set of DOM elements that act as controls\n * for searching or for setting search preferences in the UI. This object\n * also sets up the appropriate events for the controls. Actual searching\n * is done by PDFFindController.\n */\nclass PDFFindBar {\n constructor(options, l10n = NullL10n) {\n this.opened = false;\n\n this.bar = options.bar || null;\n this.toggleButton = options.toggleButton || null;\n this.findField = options.findField || null;\n this.highlightAll = options.highlightAllCheckbox || null;\n this.caseSensitive = options.caseSensitiveCheckbox || null;\n this.findMsg = options.findMsg || null;\n this.findResultsCount = options.findResultsCount || null;\n this.findStatusIcon = options.findStatusIcon || null;\n this.findPreviousButton = options.findPreviousButton || null;\n this.findNextButton = options.findNextButton || null;\n this.findController = options.findController || null;\n this.eventBus = options.eventBus;\n this.l10n = l10n;\n\n if (this.findController === null) {\n throw new Error('PDFFindBar cannot be used without a ' +\n 'PDFFindController instance.');\n }\n\n // Add event listeners to the DOM elements.\n this.toggleButton.addEventListener('click', () => {\n this.toggle();\n });\n\n this.findField.addEventListener('input', () => {\n this.dispatchEvent('');\n });\n\n this.bar.addEventListener('keydown', (e) => {\n switch (e.keyCode) {\n case 13: // Enter\n if (e.target === this.findField) {\n this.dispatchEvent('again', e.shiftKey);\n }\n break;\n case 27: // Escape\n this.close();\n break;\n }\n });\n\n this.findPreviousButton.addEventListener('click', () => {\n this.dispatchEvent('again', true);\n });\n\n this.findNextButton.addEventListener('click', () => {\n this.dispatchEvent('again', false);\n });\n\n this.highlightAll.addEventListener('click', () => {\n this.dispatchEvent('highlightallchange');\n });\n\n this.caseSensitive.addEventListener('click', () => {\n this.dispatchEvent('casesensitivitychange');\n });\n\n this.eventBus.on('resize', this._adjustWidth.bind(this));\n }\n\n reset() {\n this.updateUIState();\n }\n\n dispatchEvent(type, findPrev) {\n this.eventBus.dispatch('find', {\n source: this,\n type,\n query: this.findField.value,\n caseSensitive: this.caseSensitive.checked,\n phraseSearch: true,\n highlightAll: this.highlightAll.checked,\n findPrevious: findPrev,\n });\n }\n\n updateUIState(state, previous, matchCount) {\n let notFound = false;\n let findMsg = '';\n let status = '';\n\n switch (state) {\n case FindState.FOUND:\n break;\n\n case FindState.PENDING:\n status = 'pending';\n break;\n\n case FindState.NOT_FOUND:\n findMsg = this.l10n.get('find_not_found', null, 'Phrase not found');\n notFound = true;\n break;\n\n case FindState.WRAPPED:\n if (previous) {\n findMsg = this.l10n.get('find_reached_top', null,\n 'Reached top of document, continued from bottom');\n } else {\n findMsg = this.l10n.get('find_reached_bottom', null,\n 'Reached end of document, continued from top');\n }\n break;\n }\n\n if (notFound) {\n this.findField.classList.add('notFound');\n } else {\n this.findField.classList.remove('notFound');\n }\n\n this.findField.setAttribute('data-status', status);\n Promise.resolve(findMsg).then((msg) => {\n this.findMsg.textContent = msg;\n this._adjustWidth();\n });\n\n this.updateResultsCount(matchCount);\n }\n\n updateResultsCount(matchCount) {\n if (!this.findResultsCount) {\n return; // No UI control is provided.\n }\n\n if (!matchCount) {\n // If there are no matches, hide and reset the counter.\n this.findResultsCount.classList.add('hidden');\n this.findResultsCount.textContent = '';\n } else {\n // Update and show the match counter.\n this.findResultsCount.textContent = matchCount.toLocaleString();\n this.findResultsCount.classList.remove('hidden');\n }\n // Since `updateResultsCount` may be called from `PDFFindController`,\n // ensure that the width of the findbar is always updated correctly.\n this._adjustWidth();\n }\n\n open() {\n if (!this.opened) {\n this.opened = true;\n this.toggleButton.classList.add('toggled');\n this.bar.classList.remove('hidden');\n }\n this.findField.select();\n this.findField.focus();\n\n this._adjustWidth();\n }\n\n close() {\n if (!this.opened) {\n return;\n }\n this.opened = false;\n this.toggleButton.classList.remove('toggled');\n this.bar.classList.add('hidden');\n this.findController.active = false;\n }\n\n toggle() {\n if (this.opened) {\n this.close();\n } else {\n this.open();\n }\n }\n\n /**\n * @private\n */\n _adjustWidth() {\n if (!this.opened) {\n return;\n }\n\n // The find bar has an absolute position and thus the browser extends\n // its width to the maximum possible width once the find bar does not fit\n // entirely within the window anymore (and its elements are automatically\n // wrapped). Here we detect and fix that.\n this.bar.classList.remove('wrapContainers');\n\n let findbarHeight = this.bar.clientHeight;\n let inputContainerHeight = this.bar.firstElementChild.clientHeight;\n\n if (findbarHeight > inputContainerHeight) {\n // The findbar is taller than the input container, which means that\n // the browser wrapped some of the elements. For a consistent look,\n // wrap all of them to adjust the width of the find bar.\n this.bar.classList.add('wrapContainers');\n }\n }\n}\n\nexport {\n PDFFindBar,\n};\n\n\n\n// WEBPACK FOOTER //\n// web/pdf_find_bar.js","/* Copyright 2017 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n cloneObj, isValidRotation, parseQueryString, waitOnEventOrTimeout\n} from './ui_utils';\nimport { getGlobalEventBus } from './dom_events';\n\n// Heuristic value used when force-resetting `this._blockHashChange`.\nconst HASH_CHANGE_TIMEOUT = 1000; // milliseconds\n// Heuristic value used when adding the current position to the browser history.\nconst POSITION_UPDATED_THRESHOLD = 50;\n// Heuristic value used when adding a temporary position to the browser history.\nconst UPDATE_VIEWAREA_TIMEOUT = 1000; // milliseconds\n\n/**\n * @typedef {Object} PDFHistoryOptions\n * @property {IPDFLinkService} linkService - The navigation/linking service.\n * @property {EventBus} eventBus - The application event bus.\n */\n\n/**\n * @typedef {Object} PushParameters\n * @property {string} namedDest - (optional) The named destination. If absent,\n * a stringified version of `explicitDest` is used.\n * @property {Array} explicitDest - The explicit destination array.\n * @property {number} pageNumber - The page to which the destination points.\n */\n\nfunction getCurrentHash() {\n return document.location.hash;\n}\n\nfunction parseCurrentHash(linkService) {\n let hash = unescape(getCurrentHash()).substring(1);\n let params = parseQueryString(hash);\n\n let page = params.page | 0;\n if (!(Number.isInteger(page) && page > 0 && page <= linkService.pagesCount)) {\n page = null;\n }\n return { hash, page, rotation: linkService.rotation, };\n}\n\nclass PDFHistory {\n /**\n * @param {PDFHistoryOptions} options\n */\n constructor({ linkService, eventBus, }) {\n this.linkService = linkService;\n this.eventBus = eventBus || getGlobalEventBus();\n\n this.initialized = false;\n this.initialBookmark = null;\n this.initialRotation = null;\n\n this._boundEvents = Object.create(null);\n this._isViewerInPresentationMode = false;\n this._isPagesLoaded = false;\n\n // Ensure that we don't miss either a 'presentationmodechanged' or a\n // 'pagesloaded' event, by registering the listeners immediately.\n this.eventBus.on('presentationmodechanged', (evt) => {\n this._isViewerInPresentationMode = evt.active || evt.switchInProgress;\n });\n this.eventBus.on('pagesloaded', (evt) => {\n this._isPagesLoaded = !!evt.pagesCount;\n });\n }\n\n /**\n * Initialize the history for the PDF document, using either the current\n * browser history entry or the document hash, whichever is present.\n * @param {string} fingerprint - The PDF document's unique fingerprint.\n * @param {boolean} resetHistory - (optional) Reset the browsing history.\n */\n initialize(fingerprint, resetHistory = false) {\n if (!fingerprint || typeof fingerprint !== 'string') {\n console.error(\n 'PDFHistory.initialize: The \"fingerprint\" must be a non-empty string.');\n return;\n }\n let reInitialized = this.initialized && this.fingerprint !== fingerprint;\n this.fingerprint = fingerprint;\n\n if (!this.initialized) {\n this._bindEvents();\n }\n let state = window.history.state;\n\n this.initialized = true;\n this.initialBookmark = null;\n this.initialRotation = null;\n\n this._popStateInProgress = false;\n this._blockHashChange = 0;\n this._currentHash = getCurrentHash();\n this._numPositionUpdates = 0;\n\n this._currentUid = this._uid = 0;\n this._destination = null;\n this._position = null;\n\n if (!this._isValidState(state) || resetHistory) {\n let { hash, page, rotation, } = parseCurrentHash(this.linkService);\n\n if (!hash || reInitialized || resetHistory) {\n // Ensure that the browser history is reset on PDF document load.\n this._pushOrReplaceState(null, /* forceReplace = */ true);\n return;\n }\n // Ensure that the browser history is initialized correctly when\n // the document hash is present on PDF document load.\n this._pushOrReplaceState({ hash, page, rotation, },\n /* forceReplace = */ true);\n return;\n }\n\n // The browser history contains a valid entry, ensure that the history is\n // initialized correctly on PDF document load.\n let destination = state.destination;\n this._updateInternalState(destination, state.uid,\n /* removeTemporary = */ true);\n\n if (destination.rotation !== undefined) {\n this.initialRotation = destination.rotation;\n }\n if (destination.dest) {\n this.initialBookmark = JSON.stringify(destination.dest);\n\n // If the history is updated, e.g. through the user changing the hash,\n // before the initial destination has become visible, then we do *not*\n // want to potentially add `this._position` to the browser history.\n this._destination.page = null;\n } else if (destination.hash) {\n this.initialBookmark = destination.hash;\n } else if (destination.page) {\n // Fallback case; shouldn't be necessary, but better safe than sorry.\n this.initialBookmark = `page=${destination.page}`;\n }\n }\n\n /**\n * Push an internal destination to the browser history.\n * @param {PushParameters}\n */\n push({ namedDest, explicitDest, pageNumber, }) {\n if (!this.initialized) {\n return;\n }\n if ((namedDest && typeof namedDest !== 'string') ||\n !(explicitDest instanceof Array) ||\n !(Number.isInteger(pageNumber) &&\n pageNumber > 0 && pageNumber <= this.linkService.pagesCount)) {\n console.error('PDFHistory.push: Invalid parameters.');\n return;\n }\n\n let hash = namedDest || JSON.stringify(explicitDest);\n if (!hash) {\n // The hash *should* never be undefined, but if that were to occur,\n // avoid any possible issues by not updating the browser history.\n return;\n }\n\n let forceReplace = false;\n if (this._destination &&\n (this._destination.hash === hash ||\n isDestsEqual(this._destination.dest, explicitDest))) {\n // When the new destination is identical to `this._destination`, and\n // its `page` is undefined, replace the current browser history entry.\n // NOTE: This can only occur if `this._destination` was set either:\n // - through the document hash being specified on load.\n // - through the user changing the hash of the document.\n if (this._destination.page) {\n return;\n }\n forceReplace = true;\n }\n if (this._popStateInProgress && !forceReplace) {\n return;\n }\n\n this._pushOrReplaceState({\n dest: explicitDest,\n hash,\n page: pageNumber,\n rotation: this.linkService.rotation,\n }, forceReplace);\n\n if (!this._popStateInProgress) {\n // Prevent the browser history from updating while the new destination is\n // being scrolled into view, to avoid potentially inconsistent state.\n this._popStateInProgress = true;\n // We defer the resetting of `this._popStateInProgress`, to account for\n // e.g. zooming occuring when the new destination is being navigated to.\n Promise.resolve().then(() => {\n this._popStateInProgress = false;\n });\n }\n }\n\n /**\n * Push the current position to the browser history.\n */\n pushCurrentPosition() {\n if (!this.initialized || this._popStateInProgress) {\n return;\n }\n this._tryPushCurrentPosition();\n }\n\n /**\n * Go back one step in the browser history.\n * NOTE: Avoids navigating away from the document, useful for \"named actions\".\n */\n back() {\n if (!this.initialized || this._popStateInProgress) {\n return;\n }\n let state = window.history.state;\n if (this._isValidState(state) && state.uid > 0) {\n window.history.back();\n }\n }\n\n /**\n * Go forward one step in the browser history.\n * NOTE: Avoids navigating away from the document, useful for \"named actions\".\n */\n forward() {\n if (!this.initialized || this._popStateInProgress) {\n return;\n }\n let state = window.history.state;\n if (this._isValidState(state) && state.uid < (this._uid - 1)) {\n window.history.forward();\n }\n }\n\n /**\n * @returns {boolean} Indicating if the user is currently moving through the\n * browser history, useful e.g. for skipping the next 'hashchange' event.\n */\n get popStateInProgress() {\n return this.initialized &&\n (this._popStateInProgress || this._blockHashChange > 0);\n }\n\n /**\n * @private\n */\n _pushOrReplaceState(destination, forceReplace = false) {\n let shouldReplace = forceReplace || !this._destination;\n let newState = {\n fingerprint: this.fingerprint,\n uid: shouldReplace ? this._currentUid : this._uid,\n destination,\n };\n\n if (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('CHROME') &&\n window.history.state && window.history.state.chromecomState) {\n // history.state.chromecomState is managed by chromecom.js.\n newState.chromecomState = window.history.state.chromecomState;\n }\n this._updateInternalState(destination, newState.uid);\n\n if (shouldReplace) {\n if (typeof PDFJSDev !== 'undefined' &&\n PDFJSDev.test('FIREFOX || MOZCENTRAL')) {\n // Providing the third argument causes a SecurityError for file:// URLs.\n window.history.replaceState(newState, '');\n } else {\n window.history.replaceState(newState, '', document.URL);\n }\n } else {\n if (typeof PDFJSDev !== 'undefined' &&\n PDFJSDev.test('FIREFOX || MOZCENTRAL')) {\n // Providing the third argument causes a SecurityError for file:// URLs.\n window.history.pushState(newState, '');\n } else {\n window.history.pushState(newState, '', document.URL);\n }\n }\n\n if (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('CHROME') &&\n top === window) {\n // eslint-disable-next-line no-undef\n chrome.runtime.sendMessage('showPageAction');\n }\n }\n\n /**\n * @private\n */\n _tryPushCurrentPosition(temporary = false) {\n if (!this._position) {\n return;\n }\n let position = this._position;\n if (temporary) {\n position = cloneObj(this._position);\n position.temporary = true;\n }\n\n if (!this._destination) {\n this._pushOrReplaceState(position);\n return;\n }\n if (this._destination.temporary) {\n // Always replace a previous *temporary* position.\n this._pushOrReplaceState(position, /* forceReplace = */ true);\n return;\n }\n if (this._destination.hash === position.hash) {\n return; // The current document position has not changed.\n }\n if (!this._destination.page &&\n (POSITION_UPDATED_THRESHOLD <= 0 ||\n this._numPositionUpdates <= POSITION_UPDATED_THRESHOLD)) {\n // `this._destination` was set through the user changing the hash of\n // the document. Do not add `this._position` to the browser history,\n // to avoid \"flooding\" it with lots of (nearly) identical entries,\n // since we cannot ensure that the document position has changed.\n return;\n }\n\n let forceReplace = false;\n if (this._destination.page === position.first ||\n this._destination.page === position.page) {\n // When the `page` of `this._destination` is still visible, do not\n // update the browsing history when `this._destination` either:\n // - contains an internal destination, since in this case we\n // cannot ensure that the document position has actually changed.\n // - was set through the user changing the hash of the document.\n if (this._destination.dest || !this._destination.first) {\n return;\n }\n // To avoid \"flooding\" the browser history, replace the current entry.\n forceReplace = true;\n }\n this._pushOrReplaceState(position, forceReplace);\n }\n\n /**\n * @private\n */\n _isValidState(state) {\n if (!state) {\n return false;\n }\n if (state.fingerprint !== this.fingerprint) {\n // This should only occur in viewers with support for opening more than\n // one PDF document, e.g. the GENERIC viewer.\n return false;\n }\n if (!Number.isInteger(state.uid) || state.uid < 0) {\n return false;\n }\n if (state.destination === null || typeof state.destination !== 'object') {\n return false;\n }\n return true;\n }\n\n /**\n * @private\n */\n _updateInternalState(destination, uid, removeTemporary = false) {\n if (this._updateViewareaTimeout) {\n // When updating `this._destination`, make sure that we always wait for\n // the next 'updateviewarea' event before (potentially) attempting to\n // push the current position to the browser history.\n clearTimeout(this._updateViewareaTimeout);\n this._updateViewareaTimeout = null;\n }\n if (removeTemporary && destination && destination.temporary) {\n // When the `destination` comes from the browser history,\n // we no longer treat it as a *temporary* position.\n delete destination.temporary;\n }\n this._destination = destination;\n this._currentUid = uid;\n this._uid = this._currentUid + 1;\n // This should always be reset when `this._destination` is updated.\n this._numPositionUpdates = 0;\n }\n\n /**\n * @private\n */\n _updateViewarea({ location, }) {\n if (this._updateViewareaTimeout) {\n clearTimeout(this._updateViewareaTimeout);\n this._updateViewareaTimeout = null;\n }\n\n this._position = {\n hash: this._isViewerInPresentationMode ?\n `page=${location.pageNumber}` : location.pdfOpenParams.substring(1),\n page: this.linkService.page,\n first: location.pageNumber,\n rotation: location.rotation,\n };\n\n if (this._popStateInProgress) {\n return;\n }\n\n if (POSITION_UPDATED_THRESHOLD > 0 && this._isPagesLoaded &&\n this._destination && !this._destination.page) {\n // If the current destination was set through the user changing the hash\n // of the document, we will usually not try to push the current position\n // to the browser history; see `this._tryPushCurrentPosition()`.\n //\n // To prevent `this._tryPushCurrentPosition()` from effectively being\n // reduced to a no-op in this case, we will assume that the position\n // *did* in fact change if the 'updateviewarea' event was dispatched\n // more than `POSITION_UPDATED_THRESHOLD` times.\n this._numPositionUpdates++;\n }\n\n if (UPDATE_VIEWAREA_TIMEOUT > 0) {\n // When closing the browser, a 'pagehide' event will be dispatched which\n // *should* allow us to push the current position to the browser history.\n // In practice, it seems that the event is arriving too late in order for\n // the session history to be successfully updated.\n // (For additional details, please refer to the discussion in\n // https://bugzilla.mozilla.org/show_bug.cgi?id=1153393.)\n //\n // To workaround this we attempt to *temporarily* add the current position\n // to the browser history only when the viewer is *idle*,\n // i.e. when scrolling and/or zooming does not occur.\n //\n // PLEASE NOTE: It's absolutely imperative that the browser history is\n // *not* updated too often, since that would render the viewer more or\n // less unusable. Hence the use of a timeout to delay the update until\n // the viewer has been idle for `UPDATE_VIEWAREA_TIMEOUT` milliseconds.\n this._updateViewareaTimeout = setTimeout(() => {\n if (!this._popStateInProgress) {\n this._tryPushCurrentPosition(/* temporary = */ true);\n }\n this._updateViewareaTimeout = null;\n }, UPDATE_VIEWAREA_TIMEOUT);\n }\n }\n\n /**\n * @private\n */\n _popState({ state, }) {\n let newHash = getCurrentHash(), hashChanged = this._currentHash !== newHash;\n this._currentHash = newHash;\n\n if (!state ||\n (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('CHROME') &&\n state.chromecomState && !this._isValidState(state))) {\n // This case corresponds to the user changing the hash of the document.\n this._currentUid = this._uid;\n\n let { hash, page, rotation, } = parseCurrentHash(this.linkService);\n this._pushOrReplaceState({ hash, page, rotation, },\n /* forceReplace = */ true);\n return;\n }\n if (!this._isValidState(state)) {\n // This should only occur in viewers with support for opening more than\n // one PDF document, e.g. the GENERIC viewer.\n return;\n }\n\n // Prevent the browser history from updating until the new destination,\n // as stored in the browser history, has been scrolled into view.\n this._popStateInProgress = true;\n\n if (hashChanged) {\n // When the hash changed, implying that the 'popstate' event will be\n // followed by a 'hashchange' event, then we do *not* want to update the\n // browser history when handling the 'hashchange' event (in web/app.js)\n // since that would *overwrite* the new destination navigated to below.\n //\n // To avoid accidentally disabling all future user-initiated hash changes,\n // if there's e.g. another 'hashchange' listener that stops the event\n // propagation, we make sure to always force-reset `this._blockHashChange`\n // after `HASH_CHANGE_TIMEOUT` milliseconds have passed.\n this._blockHashChange++;\n waitOnEventOrTimeout({\n target: window,\n name: 'hashchange',\n delay: HASH_CHANGE_TIMEOUT,\n }).then(() => {\n this._blockHashChange--;\n });\n }\n\n // Navigate to the new destination.\n let destination = state.destination;\n this._updateInternalState(destination, state.uid,\n /* removeTemporary = */ true);\n\n if (isValidRotation(destination.rotation)) {\n this.linkService.rotation = destination.rotation;\n }\n if (destination.dest) {\n this.linkService.navigateTo(destination.dest);\n } else if (destination.hash) {\n this.linkService.setHash(destination.hash);\n } else if (destination.page) {\n // Fallback case; shouldn't be necessary, but better safe than sorry.\n this.linkService.page = destination.page;\n }\n\n // Since `PDFLinkService.navigateTo` is asynchronous, we thus defer the\n // resetting of `this._popStateInProgress` slightly.\n Promise.resolve().then(() => {\n this._popStateInProgress = false;\n });\n }\n\n /**\n * @private\n */\n _bindEvents() {\n let { _boundEvents, eventBus, } = this;\n\n _boundEvents.updateViewarea = this._updateViewarea.bind(this);\n _boundEvents.popState = this._popState.bind(this);\n _boundEvents.pageHide = (evt) => {\n // Attempt to push the `this._position` into the browser history when\n // navigating away from the document. This is *only* done if the history\n // is currently empty, since otherwise an existing browser history entry\n // will end up being overwritten (given that new entries cannot be pushed\n // into the browser history when the 'unload' event has already fired).\n if (!this._destination) {\n this._tryPushCurrentPosition();\n }\n };\n\n eventBus.on('updateviewarea', _boundEvents.updateViewarea);\n window.addEventListener('popstate', _boundEvents.popState);\n window.addEventListener('pagehide', _boundEvents.pageHide);\n }\n}\n\nfunction isDestsEqual(firstDest, secondDest) {\n function isEntryEqual(first, second) {\n if (typeof first !== typeof second) {\n return false;\n }\n if (first instanceof Array || second instanceof Array) {\n return false;\n }\n if (first !== null && typeof first === 'object' && second !== null) {\n if (Object.keys(first).length !== Object.keys(second).length) {\n return false;\n }\n for (var key in first) {\n if (!isEntryEqual(first[key], second[key])) {\n return false;\n }\n }\n return true;\n }\n return first === second || (Number.isNaN(first) && Number.isNaN(second));\n }\n\n if (!(firstDest instanceof Array && secondDest instanceof Array)) {\n return false;\n }\n if (firstDest.length !== secondDest.length) {\n return false;\n }\n for (let i = 0, ii = firstDest.length; i < ii; i++) {\n if (!isEntryEqual(firstDest[i], secondDest[i])) {\n return false;\n }\n }\n return true;\n}\n\nexport {\n PDFHistory,\n isDestsEqual,\n};\n\n\n\n// WEBPACK FOOTER //\n// web/pdf_history.js","/* Copyright 2012 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n addLinkAttributes, PDFJS, removeNullCharacters\n} from 'pdfjs-lib';\n\nconst DEFAULT_TITLE = '\\u2013';\n\n/**\n * @typedef {Object} PDFOutlineViewerOptions\n * @property {HTMLDivElement} container - The viewer element.\n * @property {IPDFLinkService} linkService - The navigation/linking service.\n * @property {EventBus} eventBus - The application event bus.\n */\n\n/**\n * @typedef {Object} PDFOutlineViewerRenderParameters\n * @property {Array|null} outline - An array of outline objects.\n */\n\nclass PDFOutlineViewer {\n /**\n * @param {PDFOutlineViewerOptions} options\n */\n constructor({ container, linkService, eventBus, }) {\n this.container = container;\n this.linkService = linkService;\n this.eventBus = eventBus;\n\n this.reset();\n }\n\n reset() {\n this.outline = null;\n this.lastToggleIsShow = true;\n\n // Remove the outline from the DOM.\n this.container.textContent = '';\n\n // Ensure that the left (right in RTL locales) margin is always reset,\n // to prevent incorrect outline alignment if a new document is opened.\n this.container.classList.remove('outlineWithDeepNesting');\n }\n\n /**\n * @private\n */\n _dispatchEvent(outlineCount) {\n this.eventBus.dispatch('outlineloaded', {\n source: this,\n outlineCount,\n });\n }\n\n /**\n * @private\n */\n _bindLink(element, item) {\n if (item.url) {\n addLinkAttributes(element, {\n url: item.url,\n target: (item.newWindow ? PDFJS.LinkTarget.BLANK : undefined),\n });\n return;\n }\n let destination = item.dest;\n\n element.href = this.linkService.getDestinationHash(destination);\n element.onclick = () => {\n if (destination) {\n this.linkService.navigateTo(destination);\n }\n return false;\n };\n }\n\n /**\n * @private\n */\n _setStyles(element, item) {\n let styleStr = '';\n if (item.bold) {\n styleStr += 'font-weight: bold;';\n }\n if (item.italic) {\n styleStr += 'font-style: italic;';\n }\n\n if (styleStr) {\n element.setAttribute('style', styleStr);\n }\n }\n\n /**\n * Prepend a button before an outline item which allows the user to toggle\n * the visibility of all outline items at that level.\n *\n * @private\n */\n _addToggleButton(div) {\n let toggler = document.createElement('div');\n toggler.className = 'outlineItemToggler';\n toggler.onclick = (evt) => {\n evt.stopPropagation();\n toggler.classList.toggle('outlineItemsHidden');\n\n if (evt.shiftKey) {\n let shouldShowAll = !toggler.classList.contains('outlineItemsHidden');\n this._toggleOutlineItem(div, shouldShowAll);\n }\n };\n div.insertBefore(toggler, div.firstChild);\n }\n\n /**\n * Toggle the visibility of the subtree of an outline item.\n *\n * @param {Element} root - the root of the outline (sub)tree.\n * @param {boolean} show - whether to show the outline (sub)tree. If false,\n * the outline subtree rooted at |root| will be collapsed.\n *\n * @private\n */\n _toggleOutlineItem(root, show) {\n this.lastToggleIsShow = show;\n let togglers = root.querySelectorAll('.outlineItemToggler');\n for (let i = 0, ii = togglers.length; i < ii; ++i) {\n togglers[i].classList[show ? 'remove' : 'add']('outlineItemsHidden');\n }\n }\n\n /**\n * Collapse or expand all subtrees of the outline.\n */\n toggleOutlineTree() {\n if (!this.outline) {\n return;\n }\n this._toggleOutlineItem(this.container, !this.lastToggleIsShow);\n }\n\n /**\n * @param {PDFOutlineViewerRenderParameters} params\n */\n render({ outline, }) {\n let outlineCount = 0;\n\n if (this.outline) {\n this.reset();\n }\n this.outline = outline || null;\n\n if (!outline) {\n this._dispatchEvent(outlineCount);\n return;\n }\n\n let fragment = document.createDocumentFragment();\n let queue = [{ parent: fragment, items: this.outline, }];\n let hasAnyNesting = false;\n while (queue.length > 0) {\n let levelData = queue.shift();\n for (let i = 0, len = levelData.items.length; i < len; i++) {\n let item = levelData.items[i];\n\n let div = document.createElement('div');\n div.className = 'outlineItem';\n\n let element = document.createElement('a');\n this._bindLink(element, item);\n this._setStyles(element, item);\n element.textContent =\n removeNullCharacters(item.title) || DEFAULT_TITLE;\n\n div.appendChild(element);\n\n if (item.items.length > 0) {\n hasAnyNesting = true;\n this._addToggleButton(div);\n\n let itemsDiv = document.createElement('div');\n itemsDiv.className = 'outlineItems';\n div.appendChild(itemsDiv);\n queue.push({ parent: itemsDiv, items: item.items, });\n }\n\n levelData.parent.appendChild(div);\n outlineCount++;\n }\n }\n if (hasAnyNesting) {\n this.container.classList.add('outlineWithDeepNesting');\n }\n\n this.container.appendChild(fragment);\n\n this._dispatchEvent(outlineCount);\n }\n}\n\nexport {\n PDFOutlineViewer,\n};\n\n\n\n// WEBPACK FOOTER //\n// web/pdf_outline_viewer.js","/* Copyright 2012 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { normalizeWheelEventDelta } from './ui_utils';\n\nconst DELAY_BEFORE_RESETTING_SWITCH_IN_PROGRESS = 1500; // in ms\nconst DELAY_BEFORE_HIDING_CONTROLS = 3000; // in ms\nconst ACTIVE_SELECTOR = 'pdfPresentationMode';\nconst CONTROLS_SELECTOR = 'pdfPresentationModeControls';\nconst MOUSE_SCROLL_COOLDOWN_TIME = 50; // in ms\nconst PAGE_SWITCH_THRESHOLD = 0.1;\n\n// Number of CSS pixels for a movement to count as a swipe.\nconst SWIPE_MIN_DISTANCE_THRESHOLD = 50;\n\n// Swipe angle deviation from the x or y axis before it is not\n// considered a swipe in that direction any more.\nconst SWIPE_ANGLE_THRESHOLD = Math.PI / 6;\n\n/**\n * @typedef {Object} PDFPresentationModeOptions\n * @property {HTMLDivElement} container - The container for the viewer element.\n * @property {HTMLDivElement} viewer - (optional) The viewer element.\n * @property {PDFViewer} pdfViewer - The document viewer.\n * @property {EventBus} eventBus - The application event bus.\n * @property {Array} contextMenuItems - (optional) The menuitems that are added\n * to the context menu in Presentation Mode.\n */\n\nclass PDFPresentationMode {\n /**\n * @param {PDFPresentationModeOptions} options\n */\n constructor({ container, viewer = null, pdfViewer, eventBus,\n contextMenuItems = null, }) {\n this.container = container;\n this.viewer = viewer || container.firstElementChild;\n this.pdfViewer = pdfViewer;\n this.eventBus = eventBus;\n\n this.active = false;\n this.args = null;\n this.contextMenuOpen = false;\n this.mouseScrollTimeStamp = 0;\n this.mouseScrollDelta = 0;\n this.touchSwipeState = null;\n\n if (contextMenuItems) {\n contextMenuItems.contextFirstPage.addEventListener('click', () => {\n this.contextMenuOpen = false;\n this.eventBus.dispatch('firstpage');\n });\n contextMenuItems.contextLastPage.addEventListener('click', () => {\n this.contextMenuOpen = false;\n this.eventBus.dispatch('lastpage');\n });\n contextMenuItems.contextPageRotateCw.addEventListener('click', () => {\n this.contextMenuOpen = false;\n this.eventBus.dispatch('rotatecw');\n });\n contextMenuItems.contextPageRotateCcw.addEventListener('click', () => {\n this.contextMenuOpen = false;\n this.eventBus.dispatch('rotateccw');\n });\n }\n }\n\n /**\n * Request the browser to enter fullscreen mode.\n * @returns {boolean} Indicating if the request was successful.\n */\n request() {\n if (this.switchInProgress || this.active || !this.viewer.hasChildNodes()) {\n return false;\n }\n this._addFullscreenChangeListeners();\n this._setSwitchInProgress();\n this._notifyStateChange();\n\n if (this.container.requestFullscreen) {\n this.container.requestFullscreen();\n } else if (this.container.mozRequestFullScreen) {\n this.container.mozRequestFullScreen();\n } else if (this.container.webkitRequestFullscreen) {\n this.container.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);\n } else if (this.container.msRequestFullscreen) {\n this.container.msRequestFullscreen();\n } else {\n return false;\n }\n\n this.args = {\n page: this.pdfViewer.currentPageNumber,\n previousScale: this.pdfViewer.currentScaleValue,\n };\n\n return true;\n }\n\n /**\n * @private\n */\n _mouseWheel(evt) {\n if (!this.active) {\n return;\n }\n\n evt.preventDefault();\n\n let delta = normalizeWheelEventDelta(evt);\n let currentTime = (new Date()).getTime();\n let storedTime = this.mouseScrollTimeStamp;\n\n // If we've already switched page, avoid accidentally switching again.\n if (currentTime > storedTime &&\n currentTime - storedTime < MOUSE_SCROLL_COOLDOWN_TIME) {\n return;\n }\n // If the scroll direction changed, reset the accumulated scroll delta.\n if ((this.mouseScrollDelta > 0 && delta < 0) ||\n (this.mouseScrollDelta < 0 && delta > 0)) {\n this._resetMouseScrollState();\n }\n this.mouseScrollDelta += delta;\n\n if (Math.abs(this.mouseScrollDelta) >= PAGE_SWITCH_THRESHOLD) {\n let totalDelta = this.mouseScrollDelta;\n this._resetMouseScrollState();\n let success = totalDelta > 0 ? this._goToPreviousPage()\n : this._goToNextPage();\n if (success) {\n this.mouseScrollTimeStamp = currentTime;\n }\n }\n }\n\n get isFullscreen() {\n return !!(document.fullscreenElement || document.mozFullScreen ||\n document.webkitIsFullScreen || document.msFullscreenElement);\n }\n\n /**\n * @private\n */\n _goToPreviousPage() {\n let page = this.pdfViewer.currentPageNumber;\n // If we're at the first page, we don't need to do anything.\n if (page <= 1) {\n return false;\n }\n this.pdfViewer.currentPageNumber = (page - 1);\n return true;\n }\n\n /**\n * @private\n */\n _goToNextPage() {\n let page = this.pdfViewer.currentPageNumber;\n // If we're at the last page, we don't need to do anything.\n if (page >= this.pdfViewer.pagesCount) {\n return false;\n }\n this.pdfViewer.currentPageNumber = (page + 1);\n return true;\n }\n\n /**\n * @private\n */\n _notifyStateChange() {\n this.eventBus.dispatch('presentationmodechanged', {\n source: this,\n active: this.active,\n switchInProgress: !!this.switchInProgress,\n });\n }\n\n /**\n * Used to initialize a timeout when requesting Presentation Mode,\n * i.e. when the browser is requested to enter fullscreen mode.\n * This timeout is used to prevent the current page from being scrolled\n * partially, or completely, out of view when entering Presentation Mode.\n * NOTE: This issue seems limited to certain zoom levels (e.g. page-width).\n *\n * @private\n */\n _setSwitchInProgress() {\n if (this.switchInProgress) {\n clearTimeout(this.switchInProgress);\n }\n this.switchInProgress = setTimeout(() => {\n this._removeFullscreenChangeListeners();\n delete this.switchInProgress;\n this._notifyStateChange();\n }, DELAY_BEFORE_RESETTING_SWITCH_IN_PROGRESS);\n }\n\n /**\n * @private\n */\n _resetSwitchInProgress() {\n if (this.switchInProgress) {\n clearTimeout(this.switchInProgress);\n delete this.switchInProgress;\n }\n }\n\n /**\n * @private\n */\n _enter() {\n this.active = true;\n this._resetSwitchInProgress();\n this._notifyStateChange();\n this.container.classList.add(ACTIVE_SELECTOR);\n\n // Ensure that the correct page is scrolled into view when entering\n // Presentation Mode, by waiting until fullscreen mode in enabled.\n setTimeout(() => {\n this.pdfViewer.currentPageNumber = this.args.page;\n this.pdfViewer.currentScaleValue = 'page-fit';\n }, 0);\n\n this._addWindowListeners();\n this._showControls();\n this.contextMenuOpen = false;\n this.container.setAttribute('contextmenu', 'viewerContextMenu');\n\n // Text selection is disabled in Presentation Mode, thus it's not possible\n // for the user to deselect text that is selected (e.g. with \"Select all\")\n // when entering Presentation Mode, hence we remove any active selection.\n window.getSelection().removeAllRanges();\n }\n\n /**\n * @private\n */\n _exit() {\n let page = this.pdfViewer.currentPageNumber;\n this.container.classList.remove(ACTIVE_SELECTOR);\n\n // Ensure that the correct page is scrolled into view when exiting\n // Presentation Mode, by waiting until fullscreen mode is disabled.\n setTimeout(() => {\n this.active = false;\n this._removeFullscreenChangeListeners();\n this._notifyStateChange();\n\n this.pdfViewer.currentScaleValue = this.args.previousScale;\n this.pdfViewer.currentPageNumber = page;\n this.args = null;\n }, 0);\n\n this._removeWindowListeners();\n this._hideControls();\n this._resetMouseScrollState();\n this.container.removeAttribute('contextmenu');\n this.contextMenuOpen = false;\n }\n\n /**\n * @private\n */\n _mouseDown(evt) {\n if (this.contextMenuOpen) {\n this.contextMenuOpen = false;\n evt.preventDefault();\n return;\n }\n if (evt.button === 0) {\n // Enable clicking of links in presentation mode. Note: only links\n // pointing to destinations in the current PDF document work.\n let isInternalLink = (evt.target.href &&\n evt.target.classList.contains('internalLink'));\n if (!isInternalLink) {\n // Unless an internal link was clicked, advance one page.\n evt.preventDefault();\n\n if (evt.shiftKey) {\n this._goToPreviousPage();\n } else {\n this._goToNextPage();\n }\n }\n }\n }\n\n /**\n * @private\n */\n _contextMenu() {\n this.contextMenuOpen = true;\n }\n\n /**\n * @private\n */\n _showControls() {\n if (this.controlsTimeout) {\n clearTimeout(this.controlsTimeout);\n } else {\n this.container.classList.add(CONTROLS_SELECTOR);\n }\n this.controlsTimeout = setTimeout(() => {\n this.container.classList.remove(CONTROLS_SELECTOR);\n delete this.controlsTimeout;\n }, DELAY_BEFORE_HIDING_CONTROLS);\n }\n\n /**\n * @private\n */\n _hideControls() {\n if (!this.controlsTimeout) {\n return;\n }\n clearTimeout(this.controlsTimeout);\n this.container.classList.remove(CONTROLS_SELECTOR);\n delete this.controlsTimeout;\n }\n\n /**\n * Resets the properties used for tracking mouse scrolling events.\n *\n * @private\n */\n _resetMouseScrollState() {\n this.mouseScrollTimeStamp = 0;\n this.mouseScrollDelta = 0;\n }\n\n /**\n * @private\n */\n _touchSwipe(evt) {\n if (!this.active) {\n return;\n }\n if (evt.touches.length > 1) {\n // Multiple touch points detected; cancel the swipe.\n this.touchSwipeState = null;\n return;\n }\n\n switch (evt.type) {\n case 'touchstart':\n this.touchSwipeState = {\n startX: evt.touches[0].pageX,\n startY: evt.touches[0].pageY,\n endX: evt.touches[0].pageX,\n endY: evt.touches[0].pageY,\n };\n break;\n case 'touchmove':\n if (this.touchSwipeState === null) {\n return;\n }\n this.touchSwipeState.endX = evt.touches[0].pageX;\n this.touchSwipeState.endY = evt.touches[0].pageY;\n // Avoid the swipe from triggering browser gestures (Chrome in\n // particular has some sort of swipe gesture in fullscreen mode).\n evt.preventDefault();\n break;\n case 'touchend':\n if (this.touchSwipeState === null) {\n return;\n }\n let delta = 0;\n let dx = this.touchSwipeState.endX - this.touchSwipeState.startX;\n let dy = this.touchSwipeState.endY - this.touchSwipeState.startY;\n let absAngle = Math.abs(Math.atan2(dy, dx));\n if (Math.abs(dx) > SWIPE_MIN_DISTANCE_THRESHOLD &&\n (absAngle <= SWIPE_ANGLE_THRESHOLD ||\n absAngle >= (Math.PI - SWIPE_ANGLE_THRESHOLD))) {\n // Horizontal swipe.\n delta = dx;\n } else if (Math.abs(dy) > SWIPE_MIN_DISTANCE_THRESHOLD &&\n Math.abs(absAngle - (Math.PI / 2)) <= SWIPE_ANGLE_THRESHOLD) {\n // Vertical swipe.\n delta = dy;\n }\n if (delta > 0) {\n this._goToPreviousPage();\n } else if (delta < 0) {\n this._goToNextPage();\n }\n break;\n }\n }\n\n /**\n * @private\n */\n _addWindowListeners() {\n this.showControlsBind = this._showControls.bind(this);\n this.mouseDownBind = this._mouseDown.bind(this);\n this.mouseWheelBind = this._mouseWheel.bind(this);\n this.resetMouseScrollStateBind = this._resetMouseScrollState.bind(this);\n this.contextMenuBind = this._contextMenu.bind(this);\n this.touchSwipeBind = this._touchSwipe.bind(this);\n\n window.addEventListener('mousemove', this.showControlsBind);\n window.addEventListener('mousedown', this.mouseDownBind);\n window.addEventListener('wheel', this.mouseWheelBind);\n window.addEventListener('keydown', this.resetMouseScrollStateBind);\n window.addEventListener('contextmenu', this.contextMenuBind);\n window.addEventListener('touchstart', this.touchSwipeBind);\n window.addEventListener('touchmove', this.touchSwipeBind);\n window.addEventListener('touchend', this.touchSwipeBind);\n }\n\n /**\n * @private\n */\n _removeWindowListeners() {\n window.removeEventListener('mousemove', this.showControlsBind);\n window.removeEventListener('mousedown', this.mouseDownBind);\n window.removeEventListener('wheel', this.mouseWheelBind);\n window.removeEventListener('keydown', this.resetMouseScrollStateBind);\n window.removeEventListener('contextmenu', this.contextMenuBind);\n window.removeEventListener('touchstart', this.touchSwipeBind);\n window.removeEventListener('touchmove', this.touchSwipeBind);\n window.removeEventListener('touchend', this.touchSwipeBind);\n\n delete this.showControlsBind;\n delete this.mouseDownBind;\n delete this.mouseWheelBind;\n delete this.resetMouseScrollStateBind;\n delete this.contextMenuBind;\n delete this.touchSwipeBind;\n }\n\n /**\n * @private\n */\n _fullscreenChange() {\n if (this.isFullscreen) {\n this._enter();\n } else {\n this._exit();\n }\n }\n\n /**\n * @private\n */\n _addFullscreenChangeListeners() {\n this.fullscreenChangeBind = this._fullscreenChange.bind(this);\n\n window.addEventListener('fullscreenchange', this.fullscreenChangeBind);\n window.addEventListener('mozfullscreenchange', this.fullscreenChangeBind);\n if (typeof PDFJSDev === 'undefined' ||\n !PDFJSDev.test('FIREFOX || MOZCENTRAL')) {\n window.addEventListener('webkitfullscreenchange',\n this.fullscreenChangeBind);\n window.addEventListener('MSFullscreenChange',\n this.fullscreenChangeBind);\n }\n }\n\n /**\n * @private\n */\n _removeFullscreenChangeListeners() {\n window.removeEventListener('fullscreenchange', this.fullscreenChangeBind);\n window.removeEventListener('mozfullscreenchange',\n this.fullscreenChangeBind);\n if (typeof PDFJSDev === 'undefined' ||\n !PDFJSDev.test('FIREFOX || MOZCENTRAL')) {\n window.removeEventListener('webkitfullscreenchange',\n this.fullscreenChangeBind);\n window.removeEventListener('MSFullscreenChange',\n this.fullscreenChangeBind);\n }\n\n delete this.fullscreenChangeBind;\n }\n}\n\nexport {\n PDFPresentationMode,\n};\n\n\n\n// WEBPACK FOOTER //\n// web/pdf_presentation_mode.js","/* Copyright 2012 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n getVisibleElements, isValidRotation, NullL10n, scrollIntoView, watchScroll\n} from './ui_utils';\nimport { PDFThumbnailView } from './pdf_thumbnail_view';\n\nconst THUMBNAIL_SCROLL_MARGIN = -19;\n\n/**\n * @typedef {Object} PDFThumbnailViewerOptions\n * @property {HTMLDivElement} container - The container for the thumbnail\n * elements.\n * @property {IPDFLinkService} linkService - The navigation/linking service.\n * @property {PDFRenderingQueue} renderingQueue - The rendering queue object.\n * @property {IL10n} l10n - Localization service.\n */\n\n/**\n * Viewer control to display thumbnails for pages in a PDF document.\n *\n * @implements {IRenderableView}\n */\nclass PDFThumbnailViewer {\n /**\n * @param {PDFThumbnailViewerOptions} options\n */\n constructor({ container, linkService, renderingQueue, l10n = NullL10n, }) {\n this.container = container;\n this.linkService = linkService;\n this.renderingQueue = renderingQueue;\n this.l10n = l10n;\n\n this.scroll = watchScroll(this.container, this._scrollUpdated.bind(this));\n this._resetView();\n }\n\n /**\n * @private\n */\n _scrollUpdated() {\n this.renderingQueue.renderHighestPriority();\n }\n\n getThumbnail(index) {\n return this._thumbnails[index];\n }\n\n /**\n * @private\n */\n _getVisibleThumbs() {\n return getVisibleElements(this.container, this._thumbnails);\n }\n\n scrollThumbnailIntoView(page) {\n let selected = document.querySelector('.thumbnail.selected');\n if (selected) {\n selected.classList.remove('selected');\n }\n let thumbnail = document.querySelector(\n 'div.thumbnail[data-page-number=\"' + page + '\"]');\n if (thumbnail) {\n thumbnail.classList.add('selected');\n }\n let visibleThumbs = this._getVisibleThumbs();\n let numVisibleThumbs = visibleThumbs.views.length;\n\n // If the thumbnail isn't currently visible, scroll it into view.\n if (numVisibleThumbs > 0) {\n let first = visibleThumbs.first.id;\n // Account for only one thumbnail being visible.\n let last = (numVisibleThumbs > 1 ? visibleThumbs.last.id : first);\n if (page <= first || page >= last) {\n scrollIntoView(thumbnail, { top: THUMBNAIL_SCROLL_MARGIN, });\n }\n }\n }\n\n get pagesRotation() {\n return this._pagesRotation;\n }\n\n set pagesRotation(rotation) {\n if (!isValidRotation(rotation)) {\n throw new Error('Invalid thumbnails rotation angle.');\n }\n if (!this.pdfDocument) {\n return;\n }\n if (this._pagesRotation === rotation) {\n return; // The rotation didn't change.\n }\n this._pagesRotation = rotation;\n\n for (let i = 0, ii = this._thumbnails.length; i < ii; i++) {\n this._thumbnails[i].update(rotation);\n }\n }\n\n cleanup() {\n PDFThumbnailView.cleanup();\n }\n\n /**\n * @private\n */\n _resetView() {\n this._thumbnails = [];\n this._pageLabels = null;\n this._pagesRotation = 0;\n this._pagesRequests = [];\n\n // Remove the thumbnails from the DOM.\n this.container.textContent = '';\n }\n\n setDocument(pdfDocument) {\n if (this.pdfDocument) {\n this._cancelRendering();\n this._resetView();\n }\n\n this.pdfDocument = pdfDocument;\n if (!pdfDocument) {\n return;\n }\n\n pdfDocument.getPage(1).then((firstPage) => {\n let pagesCount = pdfDocument.numPages;\n let viewport = firstPage.getViewport(1.0);\n for (let pageNum = 1; pageNum <= pagesCount; ++pageNum) {\n let thumbnail = new PDFThumbnailView({\n container: this.container,\n id: pageNum,\n defaultViewport: viewport.clone(),\n linkService: this.linkService,\n renderingQueue: this.renderingQueue,\n disableCanvasToImageConversion: false,\n l10n: this.l10n,\n });\n this._thumbnails.push(thumbnail);\n }\n }).catch((reason) => {\n console.error('Unable to initialize thumbnail viewer', reason);\n });\n }\n\n /**\n * @private\n */\n _cancelRendering() {\n for (let i = 0, ii = this._thumbnails.length; i < ii; i++) {\n if (this._thumbnails[i]) {\n this._thumbnails[i].cancelRendering();\n }\n }\n }\n\n /**\n * @param {Array|null} labels\n */\n setPageLabels(labels) {\n if (!this.pdfDocument) {\n return;\n }\n if (!labels) {\n this._pageLabels = null;\n } else if (!(labels instanceof Array &&\n this.pdfDocument.numPages === labels.length)) {\n this._pageLabels = null;\n console.error('PDFThumbnailViewer_setPageLabels: Invalid page labels.');\n } else {\n this._pageLabels = labels;\n }\n // Update all the `PDFThumbnailView` instances.\n for (let i = 0, ii = this._thumbnails.length; i < ii; i++) {\n let label = this._pageLabels && this._pageLabels[i];\n this._thumbnails[i].setPageLabel(label);\n }\n }\n\n /**\n * @param {PDFThumbnailView} thumbView\n * @returns {PDFPage}\n * @private\n */\n _ensurePdfPageLoaded(thumbView) {\n if (thumbView.pdfPage) {\n return Promise.resolve(thumbView.pdfPage);\n }\n let pageNumber = thumbView.id;\n if (this._pagesRequests[pageNumber]) {\n return this._pagesRequests[pageNumber];\n }\n let promise = this.pdfDocument.getPage(pageNumber).then((pdfPage) => {\n thumbView.setPdfPage(pdfPage);\n this._pagesRequests[pageNumber] = null;\n return pdfPage;\n }).catch((reason) => {\n console.error('Unable to get page for thumb view', reason);\n // Page error -- there is nothing can be done.\n this._pagesRequests[pageNumber] = null;\n });\n this._pagesRequests[pageNumber] = promise;\n return promise;\n }\n\n forceRendering() {\n let visibleThumbs = this._getVisibleThumbs();\n let thumbView = this.renderingQueue.getHighestPriority(visibleThumbs,\n this._thumbnails,\n this.scroll.down);\n if (thumbView) {\n this._ensurePdfPageLoaded(thumbView).then(() => {\n this.renderingQueue.renderView(thumbView);\n });\n return true;\n }\n return false;\n }\n}\n\nexport {\n PDFThumbnailViewer,\n};\n\n\n\n// WEBPACK FOOTER //\n// web/pdf_thumbnail_viewer.js","/* Copyright 2012 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n createPromiseCapability, RenderingCancelledException\n} from 'pdfjs-lib';\nimport { getOutputScale, NullL10n } from './ui_utils';\nimport { RenderingStates } from './pdf_rendering_queue';\n\nconst MAX_NUM_SCALING_STEPS = 3;\nconst THUMBNAIL_CANVAS_BORDER_WIDTH = 1; // px\nconst THUMBNAIL_WIDTH = 98; // px\n\n/**\n * @typedef {Object} PDFThumbnailViewOptions\n * @property {HTMLDivElement} container - The viewer element.\n * @property {number} id - The thumbnail's unique ID (normally its number).\n * @property {PageViewport} defaultViewport - The page viewport.\n * @property {IPDFLinkService} linkService - The navigation/linking service.\n * @property {PDFRenderingQueue} renderingQueue - The rendering queue object.\n * @property {boolean} disableCanvasToImageConversion - (optional) Don't convert\n * the canvas thumbnails to images. This prevents `toDataURL` calls,\n * but increases the overall memory usage. The default value is `false`.\n * @property {IL10n} l10n - Localization service.\n */\n\nconst TempImageFactory = (function TempImageFactoryClosure() {\n let tempCanvasCache = null;\n\n return {\n getCanvas(width, height) {\n let tempCanvas = tempCanvasCache;\n if (!tempCanvas) {\n tempCanvas = document.createElement('canvas');\n tempCanvasCache = tempCanvas;\n }\n tempCanvas.width = width;\n tempCanvas.height = height;\n\n // Since this is a temporary canvas, we need to fill it with a white\n // background ourselves. `_getPageDrawContext` uses CSS rules for this.\n if (typeof PDFJSDev === 'undefined' ||\n PDFJSDev.test('MOZCENTRAL || FIREFOX || GENERIC')) {\n tempCanvas.mozOpaque = true;\n }\n\n let ctx = tempCanvas.getContext('2d', { alpha: false, });\n ctx.save();\n ctx.fillStyle = 'rgb(255, 255, 255)';\n ctx.fillRect(0, 0, width, height);\n ctx.restore();\n return tempCanvas;\n },\n\n destroyCanvas() {\n let tempCanvas = tempCanvasCache;\n if (tempCanvas) {\n // Zeroing the width and height causes Firefox to release graphics\n // resources immediately, which can greatly reduce memory consumption.\n tempCanvas.width = 0;\n tempCanvas.height = 0;\n }\n tempCanvasCache = null;\n },\n };\n})();\n\n/**\n * @implements {IRenderableView}\n */\nclass PDFThumbnailView {\n /**\n * @param {PDFThumbnailViewOptions} options\n */\n constructor({ container, id, defaultViewport, linkService, renderingQueue,\n disableCanvasToImageConversion = false, l10n = NullL10n, }) {\n this.id = id;\n this.renderingId = 'thumbnail' + id;\n this.pageLabel = null;\n\n this.pdfPage = null;\n this.rotation = 0;\n this.viewport = defaultViewport;\n this.pdfPageRotate = defaultViewport.rotation;\n\n this.linkService = linkService;\n this.renderingQueue = renderingQueue;\n\n this.renderTask = null;\n this.renderingState = RenderingStates.INITIAL;\n this.resume = null;\n this.disableCanvasToImageConversion = disableCanvasToImageConversion;\n\n this.pageWidth = this.viewport.width;\n this.pageHeight = this.viewport.height;\n this.pageRatio = this.pageWidth / this.pageHeight;\n\n this.canvasWidth = THUMBNAIL_WIDTH;\n this.canvasHeight = (this.canvasWidth / this.pageRatio) | 0;\n this.scale = this.canvasWidth / this.pageWidth;\n\n this.l10n = l10n;\n\n let anchor = document.createElement('a');\n anchor.href = linkService.getAnchorUrl('#page=' + id);\n this.l10n.get('thumb_page_title', { page: id, }, 'Page {{page}}').\n then((msg) => {\n anchor.title = msg;\n });\n anchor.onclick = function() {\n linkService.page = id;\n return false;\n };\n this.anchor = anchor;\n\n let div = document.createElement('div');\n div.className = 'thumbnail';\n div.setAttribute('data-page-number', this.id);\n this.div = div;\n\n if (id === 1) {\n // Highlight the thumbnail of the first page when no page number is\n // specified (or exists in cache) when the document is loaded.\n div.classList.add('selected');\n }\n\n let ring = document.createElement('div');\n ring.className = 'thumbnailSelectionRing';\n let borderAdjustment = 2 * THUMBNAIL_CANVAS_BORDER_WIDTH;\n ring.style.width = this.canvasWidth + borderAdjustment + 'px';\n ring.style.height = this.canvasHeight + borderAdjustment + 'px';\n this.ring = ring;\n\n div.appendChild(ring);\n anchor.appendChild(div);\n container.appendChild(anchor);\n }\n\n setPdfPage(pdfPage) {\n this.pdfPage = pdfPage;\n this.pdfPageRotate = pdfPage.rotate;\n let totalRotation = (this.rotation + this.pdfPageRotate) % 360;\n this.viewport = pdfPage.getViewport(1, totalRotation);\n this.reset();\n }\n\n reset() {\n this.cancelRendering();\n\n this.pageWidth = this.viewport.width;\n this.pageHeight = this.viewport.height;\n this.pageRatio = this.pageWidth / this.pageHeight;\n\n this.canvasHeight = (this.canvasWidth / this.pageRatio) | 0;\n this.scale = (this.canvasWidth / this.pageWidth);\n\n this.div.removeAttribute('data-loaded');\n let ring = this.ring;\n let childNodes = ring.childNodes;\n for (let i = childNodes.length - 1; i >= 0; i--) {\n ring.removeChild(childNodes[i]);\n }\n let borderAdjustment = 2 * THUMBNAIL_CANVAS_BORDER_WIDTH;\n ring.style.width = this.canvasWidth + borderAdjustment + 'px';\n ring.style.height = this.canvasHeight + borderAdjustment + 'px';\n\n if (this.canvas) {\n // Zeroing the width and height causes Firefox to release graphics\n // resources immediately, which can greatly reduce memory consumption.\n this.canvas.width = 0;\n this.canvas.height = 0;\n delete this.canvas;\n }\n if (this.image) {\n this.image.removeAttribute('src');\n delete this.image;\n }\n }\n\n update(rotation) {\n if (typeof rotation !== 'undefined') {\n this.rotation = rotation;\n }\n let totalRotation = (this.rotation + this.pdfPageRotate) % 360;\n this.viewport = this.viewport.clone({\n scale: 1,\n rotation: totalRotation,\n });\n this.reset();\n }\n\n cancelRendering() {\n if (this.renderTask) {\n this.renderTask.cancel();\n this.renderTask = null;\n }\n this.renderingState = RenderingStates.INITIAL;\n this.resume = null;\n }\n\n /**\n * @private\n */\n _getPageDrawContext(noCtxScale = false) {\n let canvas = document.createElement('canvas');\n // Keep the no-thumbnail outline visible, i.e. `data-loaded === false`,\n // until rendering/image conversion is complete, to avoid display issues.\n this.canvas = canvas;\n\n if (typeof PDFJSDev === 'undefined' ||\n PDFJSDev.test('MOZCENTRAL || FIREFOX || GENERIC')) {\n canvas.mozOpaque = true;\n }\n let ctx = canvas.getContext('2d', { alpha: false, });\n let outputScale = getOutputScale(ctx);\n\n canvas.width = (this.canvasWidth * outputScale.sx) | 0;\n canvas.height = (this.canvasHeight * outputScale.sy) | 0;\n canvas.style.width = this.canvasWidth + 'px';\n canvas.style.height = this.canvasHeight + 'px';\n\n if (!noCtxScale && outputScale.scaled) {\n ctx.scale(outputScale.sx, outputScale.sy);\n }\n return ctx;\n }\n\n /**\n * @private\n */\n _convertCanvasToImage() {\n if (!this.canvas) {\n return;\n }\n if (this.renderingState !== RenderingStates.FINISHED) {\n return;\n }\n let id = this.renderingId;\n let className = 'thumbnailImage';\n\n if (this.disableCanvasToImageConversion) {\n this.canvas.id = id;\n this.canvas.className = className;\n this.l10n.get('thumb_page_canvas', { page: this.pageId, },\n 'Thumbnail of Page {{page}}').then((msg) => {\n this.canvas.setAttribute('aria-label', msg);\n });\n\n this.div.setAttribute('data-loaded', true);\n this.ring.appendChild(this.canvas);\n return;\n }\n let image = document.createElement('img');\n image.id = id;\n image.className = className;\n this.l10n.get('thumb_page_canvas', { page: this.pageId, },\n 'Thumbnail of Page {{page}}').\n then((msg) => {\n image.setAttribute('aria-label', msg);\n });\n\n image.style.width = this.canvasWidth + 'px';\n image.style.height = this.canvasHeight + 'px';\n\n image.src = this.canvas.toDataURL();\n this.image = image;\n\n this.div.setAttribute('data-loaded', true);\n this.ring.appendChild(image);\n\n // Zeroing the width and height causes Firefox to release graphics\n // resources immediately, which can greatly reduce memory consumption.\n this.canvas.width = 0;\n this.canvas.height = 0;\n delete this.canvas;\n }\n\n draw() {\n if (this.renderingState !== RenderingStates.INITIAL) {\n console.error('Must be in new state before drawing');\n return Promise.resolve(undefined);\n }\n this.renderingState = RenderingStates.RUNNING;\n\n let renderCapability = createPromiseCapability();\n let finishRenderTask = (error) => {\n // The renderTask may have been replaced by a new one, so only remove\n // the reference to the renderTask if it matches the one that is\n // triggering this callback.\n if (renderTask === this.renderTask) {\n this.renderTask = null;\n }\n\n if (((typeof PDFJSDev === 'undefined' ||\n !PDFJSDev.test('PDFJS_NEXT')) && error === 'cancelled') ||\n error instanceof RenderingCancelledException) {\n renderCapability.resolve(undefined);\n return;\n }\n\n this.renderingState = RenderingStates.FINISHED;\n this._convertCanvasToImage();\n\n if (!error) {\n renderCapability.resolve(undefined);\n } else {\n renderCapability.reject(error);\n }\n };\n\n let ctx = this._getPageDrawContext();\n let drawViewport = this.viewport.clone({ scale: this.scale, });\n let renderContinueCallback = (cont) => {\n if (!this.renderingQueue.isHighestPriority(this)) {\n this.renderingState = RenderingStates.PAUSED;\n this.resume = () => {\n this.renderingState = RenderingStates.RUNNING;\n cont();\n };\n return;\n }\n cont();\n };\n\n let renderContext = {\n canvasContext: ctx,\n viewport: drawViewport,\n };\n let renderTask = this.renderTask = this.pdfPage.render(renderContext);\n renderTask.onContinue = renderContinueCallback;\n\n renderTask.promise.then(function() {\n finishRenderTask(null);\n }, function(error) {\n finishRenderTask(error);\n });\n return renderCapability.promise;\n }\n\n setImage(pageView) {\n if (this.renderingState !== RenderingStates.INITIAL) {\n return;\n }\n let img = pageView.canvas;\n if (!img) {\n return;\n }\n if (!this.pdfPage) {\n this.setPdfPage(pageView.pdfPage);\n }\n\n this.renderingState = RenderingStates.FINISHED;\n\n let ctx = this._getPageDrawContext(true);\n let canvas = ctx.canvas;\n if (img.width <= 2 * canvas.width) {\n ctx.drawImage(img, 0, 0, img.width, img.height,\n 0, 0, canvas.width, canvas.height);\n this._convertCanvasToImage();\n return;\n }\n\n // drawImage does an awful job of rescaling the image, doing it gradually.\n let reducedWidth = canvas.width << MAX_NUM_SCALING_STEPS;\n let reducedHeight = canvas.height << MAX_NUM_SCALING_STEPS;\n let reducedImage = TempImageFactory.getCanvas(reducedWidth,\n reducedHeight);\n let reducedImageCtx = reducedImage.getContext('2d');\n\n while (reducedWidth > img.width || reducedHeight > img.height) {\n reducedWidth >>= 1;\n reducedHeight >>= 1;\n }\n reducedImageCtx.drawImage(img, 0, 0, img.width, img.height,\n 0, 0, reducedWidth, reducedHeight);\n while (reducedWidth > 2 * canvas.width) {\n reducedImageCtx.drawImage(reducedImage,\n 0, 0, reducedWidth, reducedHeight,\n 0, 0, reducedWidth >> 1, reducedHeight >> 1);\n reducedWidth >>= 1;\n reducedHeight >>= 1;\n }\n ctx.drawImage(reducedImage, 0, 0, reducedWidth, reducedHeight,\n 0, 0, canvas.width, canvas.height);\n this._convertCanvasToImage();\n }\n\n get pageId() {\n return (this.pageLabel !== null ? this.pageLabel : this.id);\n }\n\n /**\n * @param {string|null} label\n */\n setPageLabel(label) {\n this.pageLabel = (typeof label === 'string' ? label : null);\n\n this.l10n.get('thumb_page_title', { page: this.pageId, },\n 'Page {{page}}').then((msg) => {\n this.anchor.title = msg;\n });\n\n if (this.renderingState !== RenderingStates.FINISHED) {\n return;\n }\n\n this.l10n.get('thumb_page_canvas', { page: this.pageId, },\n 'Thumbnail of Page {{page}}').then((ariaLabel) => {\n if (this.image) {\n this.image.setAttribute('aria-label', ariaLabel);\n } else if (this.disableCanvasToImageConversion && this.canvas) {\n this.canvas.setAttribute('aria-label', ariaLabel);\n }\n });\n }\n\n static cleanup() {\n TempImageFactory.destroyCanvas();\n }\n}\n\nexport {\n PDFThumbnailView,\n};\n\n\n\n// WEBPACK FOOTER //\n// web/pdf_thumbnail_view.js","/* Copyright 2014 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getVisibleElements, scrollIntoView } from './ui_utils';\nimport { BaseViewer } from './base_viewer';\nimport { shadow } from 'pdfjs-lib';\n\nclass PDFViewer extends BaseViewer {\n get _setDocumentViewerElement() {\n return shadow(this, '_setDocumentViewerElement', this.viewer);\n }\n\n _scrollIntoView({ pageDiv, pageSpot = null, }) {\n scrollIntoView(pageDiv, pageSpot);\n }\n\n _getVisiblePages() {\n if (!this.isInPresentationMode) {\n return getVisibleElements(this.container, this._pages, true);\n }\n // The algorithm in getVisibleElements doesn't work in all browsers and\n // configurations when presentation mode is active.\n let currentPage = this._pages[this._currentPageNumber - 1];\n let visible = [{ id: currentPage.id, view: currentPage, }];\n return { first: currentPage, last: currentPage, views: visible, };\n }\n\n update() {\n let visible = this._getVisiblePages();\n let visiblePages = visible.views, numVisiblePages = visiblePages.length;\n\n if (numVisiblePages === 0) {\n return;\n }\n this._resizeBuffer(numVisiblePages);\n\n this.renderingQueue.renderHighestPriority(visible);\n\n let currentId = this._currentPageNumber;\n let stillFullyVisible = false;\n\n for (let i = 0; i < numVisiblePages; ++i) {\n let page = visiblePages[i];\n\n if (page.percent < 100) {\n break;\n }\n if (page.id === currentId) {\n stillFullyVisible = true;\n break;\n }\n }\n\n if (!stillFullyVisible) {\n currentId = visiblePages[0].id;\n }\n if (!this.isInPresentationMode) {\n this._setCurrentPageNumber(currentId);\n }\n\n this._updateLocation(visible.first);\n this.eventBus.dispatch('updateviewarea', {\n source: this,\n location: this._location,\n });\n }\n}\n\nexport {\n PDFViewer,\n};\n\n\n\n// WEBPACK FOOTER //\n// web/pdf_viewer.js","/* Copyright 2014 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { createPromiseCapability, PDFJS } from 'pdfjs-lib';\nimport {\n CSS_UNITS, DEFAULT_SCALE, DEFAULT_SCALE_VALUE, isValidRotation,\n MAX_AUTO_SCALE, NullL10n, PresentationModeState, RendererType,\n SCROLLBAR_PADDING, UNKNOWN_SCALE, VERTICAL_PADDING, watchScroll\n} from './ui_utils';\nimport { PDFRenderingQueue, RenderingStates } from './pdf_rendering_queue';\nimport { AnnotationLayerBuilder } from './annotation_layer_builder';\nimport { getGlobalEventBus } from './dom_events';\nimport { PDFPageView } from './pdf_page_view';\nimport { SimpleLinkService } from './pdf_link_service';\nimport { TextLayerBuilder } from './text_layer_builder';\n\nconst DEFAULT_CACHE_SIZE = 10;\n\n/**\n * @typedef {Object} PDFViewerOptions\n * @property {HTMLDivElement} container - The container for the viewer element.\n * @property {HTMLDivElement} viewer - (optional) The viewer element.\n * @property {EventBus} eventBus - The application event bus.\n * @property {IPDFLinkService} linkService - The navigation/linking service.\n * @property {DownloadManager} downloadManager - (optional) The download\n * manager component.\n * @property {PDFRenderingQueue} renderingQueue - (optional) The rendering\n * queue object.\n * @property {boolean} removePageBorders - (optional) Removes the border shadow\n * around the pages. The default is false.\n * @property {boolean} enhanceTextSelection - (optional) Enables the improved\n * text selection behaviour. The default is `false`.\n * @property {boolean} renderInteractiveForms - (optional) Enables rendering of\n * interactive form elements. The default is `false`.\n * @property {boolean} enablePrintAutoRotate - (optional) Enables automatic\n * rotation of pages whose orientation differ from the first page upon\n * printing. The default is `false`.\n * @property {string} renderer - 'canvas' or 'svg'. The default is 'canvas'.\n * @property {IL10n} l10n - Localization service.\n */\n\nfunction PDFPageViewBuffer(size) {\n let data = [];\n this.push = function(view) {\n let i = data.indexOf(view);\n if (i >= 0) {\n data.splice(i, 1);\n }\n data.push(view);\n if (data.length > size) {\n data.shift().destroy();\n }\n };\n this.resize = function(newSize) {\n size = newSize;\n while (data.length > size) {\n data.shift().destroy();\n }\n };\n}\n\nfunction isSameScale(oldScale, newScale) {\n if (newScale === oldScale) {\n return true;\n }\n if (Math.abs(newScale - oldScale) < 1e-15) {\n // Prevent unnecessary re-rendering of all pages when the scale\n // changes only because of limited numerical precision.\n return true;\n }\n return false;\n}\n\nfunction isPortraitOrientation(size) {\n return size.width <= size.height;\n}\n\n/**\n * Simple viewer control to display PDF content/pages.\n * @implements {IRenderableView}\n */\nclass BaseViewer {\n /**\n * @param {PDFViewerOptions} options\n */\n constructor(options) {\n if (this.constructor === BaseViewer) {\n throw new Error('Cannot initialize BaseViewer.');\n }\n this._name = this.constructor.name;\n\n this.container = options.container;\n this.viewer = options.viewer || options.container.firstElementChild;\n this.eventBus = options.eventBus || getGlobalEventBus();\n this.linkService = options.linkService || new SimpleLinkService();\n this.downloadManager = options.downloadManager || null;\n this.removePageBorders = options.removePageBorders || false;\n this.enhanceTextSelection = options.enhanceTextSelection || false;\n this.renderInteractiveForms = options.renderInteractiveForms || false;\n this.enablePrintAutoRotate = options.enablePrintAutoRotate || false;\n this.renderer = options.renderer || RendererType.CANVAS;\n this.l10n = options.l10n || NullL10n;\n\n this.defaultRenderingQueue = !options.renderingQueue;\n if (this.defaultRenderingQueue) {\n // Custom rendering queue is not specified, using default one\n this.renderingQueue = new PDFRenderingQueue();\n this.renderingQueue.setViewer(this);\n } else {\n this.renderingQueue = options.renderingQueue;\n }\n\n this.scroll = watchScroll(this.container, this._scrollUpdate.bind(this));\n this.presentationModeState = PresentationModeState.UNKNOWN;\n this._resetView();\n\n if (this.removePageBorders) {\n this.viewer.classList.add('removePageBorders');\n }\n }\n\n get pagesCount() {\n return this._pages.length;\n }\n\n getPageView(index) {\n return this._pages[index];\n }\n\n /**\n * @returns {boolean} true if all {PDFPageView} objects are initialized.\n */\n get pageViewsReady() {\n return this._pageViewsReady;\n }\n\n /**\n * @returns {number}\n */\n get currentPageNumber() {\n return this._currentPageNumber;\n }\n\n /**\n * @param {number} val - The page number.\n */\n set currentPageNumber(val) {\n if (!Number.isInteger(val)) {\n throw new Error('Invalid page number.');\n }\n if (!this.pdfDocument) {\n return;\n }\n // The intent can be to just reset a scroll position and/or scale.\n this._setCurrentPageNumber(val, /* resetCurrentPageView = */ true);\n }\n\n /**\n * @private\n */\n _setCurrentPageNumber(val, resetCurrentPageView = false) {\n if (this._currentPageNumber === val) {\n if (resetCurrentPageView) {\n this._resetCurrentPageView();\n }\n return;\n }\n\n if (!(0 < val && val <= this.pagesCount)) {\n console.error(\n `${this._name}._setCurrentPageNumber: \"${val}\" is out of bounds.`);\n return;\n }\n\n let arg = {\n source: this,\n pageNumber: val,\n pageLabel: this._pageLabels && this._pageLabels[val - 1],\n };\n this._currentPageNumber = val;\n this.eventBus.dispatch('pagechanging', arg);\n this.eventBus.dispatch('pagechange', arg);\n\n if (resetCurrentPageView) {\n this._resetCurrentPageView();\n }\n }\n\n /**\n * @returns {string|null} Returns the current page label,\n * or `null` if no page labels exist.\n */\n get currentPageLabel() {\n return this._pageLabels && this._pageLabels[this._currentPageNumber - 1];\n }\n\n /**\n * @param {string} val - The page label.\n */\n set currentPageLabel(val) {\n let pageNumber = val | 0; // Fallback page number.\n if (this._pageLabels) {\n let i = this._pageLabels.indexOf(val);\n if (i >= 0) {\n pageNumber = i + 1;\n }\n }\n this.currentPageNumber = pageNumber;\n }\n\n /**\n * @returns {number}\n */\n get currentScale() {\n return this._currentScale !== UNKNOWN_SCALE ? this._currentScale :\n DEFAULT_SCALE;\n }\n\n /**\n * @param {number} val - Scale of the pages in percents.\n */\n set currentScale(val) {\n if (isNaN(val)) {\n throw new Error('Invalid numeric scale');\n }\n if (!this.pdfDocument) {\n return;\n }\n this._setScale(val, false);\n }\n\n /**\n * @returns {string}\n */\n get currentScaleValue() {\n return this._currentScaleValue;\n }\n\n /**\n * @param val - The scale of the pages (in percent or predefined value).\n */\n set currentScaleValue(val) {\n if (!this.pdfDocument) {\n return;\n }\n this._setScale(val, false);\n }\n\n /**\n * @returns {number}\n */\n get pagesRotation() {\n return this._pagesRotation;\n }\n\n /**\n * @param {number} rotation - The rotation of the pages (0, 90, 180, 270).\n */\n set pagesRotation(rotation) {\n if (!isValidRotation(rotation)) {\n throw new Error('Invalid pages rotation angle.');\n }\n if (!this.pdfDocument) {\n return;\n }\n if (this._pagesRotation === rotation) {\n return; // The rotation didn't change.\n }\n this._pagesRotation = rotation;\n\n let pageNumber = this._currentPageNumber;\n\n for (let i = 0, ii = this._pages.length; i < ii; i++) {\n let pageView = this._pages[i];\n pageView.update(pageView.scale, rotation);\n }\n // Prevent errors in case the rotation changes *before* the scale has been\n // set to a non-default value.\n if (this._currentScaleValue) {\n this._setScale(this._currentScaleValue, true);\n }\n\n this.eventBus.dispatch('rotationchanging', {\n source: this,\n pagesRotation: rotation,\n pageNumber,\n });\n\n if (this.defaultRenderingQueue) {\n this.update();\n }\n }\n\n get _setDocumentViewerElement() {\n throw new Error('Not implemented: _setDocumentViewerElement');\n }\n\n /**\n * @param pdfDocument {PDFDocument}\n */\n setDocument(pdfDocument) {\n if (this.pdfDocument) {\n this._cancelRendering();\n this._resetView();\n }\n\n this.pdfDocument = pdfDocument;\n if (!pdfDocument) {\n return;\n }\n let pagesCount = pdfDocument.numPages;\n\n let pagesCapability = createPromiseCapability();\n this.pagesPromise = pagesCapability.promise;\n\n pagesCapability.promise.then(() => {\n this._pageViewsReady = true;\n this.eventBus.dispatch('pagesloaded', {\n source: this,\n pagesCount,\n });\n });\n\n let isOnePageRenderedResolved = false;\n let onePageRenderedCapability = createPromiseCapability();\n this.onePageRendered = onePageRenderedCapability.promise;\n\n let bindOnAfterAndBeforeDraw = (pageView) => {\n pageView.onBeforeDraw = () => {\n // Add the page to the buffer at the start of drawing. That way it can\n // be evicted from the buffer and destroyed even if we pause its\n // rendering.\n this._buffer.push(pageView);\n };\n pageView.onAfterDraw = () => {\n if (!isOnePageRenderedResolved) {\n isOnePageRenderedResolved = true;\n onePageRenderedCapability.resolve();\n }\n };\n };\n\n let firstPagePromise = pdfDocument.getPage(1);\n this.firstPagePromise = firstPagePromise;\n\n // Fetch a single page so we can get a viewport that will be the default\n // viewport for all pages\n firstPagePromise.then((pdfPage) => {\n let scale = this.currentScale;\n let viewport = pdfPage.getViewport(scale * CSS_UNITS);\n for (let pageNum = 1; pageNum <= pagesCount; ++pageNum) {\n let textLayerFactory = null;\n if (!PDFJS.disableTextLayer) {\n textLayerFactory = this;\n }\n let pageView = new PDFPageView({\n container: this._setDocumentViewerElement,\n eventBus: this.eventBus,\n id: pageNum,\n scale,\n defaultViewport: viewport.clone(),\n renderingQueue: this.renderingQueue,\n textLayerFactory,\n annotationLayerFactory: this,\n enhanceTextSelection: this.enhanceTextSelection,\n renderInteractiveForms: this.renderInteractiveForms,\n renderer: this.renderer,\n l10n: this.l10n,\n });\n bindOnAfterAndBeforeDraw(pageView);\n this._pages.push(pageView);\n }\n\n // Fetch all the pages since the viewport is needed before printing\n // starts to create the correct size canvas. Wait until one page is\n // rendered so we don't tie up too many resources early on.\n onePageRenderedCapability.promise.then(() => {\n if (PDFJS.disableAutoFetch) {\n // XXX: Printing is semi-broken with auto fetch disabled.\n pagesCapability.resolve();\n return;\n }\n let getPagesLeft = pagesCount;\n for (let pageNum = 1; pageNum <= pagesCount; ++pageNum) {\n pdfDocument.getPage(pageNum).then((pdfPage) => {\n let pageView = this._pages[pageNum - 1];\n if (!pageView.pdfPage) {\n pageView.setPdfPage(pdfPage);\n }\n this.linkService.cachePageRef(pageNum, pdfPage.ref);\n if (--getPagesLeft === 0) {\n pagesCapability.resolve();\n }\n }, (reason) => {\n console.error(`Unable to get page ${pageNum} to initialize viewer`,\n reason);\n if (--getPagesLeft === 0) {\n pagesCapability.resolve();\n }\n });\n }\n });\n\n this.eventBus.dispatch('pagesinit', { source: this, });\n\n if (this.defaultRenderingQueue) {\n this.update();\n }\n\n if (this.findController) {\n this.findController.resolveFirstPage();\n }\n }).catch((reason) => {\n console.error('Unable to initialize viewer', reason);\n });\n }\n\n /**\n * @param {Array|null} labels\n */\n setPageLabels(labels) {\n if (!this.pdfDocument) {\n return;\n }\n if (!labels) {\n this._pageLabels = null;\n } else if (!(labels instanceof Array &&\n this.pdfDocument.numPages === labels.length)) {\n this._pageLabels = null;\n console.error(`${this._name}.setPageLabels: Invalid page labels.`);\n } else {\n this._pageLabels = labels;\n }\n // Update all the `PDFPageView` instances.\n for (let i = 0, ii = this._pages.length; i < ii; i++) {\n let pageView = this._pages[i];\n let label = this._pageLabels && this._pageLabels[i];\n pageView.setPageLabel(label);\n }\n }\n\n _resetView() {\n this._pages = [];\n this._currentPageNumber = 1;\n this._currentScale = UNKNOWN_SCALE;\n this._currentScaleValue = null;\n this._pageLabels = null;\n this._buffer = new PDFPageViewBuffer(DEFAULT_CACHE_SIZE);\n this._location = null;\n this._pagesRotation = 0;\n this._pagesRequests = [];\n this._pageViewsReady = false;\n\n // Remove the pages from the DOM.\n this.viewer.textContent = '';\n }\n\n _scrollUpdate() {\n if (this.pagesCount === 0) {\n return;\n }\n this.update();\n }\n\n _scrollIntoView({ pageDiv, pageSpot = null, pageNumber = null, }) {\n throw new Error('Not implemented: _scrollIntoView');\n }\n\n _setScaleDispatchEvent(newScale, newValue, preset = false) {\n let arg = {\n source: this,\n scale: newScale,\n presetValue: preset ? newValue : undefined,\n };\n this.eventBus.dispatch('scalechanging', arg);\n this.eventBus.dispatch('scalechange', arg);\n }\n\n _setScaleUpdatePages(newScale, newValue, noScroll = false, preset = false) {\n this._currentScaleValue = newValue.toString();\n\n if (isSameScale(this._currentScale, newScale)) {\n if (preset) {\n this._setScaleDispatchEvent(newScale, newValue, true);\n }\n return;\n }\n\n for (let i = 0, ii = this._pages.length; i < ii; i++) {\n this._pages[i].update(newScale);\n }\n this._currentScale = newScale;\n\n if (!noScroll) {\n let page = this._currentPageNumber, dest;\n if (this._location && !PDFJS.ignoreCurrentPositionOnZoom &&\n !(this.isInPresentationMode || this.isChangingPresentationMode)) {\n page = this._location.pageNumber;\n dest = [null, { name: 'XYZ', }, this._location.left,\n this._location.top, null];\n }\n this.scrollPageIntoView({\n pageNumber: page,\n destArray: dest,\n allowNegativeOffset: true,\n });\n }\n\n this._setScaleDispatchEvent(newScale, newValue, preset);\n\n if (this.defaultRenderingQueue) {\n this.update();\n }\n }\n\n _setScale(value, noScroll = false) {\n let scale = parseFloat(value);\n\n if (scale > 0) {\n this._setScaleUpdatePages(scale, value, noScroll, /* preset = */ false);\n } else {\n let currentPage = this._pages[this._currentPageNumber - 1];\n if (!currentPage) {\n return;\n }\n let hPadding = (this.isInPresentationMode || this.removePageBorders) ?\n 0 : SCROLLBAR_PADDING;\n let vPadding = (this.isInPresentationMode || this.removePageBorders) ?\n 0 : VERTICAL_PADDING;\n let pageWidthScale = (this.container.clientWidth - hPadding) /\n currentPage.width * currentPage.scale;\n let pageHeightScale = (this.container.clientHeight - vPadding) /\n currentPage.height * currentPage.scale;\n switch (value) {\n case 'page-actual':\n scale = 1;\n break;\n case 'page-width':\n scale = pageWidthScale;\n break;\n case 'page-height':\n scale = pageHeightScale;\n break;\n case 'page-fit':\n scale = Math.min(pageWidthScale, pageHeightScale);\n break;\n case 'auto':\n let isLandscape = (currentPage.width > currentPage.height);\n // For pages in landscape mode, fit the page height to the viewer\n // *unless* the page would thus become too wide to fit horizontally.\n let horizontalScale = isLandscape ?\n Math.min(pageHeightScale, pageWidthScale) : pageWidthScale;\n scale = Math.min(MAX_AUTO_SCALE, horizontalScale);\n break;\n default:\n console.error(\n `${this._name}._setScale: \"${value}\" is an unknown zoom value.`);\n return;\n }\n this._setScaleUpdatePages(scale, value, noScroll, /* preset = */ true);\n }\n }\n\n /**\n * Refreshes page view: scrolls to the current page and updates the scale.\n * @private\n */\n _resetCurrentPageView() {\n if (this.isInPresentationMode) {\n // Fixes the case when PDF has different page sizes.\n this._setScale(this._currentScaleValue, true);\n }\n\n let pageView = this._pages[this._currentPageNumber - 1];\n this._scrollIntoView({ pageDiv: pageView.div, });\n }\n\n /**\n * @typedef ScrollPageIntoViewParameters\n * @property {number} pageNumber - The page number.\n * @property {Array} destArray - (optional) The original PDF destination\n * array, in the format: \n * @property {boolean} allowNegativeOffset - (optional) Allow negative page\n * offsets. The default value is `false`.\n */\n\n /**\n * Scrolls page into view.\n * @param {ScrollPageIntoViewParameters} params\n */\n scrollPageIntoView(params) {\n if ((typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC')) &&\n (arguments.length > 1 || typeof params === 'number')) {\n console.error('Call of scrollPageIntoView() with obsolete signature.');\n return;\n }\n if (!this.pdfDocument) {\n return;\n }\n let pageNumber = params.pageNumber || 0;\n let dest = params.destArray || null;\n let allowNegativeOffset = params.allowNegativeOffset || false;\n\n if (this.isInPresentationMode || !dest) {\n this._setCurrentPageNumber(pageNumber, /* resetCurrentPageView = */ true);\n return;\n }\n\n let pageView = this._pages[pageNumber - 1];\n if (!pageView) {\n console.error(\n `${this._name}.scrollPageIntoView: Invalid \"pageNumber\" parameter.`);\n return;\n }\n let x = 0, y = 0;\n let width = 0, height = 0, widthScale, heightScale;\n let changeOrientation = (pageView.rotation % 180 === 0 ? false : true);\n let pageWidth = (changeOrientation ? pageView.height : pageView.width) /\n pageView.scale / CSS_UNITS;\n let pageHeight = (changeOrientation ? pageView.width : pageView.height) /\n pageView.scale / CSS_UNITS;\n let scale = 0;\n switch (dest[1].name) {\n case 'XYZ':\n x = dest[2];\n y = dest[3];\n scale = dest[4];\n // If x and/or y coordinates are not supplied, default to\n // _top_ left of the page (not the obvious bottom left,\n // since aligning the bottom of the intended page with the\n // top of the window is rarely helpful).\n x = x !== null ? x : 0;\n y = y !== null ? y : pageHeight;\n break;\n case 'Fit':\n case 'FitB':\n scale = 'page-fit';\n break;\n case 'FitH':\n case 'FitBH':\n y = dest[2];\n scale = 'page-width';\n // According to the PDF spec, section 12.3.2.2, a `null` value in the\n // parameter should maintain the position relative to the new page.\n if (y === null && this._location) {\n x = this._location.left;\n y = this._location.top;\n }\n break;\n case 'FitV':\n case 'FitBV':\n x = dest[2];\n width = pageWidth;\n height = pageHeight;\n scale = 'page-height';\n break;\n case 'FitR':\n x = dest[2];\n y = dest[3];\n width = dest[4] - x;\n height = dest[5] - y;\n let hPadding = this.removePageBorders ? 0 : SCROLLBAR_PADDING;\n let vPadding = this.removePageBorders ? 0 : VERTICAL_PADDING;\n\n widthScale = (this.container.clientWidth - hPadding) /\n width / CSS_UNITS;\n heightScale = (this.container.clientHeight - vPadding) /\n height / CSS_UNITS;\n scale = Math.min(Math.abs(widthScale), Math.abs(heightScale));\n break;\n default:\n console.error(`${this._name}.scrollPageIntoView: \"${dest[1].name}\" ` +\n 'is not a valid destination type.');\n return;\n }\n\n if (scale && scale !== this._currentScale) {\n this.currentScaleValue = scale;\n } else if (this._currentScale === UNKNOWN_SCALE) {\n this.currentScaleValue = DEFAULT_SCALE_VALUE;\n }\n\n if (scale === 'page-fit' && !dest[4]) {\n this._scrollIntoView({\n pageDiv: pageView.div,\n pageNumber,\n });\n return;\n }\n\n let boundingRect = [\n pageView.viewport.convertToViewportPoint(x, y),\n pageView.viewport.convertToViewportPoint(x + width, y + height)\n ];\n let left = Math.min(boundingRect[0][0], boundingRect[1][0]);\n let top = Math.min(boundingRect[0][1], boundingRect[1][1]);\n\n if (!allowNegativeOffset) {\n // Some bad PDF generators will create destinations with e.g. top values\n // that exceeds the page height. Ensure that offsets are not negative,\n // to prevent a previous page from becoming visible (fixes bug 874482).\n left = Math.max(left, 0);\n top = Math.max(top, 0);\n }\n this._scrollIntoView({\n pageDiv: pageView.div,\n pageSpot: { left, top, },\n pageNumber,\n });\n }\n\n _resizeBuffer(numVisiblePages) {\n let suggestedCacheSize = Math.max(DEFAULT_CACHE_SIZE,\n 2 * numVisiblePages + 1);\n this._buffer.resize(suggestedCacheSize);\n }\n\n _updateLocation(firstPage) {\n let currentScale = this._currentScale;\n let currentScaleValue = this._currentScaleValue;\n let normalizedScaleValue =\n parseFloat(currentScaleValue) === currentScale ?\n Math.round(currentScale * 10000) / 100 : currentScaleValue;\n\n let pageNumber = firstPage.id;\n let pdfOpenParams = '#page=' + pageNumber;\n pdfOpenParams += '&zoom=' + normalizedScaleValue;\n let currentPageView = this._pages[pageNumber - 1];\n let container = this.container;\n let topLeft = currentPageView.getPagePoint(\n (container.scrollLeft - firstPage.x),\n (container.scrollTop - firstPage.y));\n let intLeft = Math.round(topLeft[0]);\n let intTop = Math.round(topLeft[1]);\n pdfOpenParams += ',' + intLeft + ',' + intTop;\n\n this._location = {\n pageNumber,\n scale: normalizedScaleValue,\n top: intTop,\n left: intLeft,\n rotation: this._pagesRotation,\n pdfOpenParams,\n };\n }\n\n update() {\n throw new Error('Not implemented: update');\n }\n\n containsElement(element) {\n return this.container.contains(element);\n }\n\n focus() {\n this.container.focus();\n }\n\n get isInPresentationMode() {\n return this.presentationModeState === PresentationModeState.FULLSCREEN;\n }\n\n get isChangingPresentationMode() {\n return this.presentationModeState === PresentationModeState.CHANGING;\n }\n\n get isHorizontalScrollbarEnabled() {\n return (this.isInPresentationMode ?\n false : (this.container.scrollWidth > this.container.clientWidth));\n }\n\n _getVisiblePages() {\n throw new Error('Not implemented: _getVisiblePages');\n }\n\n cleanup() {\n for (let i = 0, ii = this._pages.length; i < ii; i++) {\n if (this._pages[i] &&\n this._pages[i].renderingState !== RenderingStates.FINISHED) {\n this._pages[i].reset();\n }\n }\n }\n\n /**\n * @private\n */\n _cancelRendering() {\n for (let i = 0, ii = this._pages.length; i < ii; i++) {\n if (this._pages[i]) {\n this._pages[i].cancelRendering();\n }\n }\n }\n\n /**\n * @param {PDFPageView} pageView\n * @returns {Promise} Returns a promise containing a {PDFPageProxy} object.\n * @private\n */\n _ensurePdfPageLoaded(pageView) {\n if (pageView.pdfPage) {\n return Promise.resolve(pageView.pdfPage);\n }\n let pageNumber = pageView.id;\n if (this._pagesRequests[pageNumber]) {\n return this._pagesRequests[pageNumber];\n }\n let promise = this.pdfDocument.getPage(pageNumber).then((pdfPage) => {\n if (!pageView.pdfPage) {\n pageView.setPdfPage(pdfPage);\n }\n this._pagesRequests[pageNumber] = null;\n return pdfPage;\n }).catch((reason) => {\n console.error('Unable to get page for page view', reason);\n // Page error -- there is nothing can be done.\n this._pagesRequests[pageNumber] = null;\n });\n this._pagesRequests[pageNumber] = promise;\n return promise;\n }\n\n forceRendering(currentlyVisiblePages) {\n let visiblePages = currentlyVisiblePages || this._getVisiblePages();\n let pageView = this.renderingQueue.getHighestPriority(visiblePages,\n this._pages,\n this.scroll.down);\n if (pageView) {\n this._ensurePdfPageLoaded(pageView).then(() => {\n this.renderingQueue.renderView(pageView);\n });\n return true;\n }\n return false;\n }\n\n getPageTextContent(pageIndex) {\n return this.pdfDocument.getPage(pageIndex + 1).then(function(page) {\n return page.getTextContent({\n normalizeWhitespace: true,\n });\n });\n }\n\n /**\n * @param {HTMLDivElement} textLayerDiv\n * @param {number} pageIndex\n * @param {PageViewport} viewport\n * @returns {TextLayerBuilder}\n */\n createTextLayerBuilder(textLayerDiv, pageIndex, viewport,\n enhanceTextSelection = false) {\n return new TextLayerBuilder({\n textLayerDiv,\n eventBus: this.eventBus,\n pageIndex,\n viewport,\n findController: this.isInPresentationMode ? null : this.findController,\n enhanceTextSelection: this.isInPresentationMode ? false :\n enhanceTextSelection,\n });\n }\n\n /**\n * @param {HTMLDivElement} pageDiv\n * @param {PDFPage} pdfPage\n * @param {boolean} renderInteractiveForms\n * @param {IL10n} l10n\n * @returns {AnnotationLayerBuilder}\n */\n createAnnotationLayerBuilder(pageDiv, pdfPage, renderInteractiveForms = false,\n l10n = NullL10n) {\n return new AnnotationLayerBuilder({\n pageDiv,\n pdfPage,\n renderInteractiveForms,\n linkService: this.linkService,\n downloadManager: this.downloadManager,\n l10n,\n });\n }\n\n setFindController(findController) {\n this.findController = findController;\n }\n\n /**\n * @returns {boolean} Whether all pages of the PDF document have identical\n * widths and heights.\n */\n get hasEqualPageSizes() {\n let firstPageView = this._pages[0];\n for (let i = 1, ii = this._pages.length; i < ii; ++i) {\n let pageView = this._pages[i];\n if (pageView.width !== firstPageView.width ||\n pageView.height !== firstPageView.height) {\n return false;\n }\n }\n return true;\n }\n\n /**\n * Returns sizes of the pages.\n * @returns {Array} Array of objects with width/height/rotation fields.\n */\n getPagesOverview() {\n let pagesOverview = this._pages.map(function(pageView) {\n let viewport = pageView.pdfPage.getViewport(1);\n return {\n width: viewport.width,\n height: viewport.height,\n rotation: viewport.rotation,\n };\n });\n if (!this.enablePrintAutoRotate) {\n return pagesOverview;\n }\n let isFirstPagePortrait = isPortraitOrientation(pagesOverview[0]);\n return pagesOverview.map(function (size) {\n if (isFirstPagePortrait === isPortraitOrientation(size)) {\n return size;\n }\n return {\n width: size.height,\n height: size.width,\n rotation: (size.rotation + 90) % 360,\n };\n });\n }\n}\n\nexport {\n BaseViewer,\n};\n\n\n\n// WEBPACK FOOTER //\n// web/base_viewer.js","/* Copyright 2014 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { AnnotationLayer } from 'pdfjs-lib';\nimport { NullL10n } from './ui_utils';\nimport { SimpleLinkService } from './pdf_link_service';\n\n/**\n * @typedef {Object} AnnotationLayerBuilderOptions\n * @property {HTMLDivElement} pageDiv\n * @property {PDFPage} pdfPage\n * @property {boolean} renderInteractiveForms\n * @property {IPDFLinkService} linkService\n * @property {DownloadManager} downloadManager\n * @property {IL10n} l10n - Localization service.\n */\n\nclass AnnotationLayerBuilder {\n /**\n * @param {AnnotationLayerBuilderOptions} options\n */\n constructor({ pageDiv, pdfPage, linkService, downloadManager,\n renderInteractiveForms = false, l10n = NullL10n, }) {\n this.pageDiv = pageDiv;\n this.pdfPage = pdfPage;\n this.linkService = linkService;\n this.downloadManager = downloadManager;\n this.renderInteractiveForms = renderInteractiveForms;\n this.l10n = l10n;\n\n this.div = null;\n }\n\n /**\n * @param {PageViewport} viewport\n * @param {string} intent (default value is 'display')\n */\n render(viewport, intent = 'display') {\n this.pdfPage.getAnnotations({ intent, }).then((annotations) => {\n let parameters = {\n viewport: viewport.clone({ dontFlip: true, }),\n div: this.div,\n annotations,\n page: this.pdfPage,\n renderInteractiveForms: this.renderInteractiveForms,\n linkService: this.linkService,\n downloadManager: this.downloadManager,\n };\n\n if (this.div) {\n // If an annotationLayer already exists, refresh its children's\n // transformation matrices.\n AnnotationLayer.update(parameters);\n } else {\n // Create an annotation layer div and render the annotations\n // if there is at least one annotation.\n if (annotations.length === 0) {\n return;\n }\n this.div = document.createElement('div');\n this.div.className = 'annotationLayer';\n this.pageDiv.appendChild(this.div);\n parameters.div = this.div;\n\n AnnotationLayer.render(parameters);\n this.l10n.translate(this.div);\n }\n });\n }\n\n hide() {\n if (!this.div) {\n return;\n }\n this.div.setAttribute('hidden', 'true');\n }\n}\n\n/**\n * @implements IPDFAnnotationLayerFactory\n */\nclass DefaultAnnotationLayerFactory {\n /**\n * @param {HTMLDivElement} pageDiv\n * @param {PDFPage} pdfPage\n * @param {boolean} renderInteractiveForms\n * @param {IL10n} l10n\n * @returns {AnnotationLayerBuilder}\n */\n createAnnotationLayerBuilder(pageDiv, pdfPage, renderInteractiveForms = false,\n l10n = NullL10n) {\n return new AnnotationLayerBuilder({\n pageDiv,\n pdfPage,\n renderInteractiveForms,\n linkService: new SimpleLinkService(),\n l10n,\n });\n }\n}\n\nexport {\n AnnotationLayerBuilder,\n DefaultAnnotationLayerFactory,\n};\n\n\n\n// WEBPACK FOOTER //\n// web/annotation_layer_builder.js","/* Copyright 2012 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n approximateFraction, CSS_UNITS, DEFAULT_SCALE, getOutputScale, NullL10n,\n RendererType, roundToDivide\n} from './ui_utils';\nimport {\n createPromiseCapability, CustomStyle, PDFJS, RenderingCancelledException,\n SVGGraphics\n} from 'pdfjs-lib';\nimport { getGlobalEventBus } from './dom_events';\nimport { RenderingStates } from './pdf_rendering_queue';\n\n/**\n * @typedef {Object} PDFPageViewOptions\n * @property {HTMLDivElement} container - The viewer element.\n * @property {EventBus} eventBus - The application event bus.\n * @property {number} id - The page unique ID (normally its number).\n * @property {number} scale - The page scale display.\n * @property {PageViewport} defaultViewport - The page viewport.\n * @property {PDFRenderingQueue} renderingQueue - The rendering queue object.\n * @property {IPDFTextLayerFactory} textLayerFactory\n * @property {IPDFAnnotationLayerFactory} annotationLayerFactory\n * @property {boolean} enhanceTextSelection - Turns on the text selection\n * enhancement. The default is `false`.\n * @property {boolean} renderInteractiveForms - Turns on rendering of\n * interactive form elements. The default is `false`.\n * @property {string} renderer - 'canvas' or 'svg'. The default is 'canvas'.\n * @property {IL10n} l10n - Localization service.\n */\n\n/**\n * @implements {IRenderableView}\n */\nclass PDFPageView {\n /**\n * @param {PDFPageViewOptions} options\n */\n constructor(options) {\n let container = options.container;\n let defaultViewport = options.defaultViewport;\n\n this.id = options.id;\n this.renderingId = 'page' + this.id;\n\n this.pdfPage = null;\n this.pageLabel = null;\n this.rotation = 0;\n this.scale = options.scale || DEFAULT_SCALE;\n this.viewport = defaultViewport;\n this.pdfPageRotate = defaultViewport.rotation;\n this.hasRestrictedScaling = false;\n this.enhanceTextSelection = options.enhanceTextSelection || false;\n this.renderInteractiveForms = options.renderInteractiveForms || false;\n\n this.eventBus = options.eventBus || getGlobalEventBus();\n this.renderingQueue = options.renderingQueue;\n this.textLayerFactory = options.textLayerFactory;\n this.annotationLayerFactory = options.annotationLayerFactory;\n this.renderer = options.renderer || RendererType.CANVAS;\n this.l10n = options.l10n || NullL10n;\n\n this.paintTask = null;\n this.paintedViewportMap = new WeakMap();\n this.renderingState = RenderingStates.INITIAL;\n this.resume = null;\n this.error = null;\n\n this.onBeforeDraw = null;\n this.onAfterDraw = null;\n\n this.annotationLayer = null;\n this.textLayer = null;\n this.zoomLayer = null;\n\n let div = document.createElement('div');\n div.className = 'page';\n div.style.width = Math.floor(this.viewport.width) + 'px';\n div.style.height = Math.floor(this.viewport.height) + 'px';\n div.setAttribute('data-page-number', this.id);\n this.div = div;\n\n container.appendChild(div);\n }\n\n setPdfPage(pdfPage) {\n this.pdfPage = pdfPage;\n this.pdfPageRotate = pdfPage.rotate;\n\n let totalRotation = (this.rotation + this.pdfPageRotate) % 360;\n this.viewport = pdfPage.getViewport(this.scale * CSS_UNITS,\n totalRotation);\n this.stats = pdfPage.stats;\n this.reset();\n }\n\n destroy() {\n this.reset();\n if (this.pdfPage) {\n this.pdfPage.cleanup();\n }\n }\n\n /**\n * @private\n */\n _resetZoomLayer(removeFromDOM = false) {\n if (!this.zoomLayer) {\n return;\n }\n let zoomLayerCanvas = this.zoomLayer.firstChild;\n this.paintedViewportMap.delete(zoomLayerCanvas);\n // Zeroing the width and height causes Firefox to release graphics\n // resources immediately, which can greatly reduce memory consumption.\n zoomLayerCanvas.width = 0;\n zoomLayerCanvas.height = 0;\n\n if (removeFromDOM) {\n // Note: `ChildNode.remove` doesn't throw if the parent node is undefined.\n this.zoomLayer.remove();\n }\n this.zoomLayer = null;\n }\n\n reset(keepZoomLayer = false, keepAnnotations = false) {\n this.cancelRendering();\n\n let div = this.div;\n div.style.width = Math.floor(this.viewport.width) + 'px';\n div.style.height = Math.floor(this.viewport.height) + 'px';\n\n let childNodes = div.childNodes;\n let currentZoomLayerNode = (keepZoomLayer && this.zoomLayer) || null;\n let currentAnnotationNode = (keepAnnotations && this.annotationLayer &&\n this.annotationLayer.div) || null;\n for (let i = childNodes.length - 1; i >= 0; i--) {\n let node = childNodes[i];\n if (currentZoomLayerNode === node || currentAnnotationNode === node) {\n continue;\n }\n div.removeChild(node);\n }\n div.removeAttribute('data-loaded');\n\n if (currentAnnotationNode) {\n // Hide the annotation layer until all elements are resized\n // so they are not displayed on the already resized page.\n this.annotationLayer.hide();\n } else {\n this.annotationLayer = null;\n }\n\n if (!currentZoomLayerNode) {\n if (this.canvas) {\n this.paintedViewportMap.delete(this.canvas);\n // Zeroing the width and height causes Firefox to release graphics\n // resources immediately, which can greatly reduce memory consumption.\n this.canvas.width = 0;\n this.canvas.height = 0;\n delete this.canvas;\n }\n this._resetZoomLayer();\n }\n if (this.svg) {\n this.paintedViewportMap.delete(this.svg);\n delete this.svg;\n }\n\n this.loadingIconDiv = document.createElement('div');\n this.loadingIconDiv.className = 'loadingIcon';\n div.appendChild(this.loadingIconDiv);\n }\n\n update(scale, rotation) {\n this.scale = scale || this.scale;\n if (typeof rotation !== 'undefined') { // The rotation may be zero.\n this.rotation = rotation;\n }\n\n let totalRotation = (this.rotation + this.pdfPageRotate) % 360;\n this.viewport = this.viewport.clone({\n scale: this.scale * CSS_UNITS,\n rotation: totalRotation,\n });\n\n if (this.svg) {\n this.cssTransform(this.svg, true);\n\n this.eventBus.dispatch('pagerendered', {\n source: this,\n pageNumber: this.id,\n cssTransform: true,\n });\n return;\n }\n\n let isScalingRestricted = false;\n if (this.canvas && PDFJS.maxCanvasPixels > 0) {\n let outputScale = this.outputScale;\n if (((Math.floor(this.viewport.width) * outputScale.sx) | 0) *\n ((Math.floor(this.viewport.height) * outputScale.sy) | 0) >\n PDFJS.maxCanvasPixels) {\n isScalingRestricted = true;\n }\n }\n\n if (this.canvas) {\n if (PDFJS.useOnlyCssZoom ||\n (this.hasRestrictedScaling && isScalingRestricted)) {\n this.cssTransform(this.canvas, true);\n\n this.eventBus.dispatch('pagerendered', {\n source: this,\n pageNumber: this.id,\n cssTransform: true,\n });\n return;\n }\n if (!this.zoomLayer && !this.canvas.hasAttribute('hidden')) {\n this.zoomLayer = this.canvas.parentNode;\n this.zoomLayer.style.position = 'absolute';\n }\n }\n if (this.zoomLayer) {\n this.cssTransform(this.zoomLayer.firstChild);\n }\n this.reset(/* keepZoomLayer = */ true, /* keepAnnotations = */ true);\n }\n\n cancelRendering() {\n if (this.paintTask) {\n this.paintTask.cancel();\n this.paintTask = null;\n }\n this.renderingState = RenderingStates.INITIAL;\n this.resume = null;\n\n if (this.textLayer) {\n this.textLayer.cancel();\n this.textLayer = null;\n }\n }\n\n cssTransform(target, redrawAnnotations = false) {\n // Scale target (canvas or svg), its wrapper and page container.\n let width = this.viewport.width;\n let height = this.viewport.height;\n let div = this.div;\n target.style.width = target.parentNode.style.width = div.style.width =\n Math.floor(width) + 'px';\n target.style.height = target.parentNode.style.height = div.style.height =\n Math.floor(height) + 'px';\n // The canvas may have been originally rotated; rotate relative to that.\n let relativeRotation = this.viewport.rotation -\n this.paintedViewportMap.get(target).rotation;\n let absRotation = Math.abs(relativeRotation);\n let scaleX = 1, scaleY = 1;\n if (absRotation === 90 || absRotation === 270) {\n // Scale x and y because of the rotation.\n scaleX = height / width;\n scaleY = width / height;\n }\n let cssTransform = 'rotate(' + relativeRotation + 'deg) ' +\n 'scale(' + scaleX + ',' + scaleY + ')';\n CustomStyle.setProp('transform', target, cssTransform);\n\n if (this.textLayer) {\n // Rotating the text layer is more complicated since the divs inside the\n // the text layer are rotated.\n // TODO: This could probably be simplified by drawing the text layer in\n // one orientation and then rotating overall.\n let textLayerViewport = this.textLayer.viewport;\n let textRelativeRotation = this.viewport.rotation -\n textLayerViewport.rotation;\n let textAbsRotation = Math.abs(textRelativeRotation);\n let scale = width / textLayerViewport.width;\n if (textAbsRotation === 90 || textAbsRotation === 270) {\n scale = width / textLayerViewport.height;\n }\n let textLayerDiv = this.textLayer.textLayerDiv;\n let transX, transY;\n switch (textAbsRotation) {\n case 0:\n transX = transY = 0;\n break;\n case 90:\n transX = 0;\n transY = '-' + textLayerDiv.style.height;\n break;\n case 180:\n transX = '-' + textLayerDiv.style.width;\n transY = '-' + textLayerDiv.style.height;\n break;\n case 270:\n transX = '-' + textLayerDiv.style.width;\n transY = 0;\n break;\n default:\n console.error('Bad rotation value.');\n break;\n }\n CustomStyle.setProp('transform', textLayerDiv,\n 'rotate(' + textAbsRotation + 'deg) ' +\n 'scale(' + scale + ', ' + scale + ') ' +\n 'translate(' + transX + ', ' + transY + ')');\n CustomStyle.setProp('transformOrigin', textLayerDiv, '0% 0%');\n }\n\n if (redrawAnnotations && this.annotationLayer) {\n this.annotationLayer.render(this.viewport, 'display');\n }\n }\n\n get width() {\n return this.viewport.width;\n }\n\n get height() {\n return this.viewport.height;\n }\n\n getPagePoint(x, y) {\n return this.viewport.convertToPdfPoint(x, y);\n }\n\n draw() {\n if (this.renderingState !== RenderingStates.INITIAL) {\n console.error('Must be in new state before drawing');\n this.reset(); // Ensure that we reset all state to prevent issues.\n }\n\n if (!this.pdfPage) {\n this.renderingState = RenderingStates.FINISHED;\n return Promise.reject(new Error('Page is not loaded'));\n }\n\n this.renderingState = RenderingStates.RUNNING;\n\n let pdfPage = this.pdfPage;\n let div = this.div;\n // Wrap the canvas so that if it has a CSS transform for high DPI the\n // overflow will be hidden in Firefox.\n let canvasWrapper = document.createElement('div');\n canvasWrapper.style.width = div.style.width;\n canvasWrapper.style.height = div.style.height;\n canvasWrapper.classList.add('canvasWrapper');\n\n if (this.annotationLayer && this.annotationLayer.div) {\n // The annotation layer needs to stay on top.\n div.insertBefore(canvasWrapper, this.annotationLayer.div);\n } else {\n div.appendChild(canvasWrapper);\n }\n\n let textLayer = null;\n if (this.textLayerFactory) {\n let textLayerDiv = document.createElement('div');\n textLayerDiv.className = 'textLayer';\n textLayerDiv.style.width = canvasWrapper.style.width;\n textLayerDiv.style.height = canvasWrapper.style.height;\n if (this.annotationLayer && this.annotationLayer.div) {\n // The annotation layer needs to stay on top.\n div.insertBefore(textLayerDiv, this.annotationLayer.div);\n } else {\n div.appendChild(textLayerDiv);\n }\n\n textLayer = this.textLayerFactory.\n createTextLayerBuilder(textLayerDiv, this.id - 1, this.viewport,\n this.enhanceTextSelection);\n }\n this.textLayer = textLayer;\n\n let renderContinueCallback = null;\n if (this.renderingQueue) {\n renderContinueCallback = (cont) => {\n if (!this.renderingQueue.isHighestPriority(this)) {\n this.renderingState = RenderingStates.PAUSED;\n this.resume = () => {\n this.renderingState = RenderingStates.RUNNING;\n cont();\n };\n return;\n }\n cont();\n };\n }\n\n let finishPaintTask = (error) => {\n // The paintTask may have been replaced by a new one, so only remove\n // the reference to the paintTask if it matches the one that is\n // triggering this callback.\n if (paintTask === this.paintTask) {\n this.paintTask = null;\n }\n\n if (((typeof PDFJSDev === 'undefined' ||\n !PDFJSDev.test('PDFJS_NEXT')) && error === 'cancelled') ||\n error instanceof RenderingCancelledException) {\n this.error = null;\n return Promise.resolve(undefined);\n }\n\n this.renderingState = RenderingStates.FINISHED;\n\n if (this.loadingIconDiv) {\n div.removeChild(this.loadingIconDiv);\n delete this.loadingIconDiv;\n }\n this._resetZoomLayer(/* removeFromDOM = */ true);\n\n this.error = error;\n this.stats = pdfPage.stats;\n if (this.onAfterDraw) {\n this.onAfterDraw();\n }\n this.eventBus.dispatch('pagerendered', {\n source: this,\n pageNumber: this.id,\n cssTransform: false,\n });\n\n if (error) {\n return Promise.reject(error);\n }\n return Promise.resolve(undefined);\n };\n\n let paintTask = this.renderer === RendererType.SVG ?\n this.paintOnSvg(canvasWrapper) :\n this.paintOnCanvas(canvasWrapper);\n paintTask.onRenderContinue = renderContinueCallback;\n this.paintTask = paintTask;\n\n let resultPromise = paintTask.promise.then(function() {\n return finishPaintTask(null).then(function () {\n if (textLayer) {\n let readableStream = pdfPage.streamTextContent({\n normalizeWhitespace: true,\n });\n textLayer.setTextContentStream(readableStream);\n textLayer.render();\n }\n });\n }, function(reason) {\n return finishPaintTask(reason);\n });\n\n if (this.annotationLayerFactory) {\n if (!this.annotationLayer) {\n this.annotationLayer = this.annotationLayerFactory.\n createAnnotationLayerBuilder(div, pdfPage,\n this.renderInteractiveForms, this.l10n);\n }\n this.annotationLayer.render(this.viewport, 'display');\n }\n div.setAttribute('data-loaded', true);\n\n if (this.onBeforeDraw) {\n this.onBeforeDraw();\n }\n return resultPromise;\n }\n\n paintOnCanvas(canvasWrapper) {\n let renderCapability = createPromiseCapability();\n let result = {\n promise: renderCapability.promise,\n onRenderContinue(cont) {\n cont();\n },\n cancel() {\n renderTask.cancel();\n },\n };\n\n let viewport = this.viewport;\n let canvas = document.createElement('canvas');\n canvas.id = this.renderingId;\n\n // Keep the canvas hidden until the first draw callback, or until drawing\n // is complete when `!this.renderingQueue`, to prevent black flickering.\n canvas.setAttribute('hidden', 'hidden');\n let isCanvasHidden = true;\n let showCanvas = function () {\n if (isCanvasHidden) {\n canvas.removeAttribute('hidden');\n isCanvasHidden = false;\n }\n };\n\n canvasWrapper.appendChild(canvas);\n this.canvas = canvas;\n\n if (typeof PDFJSDev === 'undefined' ||\n PDFJSDev.test('MOZCENTRAL || FIREFOX || GENERIC')) {\n canvas.mozOpaque = true;\n }\n\n let ctx = canvas.getContext('2d', { alpha: false, });\n let outputScale = getOutputScale(ctx);\n this.outputScale = outputScale;\n\n if (PDFJS.useOnlyCssZoom) {\n let actualSizeViewport = viewport.clone({ scale: CSS_UNITS, });\n // Use a scale that makes the canvas have the originally intended size\n // of the page.\n outputScale.sx *= actualSizeViewport.width / viewport.width;\n outputScale.sy *= actualSizeViewport.height / viewport.height;\n outputScale.scaled = true;\n }\n\n if (PDFJS.maxCanvasPixels > 0) {\n let pixelsInViewport = viewport.width * viewport.height;\n let maxScale = Math.sqrt(PDFJS.maxCanvasPixels / pixelsInViewport);\n if (outputScale.sx > maxScale || outputScale.sy > maxScale) {\n outputScale.sx = maxScale;\n outputScale.sy = maxScale;\n outputScale.scaled = true;\n this.hasRestrictedScaling = true;\n } else {\n this.hasRestrictedScaling = false;\n }\n }\n\n let sfx = approximateFraction(outputScale.sx);\n let sfy = approximateFraction(outputScale.sy);\n canvas.width = roundToDivide(viewport.width * outputScale.sx, sfx[0]);\n canvas.height = roundToDivide(viewport.height * outputScale.sy, sfy[0]);\n canvas.style.width = roundToDivide(viewport.width, sfx[1]) + 'px';\n canvas.style.height = roundToDivide(viewport.height, sfy[1]) + 'px';\n // Add the viewport so it's known what it was originally drawn with.\n this.paintedViewportMap.set(canvas, viewport);\n\n // Rendering area\n let transform = !outputScale.scaled ? null :\n [outputScale.sx, 0, 0, outputScale.sy, 0, 0];\n let renderContext = {\n canvasContext: ctx,\n transform,\n viewport: this.viewport,\n renderInteractiveForms: this.renderInteractiveForms,\n };\n let renderTask = this.pdfPage.render(renderContext);\n renderTask.onContinue = function (cont) {\n showCanvas();\n if (result.onRenderContinue) {\n result.onRenderContinue(cont);\n } else {\n cont();\n }\n };\n\n renderTask.promise.then(function() {\n showCanvas();\n renderCapability.resolve(undefined);\n }, function(error) {\n showCanvas();\n renderCapability.reject(error);\n });\n return result;\n }\n\n paintOnSvg(wrapper) {\n if (typeof PDFJSDev !== 'undefined' &&\n PDFJSDev.test('FIREFOX || MOZCENTRAL || CHROME')) {\n // Return a mock object, to prevent errors such as e.g.\n // \"TypeError: paintTask.promise is undefined\".\n return {\n promise: Promise.reject(new Error('SVG rendering is not supported.')),\n onRenderContinue(cont) { },\n cancel() { },\n };\n }\n\n let cancelled = false;\n let ensureNotCancelled = () => {\n if (cancelled) {\n if ((typeof PDFJSDev !== 'undefined' &&\n PDFJSDev.test('PDFJS_NEXT')) || PDFJS.pdfjsNext) {\n throw new RenderingCancelledException(\n 'Rendering cancelled, page ' + this.id, 'svg');\n } else {\n throw 'cancelled'; // eslint-disable-line no-throw-literal\n }\n }\n };\n\n let pdfPage = this.pdfPage;\n let actualSizeViewport = this.viewport.clone({ scale: CSS_UNITS, });\n let promise = pdfPage.getOperatorList().then((opList) => {\n ensureNotCancelled();\n let svgGfx = new SVGGraphics(pdfPage.commonObjs, pdfPage.objs);\n return svgGfx.getSVG(opList, actualSizeViewport).then((svg) => {\n ensureNotCancelled();\n this.svg = svg;\n this.paintedViewportMap.set(svg, actualSizeViewport);\n\n svg.style.width = wrapper.style.width;\n svg.style.height = wrapper.style.height;\n this.renderingState = RenderingStates.FINISHED;\n wrapper.appendChild(svg);\n });\n });\n\n return {\n promise,\n onRenderContinue(cont) {\n cont();\n },\n cancel() {\n cancelled = true;\n },\n };\n }\n\n /**\n * @param {string|null} label\n */\n setPageLabel(label) {\n this.pageLabel = (typeof label === 'string' ? label : null);\n\n if (this.pageLabel !== null) {\n this.div.setAttribute('data-page-label', this.pageLabel);\n } else {\n this.div.removeAttribute('data-page-label');\n }\n }\n}\n\nexport {\n PDFPageView,\n};\n\n\n\n// WEBPACK FOOTER //\n// web/pdf_page_view.js","/* Copyright 2012 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getGlobalEventBus } from './dom_events';\nimport { renderTextLayer } from 'pdfjs-lib';\n\nconst EXPAND_DIVS_TIMEOUT = 300; // ms\n\n/**\n * @typedef {Object} TextLayerBuilderOptions\n * @property {HTMLDivElement} textLayerDiv - The text layer container.\n * @property {EventBus} eventBus - The application event bus.\n * @property {number} pageIndex - The page index.\n * @property {PageViewport} viewport - The viewport of the text layer.\n * @property {PDFFindController} findController\n * @property {boolean} enhanceTextSelection - Option to turn on improved\n * text selection.\n */\n\n/**\n * The text layer builder provides text selection functionality for the PDF.\n * It does this by creating overlay divs over the PDF's text. These divs\n * contain text that matches the PDF text they are overlaying. This object\n * also provides a way to highlight text that is being searched for.\n */\nclass TextLayerBuilder {\n constructor({ textLayerDiv, eventBus, pageIndex, viewport,\n findController = null, enhanceTextSelection = false, }) {\n this.textLayerDiv = textLayerDiv;\n this.eventBus = eventBus || getGlobalEventBus();\n this.textContent = null;\n this.textContentItemsStr = [];\n this.textContentStream = null;\n this.renderingDone = false;\n this.pageIdx = pageIndex;\n this.pageNumber = this.pageIdx + 1;\n this.matches = [];\n this.viewport = viewport;\n this.textDivs = [];\n this.findController = findController;\n this.textLayerRenderTask = null;\n this.enhanceTextSelection = enhanceTextSelection;\n\n this._bindMouse();\n }\n\n /**\n * @private\n */\n _finishRendering() {\n this.renderingDone = true;\n\n if (!this.enhanceTextSelection) {\n let endOfContent = document.createElement('div');\n endOfContent.className = 'endOfContent';\n this.textLayerDiv.appendChild(endOfContent);\n }\n\n this.eventBus.dispatch('textlayerrendered', {\n source: this,\n pageNumber: this.pageNumber,\n numTextDivs: this.textDivs.length,\n });\n }\n\n /**\n * Renders the text layer.\n *\n * @param {number} timeout - (optional) wait for a specified amount of\n * milliseconds before rendering\n */\n render(timeout = 0) {\n if (!(this.textContent || this.textContentStream) || this.renderingDone) {\n return;\n }\n this.cancel();\n\n this.textDivs = [];\n let textLayerFrag = document.createDocumentFragment();\n this.textLayerRenderTask = renderTextLayer({\n textContent: this.textContent,\n textContentStream: this.textContentStream,\n container: textLayerFrag,\n viewport: this.viewport,\n textDivs: this.textDivs,\n textContentItemsStr: this.textContentItemsStr,\n timeout,\n enhanceTextSelection: this.enhanceTextSelection,\n });\n this.textLayerRenderTask.promise.then(() => {\n this.textLayerDiv.appendChild(textLayerFrag);\n this._finishRendering();\n this.updateMatches();\n }, function (reason) {\n // Cancelled or failed to render text layer; skipping errors.\n });\n }\n\n /**\n * Cancel rendering of the text layer.\n */\n cancel() {\n if (this.textLayerRenderTask) {\n this.textLayerRenderTask.cancel();\n this.textLayerRenderTask = null;\n }\n }\n\n setTextContentStream(readableStream) {\n this.cancel();\n this.textContentStream = readableStream;\n }\n\n setTextContent(textContent) {\n this.cancel();\n this.textContent = textContent;\n }\n\n convertMatches(matches, matchesLength) {\n let i = 0;\n let iIndex = 0;\n let textContentItemsStr = this.textContentItemsStr;\n let end = textContentItemsStr.length - 1;\n let queryLen = (this.findController === null ?\n 0 : this.findController.state.query.length);\n let ret = [];\n if (!matches) {\n return ret;\n }\n for (let m = 0, len = matches.length; m < len; m++) {\n // Calculate the start position.\n let matchIdx = matches[m];\n\n // Loop over the divIdxs.\n while (i !== end && matchIdx >=\n (iIndex + textContentItemsStr[i].length)) {\n iIndex += textContentItemsStr[i].length;\n i++;\n }\n\n if (i === textContentItemsStr.length) {\n console.error('Could not find a matching mapping');\n }\n\n let match = {\n begin: {\n divIdx: i,\n offset: matchIdx - iIndex,\n },\n };\n\n // Calculate the end position.\n if (matchesLength) { // Multiterm search.\n matchIdx += matchesLength[m];\n } else { // Phrase search.\n matchIdx += queryLen;\n }\n\n // Somewhat the same array as above, but use > instead of >= to get\n // the end position right.\n while (i !== end && matchIdx >\n (iIndex + textContentItemsStr[i].length)) {\n iIndex += textContentItemsStr[i].length;\n i++;\n }\n\n match.end = {\n divIdx: i,\n offset: matchIdx - iIndex,\n };\n ret.push(match);\n }\n\n return ret;\n }\n\n renderMatches(matches) {\n // Early exit if there is nothing to render.\n if (matches.length === 0) {\n return;\n }\n\n let textContentItemsStr = this.textContentItemsStr;\n let textDivs = this.textDivs;\n let prevEnd = null;\n let pageIdx = this.pageIdx;\n let isSelectedPage = (this.findController === null ?\n false : (pageIdx === this.findController.selected.pageIdx));\n let selectedMatchIdx = (this.findController === null ?\n -1 : this.findController.selected.matchIdx);\n let highlightAll = (this.findController === null ?\n false : this.findController.state.highlightAll);\n let infinity = {\n divIdx: -1,\n offset: undefined,\n };\n\n function beginText(begin, className) {\n let divIdx = begin.divIdx;\n textDivs[divIdx].textContent = '';\n appendTextToDiv(divIdx, 0, begin.offset, className);\n }\n\n function appendTextToDiv(divIdx, fromOffset, toOffset, className) {\n let div = textDivs[divIdx];\n let content = textContentItemsStr[divIdx].substring(fromOffset, toOffset);\n let node = document.createTextNode(content);\n if (className) {\n let span = document.createElement('span');\n span.className = className;\n span.appendChild(node);\n div.appendChild(span);\n return;\n }\n div.appendChild(node);\n }\n\n let i0 = selectedMatchIdx, i1 = i0 + 1;\n if (highlightAll) {\n i0 = 0;\n i1 = matches.length;\n } else if (!isSelectedPage) {\n // Not highlighting all and this isn't the selected page, so do nothing.\n return;\n }\n\n for (let i = i0; i < i1; i++) {\n let match = matches[i];\n let begin = match.begin;\n let end = match.end;\n let isSelected = (isSelectedPage && i === selectedMatchIdx);\n let highlightSuffix = (isSelected ? ' selected' : '');\n\n if (this.findController) {\n this.findController.updateMatchPosition(pageIdx, i, textDivs,\n begin.divIdx);\n }\n\n // Match inside new div.\n if (!prevEnd || begin.divIdx !== prevEnd.divIdx) {\n // If there was a previous div, then add the text at the end.\n if (prevEnd !== null) {\n appendTextToDiv(prevEnd.divIdx, prevEnd.offset, infinity.offset);\n }\n // Clear the divs and set the content until the starting point.\n beginText(begin);\n } else {\n appendTextToDiv(prevEnd.divIdx, prevEnd.offset, begin.offset);\n }\n\n if (begin.divIdx === end.divIdx) {\n appendTextToDiv(begin.divIdx, begin.offset, end.offset,\n 'highlight' + highlightSuffix);\n } else {\n appendTextToDiv(begin.divIdx, begin.offset, infinity.offset,\n 'highlight begin' + highlightSuffix);\n for (let n0 = begin.divIdx + 1, n1 = end.divIdx; n0 < n1; n0++) {\n textDivs[n0].className = 'highlight middle' + highlightSuffix;\n }\n beginText(end, 'highlight end' + highlightSuffix);\n }\n prevEnd = end;\n }\n\n if (prevEnd) {\n appendTextToDiv(prevEnd.divIdx, prevEnd.offset, infinity.offset);\n }\n }\n\n updateMatches() {\n // Only show matches when all rendering is done.\n if (!this.renderingDone) {\n return;\n }\n\n // Clear all matches.\n let matches = this.matches;\n let textDivs = this.textDivs;\n let textContentItemsStr = this.textContentItemsStr;\n let clearedUntilDivIdx = -1;\n\n // Clear all current matches.\n for (let i = 0, len = matches.length; i < len; i++) {\n let match = matches[i];\n let begin = Math.max(clearedUntilDivIdx, match.begin.divIdx);\n for (let n = begin, end = match.end.divIdx; n <= end; n++) {\n let div = textDivs[n];\n div.textContent = textContentItemsStr[n];\n div.className = '';\n }\n clearedUntilDivIdx = match.end.divIdx + 1;\n }\n\n if (this.findController === null || !this.findController.active) {\n return;\n }\n\n // Convert the matches on the page controller into the match format\n // used for the textLayer.\n let pageMatches, pageMatchesLength;\n if (this.findController !== null) {\n pageMatches = this.findController.pageMatches[this.pageIdx] || null;\n pageMatchesLength = (this.findController.pageMatchesLength) ?\n this.findController.pageMatchesLength[this.pageIdx] || null : null;\n }\n\n this.matches = this.convertMatches(pageMatches, pageMatchesLength);\n this.renderMatches(this.matches);\n }\n\n /**\n * Improves text selection by adding an additional div where the mouse was\n * clicked. This reduces flickering of the content if the mouse is slowly\n * dragged up or down.\n *\n * @private\n */\n _bindMouse() {\n let div = this.textLayerDiv;\n let expandDivsTimer = null;\n\n div.addEventListener('mousedown', (evt) => {\n if (this.enhanceTextSelection && this.textLayerRenderTask) {\n this.textLayerRenderTask.expandTextDivs(true);\n if ((typeof PDFJSDev === 'undefined' ||\n !PDFJSDev.test('FIREFOX || MOZCENTRAL')) &&\n expandDivsTimer) {\n clearTimeout(expandDivsTimer);\n expandDivsTimer = null;\n }\n return;\n }\n\n let end = div.querySelector('.endOfContent');\n if (!end) {\n return;\n }\n if (typeof PDFJSDev === 'undefined' ||\n !PDFJSDev.test('FIREFOX || MOZCENTRAL')) {\n // On non-Firefox browsers, the selection will feel better if the height\n // of the `endOfContent` div is adjusted to start at mouse click\n // location. This avoids flickering when the selection moves up.\n // However it does not work when selection is started on empty space.\n let adjustTop = evt.target !== div;\n if (typeof PDFJSDev === 'undefined' || PDFJSDev.test('GENERIC')) {\n adjustTop = adjustTop && window.getComputedStyle(end).\n getPropertyValue('-moz-user-select') !== 'none';\n }\n if (adjustTop) {\n let divBounds = div.getBoundingClientRect();\n let r = Math.max(0, (evt.pageY - divBounds.top) / divBounds.height);\n end.style.top = (r * 100).toFixed(2) + '%';\n }\n }\n end.classList.add('active');\n });\n\n div.addEventListener('mouseup', () => {\n if (this.enhanceTextSelection && this.textLayerRenderTask) {\n if (typeof PDFJSDev === 'undefined' ||\n !PDFJSDev.test('FIREFOX || MOZCENTRAL')) {\n expandDivsTimer = setTimeout(() => {\n if (this.textLayerRenderTask) {\n this.textLayerRenderTask.expandTextDivs(false);\n }\n expandDivsTimer = null;\n }, EXPAND_DIVS_TIMEOUT);\n } else {\n this.textLayerRenderTask.expandTextDivs(false);\n }\n return;\n }\n\n let end = div.querySelector('.endOfContent');\n if (!end) {\n return;\n }\n if (typeof PDFJSDev === 'undefined' ||\n !PDFJSDev.test('FIREFOX || MOZCENTRAL')) {\n end.style.top = '';\n }\n end.classList.remove('active');\n });\n }\n}\n\n/**\n * @implements IPDFTextLayerFactory\n */\nclass DefaultTextLayerFactory {\n /**\n * @param {HTMLDivElement} textLayerDiv\n * @param {number} pageIndex\n * @param {PageViewport} viewport\n * @param {boolean} enhanceTextSelection\n * @returns {TextLayerBuilder}\n */\n createTextLayerBuilder(textLayerDiv, pageIndex, viewport,\n enhanceTextSelection = false) {\n return new TextLayerBuilder({\n textLayerDiv,\n pageIndex,\n viewport,\n enhanceTextSelection,\n });\n }\n}\n\nexport {\n TextLayerBuilder,\n DefaultTextLayerFactory,\n};\n\n\n\n// WEBPACK FOOTER //\n// web/text_layer_builder.js","/* Copyright 2012 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { CursorTool } from './pdf_cursor_tools';\nimport { SCROLLBAR_PADDING } from './ui_utils';\n\n/**\n * @typedef {Object} SecondaryToolbarOptions\n * @property {HTMLDivElement} toolbar - Container for the secondary toolbar.\n * @property {HTMLButtonElement} toggleButton - Button to toggle the visibility\n * of the secondary toolbar.\n * @property {HTMLDivElement} toolbarButtonContainer - Container where all the\n * toolbar buttons are placed. The maximum height of the toolbar is controlled\n * dynamically by adjusting the 'max-height' CSS property of this DOM element.\n * @property {HTMLButtonElement} presentationModeButton - Button for entering\n * presentation mode.\n * @property {HTMLButtonElement} openFileButton - Button to open a file.\n * @property {HTMLButtonElement} printButton - Button to print the document.\n * @property {HTMLButtonElement} downloadButton - Button to download the\n * document.\n * @property {HTMLLinkElement} viewBookmarkButton - Button to obtain a bookmark\n * link to the current location in the document.\n * @property {HTMLButtonElement} firstPageButton - Button to go to the first\n * page in the document.\n * @property {HTMLButtonElement} lastPageButton - Button to go to the last page\n * in the document.\n * @property {HTMLButtonElement} pageRotateCwButton - Button to rotate the pages\n * clockwise.\n * @property {HTMLButtonElement} pageRotateCcwButton - Button to rotate the\n * pages counterclockwise.\n * @property {HTMLButtonElement} cursorSelectToolButton - Button to enable the\n * select tool.\n * @property {HTMLButtonElement} cursorHandToolButton - Button to enable the\n * hand tool.\n * @property {HTMLButtonElement} documentPropertiesButton - Button for opening\n * the document properties dialog.\n */\n\nclass SecondaryToolbar {\n /**\n * @param {SecondaryToolbarOptions} options\n * @param {HTMLDivElement} mainContainer\n * @param {EventBus} eventBus\n */\n constructor(options, mainContainer, eventBus) {\n this.toolbar = options.toolbar;\n this.toggleButton = options.toggleButton;\n this.toolbarButtonContainer = options.toolbarButtonContainer;\n this.buttons = [\n { element: options.presentationModeButton, eventName: 'presentationmode',\n close: true, },\n { element: options.openFileButton, eventName: 'openfile', close: true, },\n { element: options.printButton, eventName: 'print', close: true, },\n { element: options.downloadButton, eventName: 'download', close: true, },\n { element: options.viewBookmarkButton, eventName: null, close: true, },\n { element: options.firstPageButton, eventName: 'firstpage',\n close: true, },\n { element: options.lastPageButton, eventName: 'lastpage', close: true, },\n { element: options.pageRotateCwButton, eventName: 'rotatecw',\n close: false, },\n { element: options.pageRotateCcwButton, eventName: 'rotateccw',\n close: false, },\n { element: options.cursorSelectToolButton, eventName: 'switchcursortool',\n eventDetails: { tool: CursorTool.SELECT, }, close: true, },\n { element: options.cursorHandToolButton, eventName: 'switchcursortool',\n eventDetails: { tool: CursorTool.HAND, }, close: true, },\n { element: options.documentPropertiesButton,\n eventName: 'documentproperties', close: true, },\n ];\n this.items = {\n firstPage: options.firstPageButton,\n lastPage: options.lastPageButton,\n pageRotateCw: options.pageRotateCwButton,\n pageRotateCcw: options.pageRotateCcwButton,\n };\n\n this.mainContainer = mainContainer;\n this.eventBus = eventBus;\n\n this.opened = false;\n this.containerHeight = null;\n this.previousContainerHeight = null;\n\n this.reset();\n\n // Bind the event listeners for click and cursor tool actions.\n this._bindClickListeners();\n this._bindCursorToolsListener(options);\n\n // Bind the event listener for adjusting the 'max-height' of the toolbar.\n this.eventBus.on('resize', this._setMaxHeight.bind(this));\n }\n\n /**\n * @return {boolean}\n */\n get isOpen() {\n return this.opened;\n }\n\n setPageNumber(pageNumber) {\n this.pageNumber = pageNumber;\n this._updateUIState();\n }\n\n setPagesCount(pagesCount) {\n this.pagesCount = pagesCount;\n this._updateUIState();\n }\n\n reset() {\n this.pageNumber = 0;\n this.pagesCount = 0;\n this._updateUIState();\n }\n\n _updateUIState() {\n this.items.firstPage.disabled = (this.pageNumber <= 1);\n this.items.lastPage.disabled = (this.pageNumber >= this.pagesCount);\n this.items.pageRotateCw.disabled = this.pagesCount === 0;\n this.items.pageRotateCcw.disabled = this.pagesCount === 0;\n }\n\n _bindClickListeners() {\n // Button to toggle the visibility of the secondary toolbar.\n this.toggleButton.addEventListener('click', this.toggle.bind(this));\n\n // All items within the secondary toolbar.\n for (let button in this.buttons) {\n let { element, eventName, close, eventDetails, } = this.buttons[button];\n\n element.addEventListener('click', (evt) => {\n if (eventName !== null) {\n let details = { source: this, };\n for (let property in eventDetails) {\n details[property] = eventDetails[property];\n }\n this.eventBus.dispatch(eventName, details);\n }\n if (close) {\n this.close();\n }\n });\n }\n }\n\n _bindCursorToolsListener(buttons) {\n this.eventBus.on('cursortoolchanged', function(evt) {\n buttons.cursorSelectToolButton.classList.remove('toggled');\n buttons.cursorHandToolButton.classList.remove('toggled');\n\n switch (evt.tool) {\n case CursorTool.SELECT:\n buttons.cursorSelectToolButton.classList.add('toggled');\n break;\n case CursorTool.HAND:\n buttons.cursorHandToolButton.classList.add('toggled');\n break;\n }\n });\n }\n\n open() {\n if (this.opened) {\n return;\n }\n this.opened = true;\n this._setMaxHeight();\n\n this.toggleButton.classList.add('toggled');\n this.toolbar.classList.remove('hidden');\n }\n\n close() {\n if (!this.opened) {\n return;\n }\n this.opened = false;\n this.toolbar.classList.add('hidden');\n this.toggleButton.classList.remove('toggled');\n }\n\n toggle() {\n if (this.opened) {\n this.close();\n } else {\n this.open();\n }\n }\n\n /**\n * @private\n */\n _setMaxHeight() {\n if (!this.opened) {\n return; // Only adjust the 'max-height' if the toolbar is visible.\n }\n this.containerHeight = this.mainContainer.clientHeight;\n\n if (this.containerHeight === this.previousContainerHeight) {\n return;\n }\n this.toolbarButtonContainer.setAttribute('style',\n 'max-height: ' + (this.containerHeight - SCROLLBAR_PADDING) + 'px;');\n\n this.previousContainerHeight = this.containerHeight;\n }\n}\n\nexport {\n SecondaryToolbar,\n};\n\n\n\n// WEBPACK FOOTER //\n// web/secondary_toolbar.js","/* Copyright 2016 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n animationStarted, DEFAULT_SCALE, DEFAULT_SCALE_VALUE, MAX_SCALE,\n MIN_SCALE, noContextMenuHandler, NullL10n\n} from './ui_utils';\n\nconst PAGE_NUMBER_LOADING_INDICATOR = 'visiblePageIsLoading';\nconst SCALE_SELECT_CONTAINER_PADDING = 8;\nconst SCALE_SELECT_PADDING = 22;\n\n/**\n * @typedef {Object} ToolbarOptions\n * @property {HTMLDivElement} container - Container for the secondary toolbar.\n * @property {HTMLSpanElement} numPages - Label that contains number of pages.\n * @property {HTMLInputElement} pageNumber - Control for display and user input\n * of the current page number.\n * @property {HTMLSpanElement} scaleSelectContainer - Container where scale\n * controls are placed. The width is adjusted on UI initialization.\n * @property {HTMLSelectElement} scaleSelect - Scale selection control.\n * @property {HTMLOptionElement} customScaleOption - The item used to display\n * a non-predefined scale.\n * @property {HTMLButtonElement} previous - Button to go to the previous page.\n * @property {HTMLButtonElement} next - Button to go to the next page.\n * @property {HTMLButtonElement} zoomIn - Button to zoom in the pages.\n * @property {HTMLButtonElement} zoomOut - Button to zoom out the pages.\n * @property {HTMLButtonElement} viewFind - Button to open find bar.\n * @property {HTMLButtonElement} openFile - Button to open a new document.\n * @property {HTMLButtonElement} presentationModeButton - Button to switch to\n * presentation mode.\n * @property {HTMLButtonElement} download - Button to download the document.\n * @property {HTMLAElement} viewBookmark - Element to link current url of\n * the page view.\n */\n\nclass Toolbar {\n /**\n * @param {ToolbarOptions} options\n * @param {HTMLDivElement} mainContainer\n * @param {EventBus} eventBus\n * @param {IL10n} l10n - Localization service.\n */\n constructor(options, mainContainer, eventBus, l10n = NullL10n) {\n this.toolbar = options.container;\n this.mainContainer = mainContainer;\n this.eventBus = eventBus;\n this.l10n = l10n;\n this.items = options;\n\n this._wasLocalized = false;\n this.reset();\n\n // Bind the event listeners for click and hand tool actions.\n this._bindListeners();\n }\n\n setPageNumber(pageNumber, pageLabel) {\n this.pageNumber = pageNumber;\n this.pageLabel = pageLabel;\n this._updateUIState(false);\n }\n\n setPagesCount(pagesCount, hasPageLabels) {\n this.pagesCount = pagesCount;\n this.hasPageLabels = hasPageLabels;\n this._updateUIState(true);\n }\n\n setPageScale(pageScaleValue, pageScale) {\n this.pageScaleValue = pageScaleValue;\n this.pageScale = pageScale;\n this._updateUIState(false);\n }\n\n reset() {\n this.pageNumber = 0;\n this.pageLabel = null;\n this.hasPageLabels = false;\n this.pagesCount = 0;\n this.pageScaleValue = DEFAULT_SCALE_VALUE;\n this.pageScale = DEFAULT_SCALE;\n this._updateUIState(true);\n }\n\n _bindListeners() {\n let { eventBus, items, } = this;\n let self = this;\n\n items.previous.addEventListener('click', function() {\n eventBus.dispatch('previouspage');\n });\n\n items.next.addEventListener('click', function() {\n eventBus.dispatch('nextpage');\n });\n\n items.zoomIn.addEventListener('click', function() {\n eventBus.dispatch('zoomin');\n });\n\n items.zoomOut.addEventListener('click', function() {\n eventBus.dispatch('zoomout');\n });\n\n items.pageNumber.addEventListener('click', function() {\n this.select();\n });\n\n items.pageNumber.addEventListener('change', function() {\n eventBus.dispatch('pagenumberchanged', {\n source: self,\n value: this.value,\n });\n });\n\n items.scaleSelect.addEventListener('change', function() {\n if (this.value === 'custom') {\n return;\n }\n eventBus.dispatch('scalechanged', {\n source: self,\n value: this.value,\n });\n });\n\n items.presentationModeButton.addEventListener('click', function() {\n eventBus.dispatch('presentationmode');\n });\n\n items.openFile.addEventListener('click', function() {\n eventBus.dispatch('openfile');\n });\n\n items.print.addEventListener('click', function() {\n eventBus.dispatch('print');\n });\n\n items.download.addEventListener('click', function() {\n eventBus.dispatch('download');\n });\n\n // Suppress context menus for some controls.\n items.scaleSelect.oncontextmenu = noContextMenuHandler;\n\n eventBus.on('localized', () => {\n this._localized();\n });\n }\n\n _localized() {\n this._wasLocalized = true;\n this._adjustScaleWidth();\n this._updateUIState(true);\n }\n\n _updateUIState(resetNumPages = false) {\n if (!this._wasLocalized) {\n // Don't update the UI state until we localize the toolbar.\n return;\n }\n let { pageNumber, pagesCount, items, } = this;\n let scaleValue = (this.pageScaleValue || this.pageScale).toString();\n let scale = this.pageScale;\n\n if (resetNumPages) {\n if (this.hasPageLabels) {\n items.pageNumber.type = 'text';\n } else {\n items.pageNumber.type = 'number';\n this.l10n.get('of_pages', { pagesCount, }, 'of {{pagesCount}}').\n then((msg) => {\n items.numPages.textContent = msg;\n });\n }\n items.pageNumber.max = pagesCount;\n }\n\n if (this.hasPageLabels) {\n items.pageNumber.value = this.pageLabel;\n this.l10n.get('page_of_pages', { pageNumber, pagesCount, },\n '({{pageNumber}} of {{pagesCount}})').then((msg) => {\n items.numPages.textContent = msg;\n });\n } else {\n items.pageNumber.value = pageNumber;\n }\n\n items.previous.disabled = (pageNumber <= 1);\n items.next.disabled = (pageNumber >= pagesCount);\n\n items.zoomOut.disabled = (scale <= MIN_SCALE);\n items.zoomIn.disabled = (scale >= MAX_SCALE);\n\n let customScale = Math.round(scale * 10000) / 100;\n this.l10n.get('page_scale_percent', { scale: customScale, },\n '{{scale}}%').then((msg) => {\n let options = items.scaleSelect.options;\n let predefinedValueFound = false;\n for (let i = 0, ii = options.length; i < ii; i++) {\n let option = options[i];\n if (option.value !== scaleValue) {\n option.selected = false;\n continue;\n }\n option.selected = true;\n predefinedValueFound = true;\n }\n if (!predefinedValueFound) {\n items.customScaleOption.textContent = msg;\n items.customScaleOption.selected = true;\n }\n });\n }\n\n updateLoadingIndicatorState(loading = false) {\n let pageNumberInput = this.items.pageNumber;\n\n if (loading) {\n pageNumberInput.classList.add(PAGE_NUMBER_LOADING_INDICATOR);\n } else {\n pageNumberInput.classList.remove(PAGE_NUMBER_LOADING_INDICATOR);\n }\n }\n\n _adjustScaleWidth() {\n let container = this.items.scaleSelectContainer;\n let select = this.items.scaleSelect;\n\n animationStarted.then(function() {\n // Adjust the width of the zoom box to fit the content.\n // Note: If the window is narrow enough that the zoom box is not\n // visible, we temporarily show it to be able to adjust its width.\n if (container.clientWidth === 0) {\n container.setAttribute('style', 'display: inherit;');\n }\n if (container.clientWidth > 0) {\n select.setAttribute('style', 'min-width: inherit;');\n let width = select.clientWidth + SCALE_SELECT_CONTAINER_PADDING;\n select.setAttribute('style', 'min-width: ' +\n (width + SCALE_SELECT_PADDING) + 'px;');\n container.setAttribute('style', 'min-width: ' + width + 'px; ' +\n 'max-width: ' + width + 'px;');\n }\n });\n }\n}\n\nexport {\n Toolbar,\n};\n\n\n\n// WEBPACK FOOTER //\n// web/toolbar.js","/* Copyright 2012 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nconst DEFAULT_VIEW_HISTORY_CACHE_SIZE = 20;\n\n/**\n * View History - This is a utility for saving various view parameters for\n * recently opened files.\n *\n * The way that the view parameters are stored depends on how PDF.js is built,\n * for 'gulp ' the following cases exist:\n * - FIREFOX or MOZCENTRAL - uses sessionStorage.\n * - GENERIC or CHROME - uses localStorage, if it is available.\n */\nclass ViewHistory {\n constructor(fingerprint, cacheSize = DEFAULT_VIEW_HISTORY_CACHE_SIZE) {\n this.fingerprint = fingerprint;\n this.cacheSize = cacheSize;\n\n this._initializedPromise = this._readFromStorage().then((databaseStr) => {\n let database = JSON.parse(databaseStr || '{}');\n if (!('files' in database)) {\n database.files = [];\n }\n if (database.files.length >= this.cacheSize) {\n database.files.shift();\n }\n let index;\n for (let i = 0, length = database.files.length; i < length; i++) {\n let branch = database.files[i];\n if (branch.fingerprint === this.fingerprint) {\n index = i;\n break;\n }\n }\n if (typeof index !== 'number') {\n index = database.files.push({ fingerprint: this.fingerprint, }) - 1;\n }\n this.file = database.files[index];\n this.database = database;\n });\n }\n\n _writeToStorage() {\n return new Promise((resolve) => {\n let databaseStr = JSON.stringify(this.database);\n\n if (typeof PDFJSDev !== 'undefined' &&\n PDFJSDev.test('FIREFOX || MOZCENTRAL')) {\n sessionStorage.setItem('pdfjs.history', databaseStr);\n } else {\n localStorage.setItem('pdfjs.history', databaseStr);\n }\n resolve();\n });\n }\n\n _readFromStorage() {\n return new Promise(function(resolve) {\n if (typeof PDFJSDev !== 'undefined' &&\n PDFJSDev.test('FIREFOX || MOZCENTRAL')) {\n resolve(sessionStorage.getItem('pdfjs.history'));\n } else {\n resolve(localStorage.getItem('pdfjs.history'));\n }\n });\n }\n\n set(name, val) {\n return this._initializedPromise.then(() => {\n this.file[name] = val;\n return this._writeToStorage();\n });\n }\n\n setMultiple(properties) {\n return this._initializedPromise.then(() => {\n for (let name in properties) {\n this.file[name] = properties[name];\n }\n return this._writeToStorage();\n });\n }\n\n get(name, defaultValue) {\n return this._initializedPromise.then(() => {\n let val = this.file[name];\n return val !== undefined ? val : defaultValue;\n });\n }\n\n getMultiple(properties) {\n return this._initializedPromise.then(() => {\n let values = Object.create(null);\n\n for (let name in properties) {\n let val = this.file[name];\n values[name] = val !== undefined ? val : properties[name];\n }\n return values;\n });\n }\n}\n\nexport {\n ViewHistory,\n};\n\n\n\n// WEBPACK FOOTER //\n// web/view_history.js","/* Copyright 2017 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { DefaultExternalServices, PDFViewerApplication } from './app';\nimport { BasePreferences } from './preferences';\nimport { DownloadManager } from './download_manager';\nimport { GenericL10n } from './genericl10n';\nimport { PDFJS } from 'pdfjs-lib';\n\nif (typeof PDFJSDev !== 'undefined' && !PDFJSDev.test('GENERIC')) {\n throw new Error('Module \"pdfjs-web/genericcom\" shall not be used outside ' +\n 'GENERIC build.');\n}\n\nlet GenericCom = {};\n\nclass GenericPreferences extends BasePreferences {\n _writeToStorage(prefObj) {\n return new Promise(function(resolve) {\n localStorage.setItem('pdfjs.preferences', JSON.stringify(prefObj));\n resolve();\n });\n }\n\n _readFromStorage(prefObj) {\n return new Promise(function(resolve) {\n let readPrefs = JSON.parse(localStorage.getItem('pdfjs.preferences'));\n resolve(readPrefs);\n });\n }\n}\n\nlet GenericExternalServices = Object.create(DefaultExternalServices);\nGenericExternalServices.createDownloadManager = function() {\n return new DownloadManager();\n};\nGenericExternalServices.createPreferences = function() {\n return new GenericPreferences();\n};\nGenericExternalServices.createL10n = function () {\n return new GenericL10n(PDFJS.locale);\n};\nPDFViewerApplication.externalServices = GenericExternalServices;\n\nexport {\n GenericCom,\n};\n\n\n\n// WEBPACK FOOTER //\n// web/genericcom.js","/* Copyright 2013 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { cloneObj } from './ui_utils';\n\nvar defaultPreferences = null;\nfunction getDefaultPreferences() {\n if (!defaultPreferences) {\n if (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('PRODUCTION')) {\n defaultPreferences = Promise.resolve(\n PDFJSDev.json('$ROOT/web/default_preferences.json'));\n } else {\n defaultPreferences = new Promise(function (resolve) {\n var xhr = new XMLHttpRequest();\n xhr.open('GET', 'default_preferences.json');\n xhr.onload = xhr.onerror = function loaded() {\n try {\n resolve(JSON.parse(xhr.responseText));\n } catch (e) {\n console.error(`Unable to load default preferences: ${e}`);\n resolve({});\n }\n };\n xhr.send();\n });\n }\n }\n return defaultPreferences;\n}\n\n/**\n * BasePreferences - Abstract base class for storing persistent settings.\n * Used for settings that should be applied to all opened documents,\n * or every time the viewer is loaded.\n */\nclass BasePreferences {\n constructor() {\n if (this.constructor === BasePreferences) {\n throw new Error('Cannot initialize BasePreferences.');\n }\n this.prefs = null;\n\n this._initializedPromise = getDefaultPreferences().then((defaults) => {\n Object.defineProperty(this, 'defaults', {\n value: Object.freeze(defaults),\n writable: false,\n enumerable: true,\n configurable: false,\n });\n\n this.prefs = cloneObj(defaults);\n return this._readFromStorage(defaults);\n }).then((prefObj) => {\n if (prefObj) {\n this.prefs = prefObj;\n }\n });\n }\n\n /**\n * Stub function for writing preferences to storage.\n * @param {Object} prefObj The preferences that should be written to storage.\n * @return {Promise} A promise that is resolved when the preference values\n * have been written.\n */\n _writeToStorage(prefObj) {\n return Promise.reject(new Error('Not implemented: _writeToStorage'));\n }\n\n /**\n * Stub function for reading preferences from storage.\n * @param {Object} prefObj The preferences that should be read from storage.\n * @return {Promise} A promise that is resolved with an {Object} containing\n * the preferences that have been read.\n */\n _readFromStorage(prefObj) {\n return Promise.reject(new Error('Not implemented: _readFromStorage'));\n }\n\n /**\n * Reset the preferences to their default values and update storage.\n * @return {Promise} A promise that is resolved when the preference values\n * have been reset.\n */\n reset() {\n return this._initializedPromise.then(() => {\n this.prefs = cloneObj(this.defaults);\n return this._writeToStorage(this.defaults);\n });\n }\n\n /**\n * Replace the current preference values with the ones from storage.\n * @return {Promise} A promise that is resolved when the preference values\n * have been updated.\n */\n reload() {\n return this._initializedPromise.then(() => {\n return this._readFromStorage(this.defaults);\n }).then((prefObj) => {\n if (prefObj) {\n this.prefs = prefObj;\n }\n });\n }\n\n /**\n * Set the value of a preference.\n * @param {string} name The name of the preference that should be changed.\n * @param {boolean|number|string} value The new value of the preference.\n * @return {Promise} A promise that is resolved when the value has been set,\n * provided that the preference exists and the types match.\n */\n set(name, value) {\n return this._initializedPromise.then(() => {\n if (this.defaults[name] === undefined) {\n throw new Error(`Set preference: \"${name}\" is undefined.`);\n } else if (value === undefined) {\n throw new Error('Set preference: no value is specified.');\n }\n var valueType = typeof value;\n var defaultType = typeof this.defaults[name];\n\n if (valueType !== defaultType) {\n if (valueType === 'number' && defaultType === 'string') {\n value = value.toString();\n } else {\n throw new Error(`Set preference: \"${value}\" is a ${valueType}, ` +\n `expected a ${defaultType}.`);\n }\n } else {\n if (valueType === 'number' && !Number.isInteger(value)) {\n throw new Error(`Set preference: \"${value}\" must be an integer.`);\n }\n }\n this.prefs[name] = value;\n return this._writeToStorage(this.prefs);\n });\n }\n\n /**\n * Get the value of a preference.\n * @param {string} name The name of the preference whose value is requested.\n * @return {Promise} A promise that is resolved with a {boolean|number|string}\n * containing the value of the preference.\n */\n get(name) {\n return this._initializedPromise.then(() => {\n var defaultValue = this.defaults[name];\n\n if (defaultValue === undefined) {\n throw new Error(`Get preference: \"${name}\" is undefined.`);\n } else {\n var prefValue = this.prefs[name];\n\n if (prefValue !== undefined) {\n return prefValue;\n }\n }\n return defaultValue;\n });\n }\n}\n\nexport {\n BasePreferences,\n};\n\n\n\n// WEBPACK FOOTER //\n// web/preferences.js","/* Copyright 2013 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { createObjectURL, createValidAbsoluteUrl, PDFJS } from 'pdfjs-lib';\n\nif (typeof PDFJSDev !== 'undefined' && !PDFJSDev.test('CHROME || GENERIC')) {\n throw new Error('Module \"pdfjs-web/download_manager\" shall not be used ' +\n 'outside CHROME and GENERIC builds.');\n}\n\nfunction download(blobUrl, filename) {\n let a = document.createElement('a');\n if (a.click) {\n // Use a.click() if available. Otherwise, Chrome might show\n // \"Unsafe JavaScript attempt to initiate a navigation change\n // for frame with URL\" and not open the PDF at all.\n // Supported by (not mentioned = untested):\n // - Firefox 6 - 19 (4- does not support a.click, 5 ignores a.click)\n // - Chrome 19 - 26 (18- does not support a.click)\n // - Opera 9 - 12.15\n // - Internet Explorer 6 - 10\n // - Safari 6 (5.1- does not support a.click)\n a.href = blobUrl;\n a.target = '_parent';\n // Use a.download if available. This increases the likelihood that\n // the file is downloaded instead of opened by another PDF plugin.\n if ('download' in a) {\n a.download = filename;\n }\n // must be in the document for IE and recent Firefox versions.\n // (otherwise .click() is ignored)\n (document.body || document.documentElement).appendChild(a);\n a.click();\n a.parentNode.removeChild(a);\n } else {\n if (window.top === window &&\n blobUrl.split('#')[0] === window.location.href.split('#')[0]) {\n // If _parent == self, then opening an identical URL with different\n // location hash will only cause a navigation, not a download.\n let padCharacter = blobUrl.indexOf('?') === -1 ? '?' : '&';\n blobUrl = blobUrl.replace(/#|$/, padCharacter + '$&');\n }\n window.open(blobUrl, '_parent');\n }\n}\n\nclass DownloadManager {\n downloadUrl(url, filename) {\n if (!createValidAbsoluteUrl(url, 'http://example.com')) {\n return; // restricted/invalid URL\n }\n download(url + '#pdfjs.action=download', filename);\n }\n\n downloadData(data, filename, contentType) {\n if (navigator.msSaveBlob) { // IE10 and above\n return navigator.msSaveBlob(new Blob([data], { type: contentType, }),\n filename);\n }\n let blobUrl = createObjectURL(data, contentType,\n PDFJS.disableCreateObjectURL);\n download(blobUrl, filename);\n }\n\n download(blob, url, filename) {\n if (navigator.msSaveBlob) {\n // IE10 / IE11\n if (!navigator.msSaveBlob(blob, filename)) {\n this.downloadUrl(url, filename);\n }\n return;\n }\n\n if (PDFJS.disableCreateObjectURL) {\n // URL.createObjectURL is not supported\n this.downloadUrl(url, filename);\n return;\n }\n\n let blobUrl = URL.createObjectURL(blob);\n download(blobUrl, filename);\n }\n}\n\nexport {\n DownloadManager,\n};\n\n\n\n// WEBPACK FOOTER //\n// web/download_manager.js","/* Copyright 2017 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport '../external/webL10n/l10n';\n\nlet webL10n = document.webL10n;\n\nclass GenericL10n {\n constructor(lang) {\n this._lang = lang;\n this._ready = new Promise((resolve, reject) => {\n webL10n.setLanguage(lang, () => {\n resolve(webL10n);\n });\n });\n }\n\n getDirection() {\n return this._ready.then((l10n) => {\n return l10n.getDirection();\n });\n }\n\n get(property, args, fallback) {\n return this._ready.then((l10n) => {\n return l10n.get(property, args, fallback);\n });\n }\n\n translate(element) {\n return this._ready.then((l10n) => {\n return l10n.translate(element);\n });\n }\n}\n\nexport {\n GenericL10n,\n};\n\n\n\n// WEBPACK FOOTER //\n// web/genericl10n.js","/**\n * Copyright (c) 2011-2013 Fabien Cazenave, Mozilla.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n/*\n Additional modifications for PDF.js project:\n - Disables language initialization on page loading.\n - Disables document translation on page loading.\n - Removes consoleWarn and consoleLog and use console.log/warn directly.\n - Removes window._ assignment.\n - Remove compatibility code for OldIE.\n*/\n\n/*jshint browser: true, devel: true, es5: true, globalstrict: true */\n'use strict';\n\ndocument.webL10n = (function(window, document, undefined) {\n var gL10nData = {};\n var gTextData = '';\n var gTextProp = 'textContent';\n var gLanguage = '';\n var gMacros = {};\n var gReadyState = 'loading';\n\n\n /**\n * Synchronously loading l10n resources significantly minimizes flickering\n * from displaying the app with non-localized strings and then updating the\n * strings. Although this will block all script execution on this page, we\n * expect that the l10n resources are available locally on flash-storage.\n *\n * As synchronous XHR is generally considered as a bad idea, we're still\n * loading l10n resources asynchronously -- but we keep this in a setting,\n * just in case... and applications using this library should hide their\n * content until the `localized' event happens.\n */\n\n var gAsyncResourceLoading = true; // read-only\n\n\n /**\n * DOM helpers for the so-called \"HTML API\".\n *\n * These functions are written for modern browsers. For old versions of IE,\n * they're overridden in the 'startup' section at the end of this file.\n */\n\n function getL10nResourceLinks() {\n return document.querySelectorAll('link[type=\"application/l10n\"]');\n }\n\n function getL10nDictionary() {\n var script = document.querySelector('script[type=\"application/l10n\"]');\n // TODO: support multiple and external JSON dictionaries\n return script ? JSON.parse(script.innerHTML) : null;\n }\n\n function getTranslatableChildren(element) {\n return element ? element.querySelectorAll('*[data-l10n-id]') : [];\n }\n\n function getL10nAttributes(element) {\n if (!element)\n return {};\n\n var l10nId = element.getAttribute('data-l10n-id');\n var l10nArgs = element.getAttribute('data-l10n-args');\n var args = {};\n if (l10nArgs) {\n try {\n args = JSON.parse(l10nArgs);\n } catch (e) {\n console.warn('could not parse arguments for #' + l10nId);\n }\n }\n return { id: l10nId, args: args };\n }\n\n function fireL10nReadyEvent(lang) {\n var evtObject = document.createEvent('Event');\n evtObject.initEvent('localized', true, false);\n evtObject.language = lang;\n document.dispatchEvent(evtObject);\n }\n\n function xhrLoadText(url, onSuccess, onFailure) {\n onSuccess = onSuccess || function _onSuccess(data) {};\n onFailure = onFailure || function _onFailure() {};\n\n var xhr = new XMLHttpRequest();\n xhr.open('GET', url, gAsyncResourceLoading);\n if (xhr.overrideMimeType) {\n xhr.overrideMimeType('text/plain; charset=utf-8');\n }\n xhr.onreadystatechange = function() {\n if (xhr.readyState == 4) {\n if (xhr.status == 200 || xhr.status === 0) {\n onSuccess(xhr.responseText);\n } else {\n onFailure();\n }\n }\n };\n xhr.onerror = onFailure;\n xhr.ontimeout = onFailure;\n\n // in Firefox OS with the app:// protocol, trying to XHR a non-existing\n // URL will raise an exception here -- hence this ugly try...catch.\n try {\n xhr.send(null);\n } catch (e) {\n onFailure();\n }\n }\n\n\n /**\n * l10n resource parser:\n * - reads (async XHR) the l10n resource matching `lang';\n * - imports linked resources (synchronously) when specified;\n * - parses the text data (fills `gL10nData' and `gTextData');\n * - triggers success/failure callbacks when done.\n *\n * @param {string} href\n * URL of the l10n resource to parse.\n *\n * @param {string} lang\n * locale (language) to parse. Must be a lowercase string.\n *\n * @param {Function} successCallback\n * triggered when the l10n resource has been successully parsed.\n *\n * @param {Function} failureCallback\n * triggered when the an error has occured.\n *\n * @return {void}\n * uses the following global variables: gL10nData, gTextData, gTextProp.\n */\n\n function parseResource(href, lang, successCallback, failureCallback) {\n var baseURL = href.replace(/[^\\/]*$/, '') || './';\n\n // handle escaped characters (backslashes) in a string\n function evalString(text) {\n if (text.lastIndexOf('\\\\') < 0)\n return text;\n return text.replace(/\\\\\\\\/g, '\\\\')\n .replace(/\\\\n/g, '\\n')\n .replace(/\\\\r/g, '\\r')\n .replace(/\\\\t/g, '\\t')\n .replace(/\\\\b/g, '\\b')\n .replace(/\\\\f/g, '\\f')\n .replace(/\\\\{/g, '{')\n .replace(/\\\\}/g, '}')\n .replace(/\\\\\"/g, '\"')\n .replace(/\\\\'/g, \"'\");\n }\n\n // parse *.properties text data into an l10n dictionary\n // If gAsyncResourceLoading is false, then the callback will be called\n // synchronously. Otherwise it is called asynchronously.\n function parseProperties(text, parsedPropertiesCallback) {\n var dictionary = {};\n\n // token expressions\n var reBlank = /^\\s*|\\s*$/;\n var reComment = /^\\s*#|^\\s*$/;\n var reSection = /^\\s*\\[(.*)\\]\\s*$/;\n var reImport = /^\\s*@import\\s+url\\((.*)\\)\\s*$/i;\n var reSplit = /^([^=\\s]*)\\s*=\\s*(.+)$/; // TODO: escape EOLs with '\\'\n\n // parse the *.properties file into an associative array\n function parseRawLines(rawText, extendedSyntax, parsedRawLinesCallback) {\n var entries = rawText.replace(reBlank, '').split(/[\\r\\n]+/);\n var currentLang = '*';\n var genericLang = lang.split('-', 1)[0];\n var skipLang = false;\n var match = '';\n\n function nextEntry() {\n // Use infinite loop instead of recursion to avoid reaching the\n // maximum recursion limit for content with many lines.\n while (true) {\n if (!entries.length) {\n parsedRawLinesCallback();\n return;\n }\n var line = entries.shift();\n\n // comment or blank line?\n if (reComment.test(line))\n continue;\n\n // the extended syntax supports [lang] sections and @import rules\n if (extendedSyntax) {\n match = reSection.exec(line);\n if (match) { // section start?\n // RFC 4646, section 4.4, \"All comparisons MUST be performed\n // in a case-insensitive manner.\"\n\n currentLang = match[1].toLowerCase();\n skipLang = (currentLang !== '*') &&\n (currentLang !== lang) && (currentLang !== genericLang);\n continue;\n } else if (skipLang) {\n continue;\n }\n match = reImport.exec(line);\n if (match) { // @import rule?\n loadImport(baseURL + match[1], nextEntry);\n return;\n }\n }\n\n // key-value pair\n var tmp = line.match(reSplit);\n if (tmp && tmp.length == 3) {\n dictionary[tmp[1]] = evalString(tmp[2]);\n }\n }\n }\n nextEntry();\n }\n\n // import another *.properties file\n function loadImport(url, callback) {\n xhrLoadText(url, function(content) {\n parseRawLines(content, false, callback); // don't allow recursive imports\n }, function () {\n console.warn(url + ' not found.');\n callback();\n });\n }\n\n // fill the dictionary\n parseRawLines(text, true, function() {\n parsedPropertiesCallback(dictionary);\n });\n }\n\n // load and parse l10n data (warning: global variables are used here)\n xhrLoadText(href, function(response) {\n gTextData += response; // mostly for debug\n\n // parse *.properties text data into an l10n dictionary\n parseProperties(response, function(data) {\n\n // find attribute descriptions, if any\n for (var key in data) {\n var id, prop, index = key.lastIndexOf('.');\n if (index > 0) { // an attribute has been specified\n id = key.substring(0, index);\n prop = key.substr(index + 1);\n } else { // no attribute: assuming text content by default\n id = key;\n prop = gTextProp;\n }\n if (!gL10nData[id]) {\n gL10nData[id] = {};\n }\n gL10nData[id][prop] = data[key];\n }\n\n // trigger callback\n if (successCallback) {\n successCallback();\n }\n });\n }, failureCallback);\n }\n\n // load and parse all resources for the specified locale\n function loadLocale(lang, callback) {\n // RFC 4646, section 2.1 states that language tags have to be treated as\n // case-insensitive. Convert to lowercase for case-insensitive comparisons.\n if (lang) {\n lang = lang.toLowerCase();\n }\n\n callback = callback || function _callback() {};\n\n clear();\n gLanguage = lang;\n\n // check all nodes\n // and load the resource files\n var langLinks = getL10nResourceLinks();\n var langCount = langLinks.length;\n if (langCount === 0) {\n // we might have a pre-compiled dictionary instead\n var dict = getL10nDictionary();\n if (dict && dict.locales && dict.default_locale) {\n console.log('using the embedded JSON directory, early way out');\n gL10nData = dict.locales[lang];\n if (!gL10nData) {\n var defaultLocale = dict.default_locale.toLowerCase();\n for (var anyCaseLang in dict.locales) {\n anyCaseLang = anyCaseLang.toLowerCase();\n if (anyCaseLang === lang) {\n gL10nData = dict.locales[lang];\n break;\n } else if (anyCaseLang === defaultLocale) {\n gL10nData = dict.locales[defaultLocale];\n }\n }\n }\n callback();\n } else {\n console.log('no resource to load, early way out');\n }\n // early way out\n fireL10nReadyEvent(lang);\n gReadyState = 'complete';\n return;\n }\n\n // start the callback when all resources are loaded\n var onResourceLoaded = null;\n var gResourceCount = 0;\n onResourceLoaded = function() {\n gResourceCount++;\n if (gResourceCount >= langCount) {\n callback();\n fireL10nReadyEvent(lang);\n gReadyState = 'complete';\n }\n };\n\n // load all resource files\n function L10nResourceLink(link) {\n var href = link.href;\n // Note: If |gAsyncResourceLoading| is false, then the following callbacks\n // are synchronously called.\n this.load = function(lang, callback) {\n parseResource(href, lang, callback, function() {\n console.warn(href + ' not found.');\n // lang not found, used default resource instead\n console.warn('\"' + lang + '\" resource not found');\n gLanguage = '';\n // Resource not loaded, but we still need to call the callback.\n callback();\n });\n };\n }\n\n for (var i = 0; i < langCount; i++) {\n var resource = new L10nResourceLink(langLinks[i]);\n resource.load(lang, onResourceLoaded);\n }\n }\n\n // clear all l10n data\n function clear() {\n gL10nData = {};\n gTextData = '';\n gLanguage = '';\n // TODO: clear all non predefined macros.\n // There's no such macro /yet/ but we're planning to have some...\n }\n\n\n /**\n * Get rules for plural forms (shared with JetPack), see:\n * http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html\n * https://github.com/mozilla/addon-sdk/blob/master/python-lib/plural-rules-generator.p\n *\n * @param {string} lang\n * locale (language) used.\n *\n * @return {Function}\n * returns a function that gives the plural form name for a given integer:\n * var fun = getPluralRules('en');\n * fun(1) -> 'one'\n * fun(0) -> 'other'\n * fun(1000) -> 'other'.\n */\n\n function getPluralRules(lang) {\n var locales2rules = {\n 'af': 3,\n 'ak': 4,\n 'am': 4,\n 'ar': 1,\n 'asa': 3,\n 'az': 0,\n 'be': 11,\n 'bem': 3,\n 'bez': 3,\n 'bg': 3,\n 'bh': 4,\n 'bm': 0,\n 'bn': 3,\n 'bo': 0,\n 'br': 20,\n 'brx': 3,\n 'bs': 11,\n 'ca': 3,\n 'cgg': 3,\n 'chr': 3,\n 'cs': 12,\n 'cy': 17,\n 'da': 3,\n 'de': 3,\n 'dv': 3,\n 'dz': 0,\n 'ee': 3,\n 'el': 3,\n 'en': 3,\n 'eo': 3,\n 'es': 3,\n 'et': 3,\n 'eu': 3,\n 'fa': 0,\n 'ff': 5,\n 'fi': 3,\n 'fil': 4,\n 'fo': 3,\n 'fr': 5,\n 'fur': 3,\n 'fy': 3,\n 'ga': 8,\n 'gd': 24,\n 'gl': 3,\n 'gsw': 3,\n 'gu': 3,\n 'guw': 4,\n 'gv': 23,\n 'ha': 3,\n 'haw': 3,\n 'he': 2,\n 'hi': 4,\n 'hr': 11,\n 'hu': 0,\n 'id': 0,\n 'ig': 0,\n 'ii': 0,\n 'is': 3,\n 'it': 3,\n 'iu': 7,\n 'ja': 0,\n 'jmc': 3,\n 'jv': 0,\n 'ka': 0,\n 'kab': 5,\n 'kaj': 3,\n 'kcg': 3,\n 'kde': 0,\n 'kea': 0,\n 'kk': 3,\n 'kl': 3,\n 'km': 0,\n 'kn': 0,\n 'ko': 0,\n 'ksb': 3,\n 'ksh': 21,\n 'ku': 3,\n 'kw': 7,\n 'lag': 18,\n 'lb': 3,\n 'lg': 3,\n 'ln': 4,\n 'lo': 0,\n 'lt': 10,\n 'lv': 6,\n 'mas': 3,\n 'mg': 4,\n 'mk': 16,\n 'ml': 3,\n 'mn': 3,\n 'mo': 9,\n 'mr': 3,\n 'ms': 0,\n 'mt': 15,\n 'my': 0,\n 'nah': 3,\n 'naq': 7,\n 'nb': 3,\n 'nd': 3,\n 'ne': 3,\n 'nl': 3,\n 'nn': 3,\n 'no': 3,\n 'nr': 3,\n 'nso': 4,\n 'ny': 3,\n 'nyn': 3,\n 'om': 3,\n 'or': 3,\n 'pa': 3,\n 'pap': 3,\n 'pl': 13,\n 'ps': 3,\n 'pt': 3,\n 'rm': 3,\n 'ro': 9,\n 'rof': 3,\n 'ru': 11,\n 'rwk': 3,\n 'sah': 0,\n 'saq': 3,\n 'se': 7,\n 'seh': 3,\n 'ses': 0,\n 'sg': 0,\n 'sh': 11,\n 'shi': 19,\n 'sk': 12,\n 'sl': 14,\n 'sma': 7,\n 'smi': 7,\n 'smj': 7,\n 'smn': 7,\n 'sms': 7,\n 'sn': 3,\n 'so': 3,\n 'sq': 3,\n 'sr': 11,\n 'ss': 3,\n 'ssy': 3,\n 'st': 3,\n 'sv': 3,\n 'sw': 3,\n 'syr': 3,\n 'ta': 3,\n 'te': 3,\n 'teo': 3,\n 'th': 0,\n 'ti': 4,\n 'tig': 3,\n 'tk': 3,\n 'tl': 4,\n 'tn': 3,\n 'to': 0,\n 'tr': 0,\n 'ts': 3,\n 'tzm': 22,\n 'uk': 11,\n 'ur': 3,\n 've': 3,\n 'vi': 0,\n 'vun': 3,\n 'wa': 4,\n 'wae': 3,\n 'wo': 0,\n 'xh': 3,\n 'xog': 3,\n 'yo': 0,\n 'zh': 0,\n 'zu': 3\n };\n\n // utility functions for plural rules methods\n function isIn(n, list) {\n return list.indexOf(n) !== -1;\n }\n function isBetween(n, start, end) {\n return start <= n && n <= end;\n }\n\n // list of all plural rules methods:\n // map an integer to the plural form name to use\n var pluralRules = {\n '0': function(n) {\n return 'other';\n },\n '1': function(n) {\n if ((isBetween((n % 100), 3, 10)))\n return 'few';\n if (n === 0)\n return 'zero';\n if ((isBetween((n % 100), 11, 99)))\n return 'many';\n if (n == 2)\n return 'two';\n if (n == 1)\n return 'one';\n return 'other';\n },\n '2': function(n) {\n if (n !== 0 && (n % 10) === 0)\n return 'many';\n if (n == 2)\n return 'two';\n if (n == 1)\n return 'one';\n return 'other';\n },\n '3': function(n) {\n if (n == 1)\n return 'one';\n return 'other';\n },\n '4': function(n) {\n if ((isBetween(n, 0, 1)))\n return 'one';\n return 'other';\n },\n '5': function(n) {\n if ((isBetween(n, 0, 2)) && n != 2)\n return 'one';\n return 'other';\n },\n '6': function(n) {\n if (n === 0)\n return 'zero';\n if ((n % 10) == 1 && (n % 100) != 11)\n return 'one';\n return 'other';\n },\n '7': function(n) {\n if (n == 2)\n return 'two';\n if (n == 1)\n return 'one';\n return 'other';\n },\n '8': function(n) {\n if ((isBetween(n, 3, 6)))\n return 'few';\n if ((isBetween(n, 7, 10)))\n return 'many';\n if (n == 2)\n return 'two';\n if (n == 1)\n return 'one';\n return 'other';\n },\n '9': function(n) {\n if (n === 0 || n != 1 && (isBetween((n % 100), 1, 19)))\n return 'few';\n if (n == 1)\n return 'one';\n return 'other';\n },\n '10': function(n) {\n if ((isBetween((n % 10), 2, 9)) && !(isBetween((n % 100), 11, 19)))\n return 'few';\n if ((n % 10) == 1 && !(isBetween((n % 100), 11, 19)))\n return 'one';\n return 'other';\n },\n '11': function(n) {\n if ((isBetween((n % 10), 2, 4)) && !(isBetween((n % 100), 12, 14)))\n return 'few';\n if ((n % 10) === 0 ||\n (isBetween((n % 10), 5, 9)) ||\n (isBetween((n % 100), 11, 14)))\n return 'many';\n if ((n % 10) == 1 && (n % 100) != 11)\n return 'one';\n return 'other';\n },\n '12': function(n) {\n if ((isBetween(n, 2, 4)))\n return 'few';\n if (n == 1)\n return 'one';\n return 'other';\n },\n '13': function(n) {\n if ((isBetween((n % 10), 2, 4)) && !(isBetween((n % 100), 12, 14)))\n return 'few';\n if (n != 1 && (isBetween((n % 10), 0, 1)) ||\n (isBetween((n % 10), 5, 9)) ||\n (isBetween((n % 100), 12, 14)))\n return 'many';\n if (n == 1)\n return 'one';\n return 'other';\n },\n '14': function(n) {\n if ((isBetween((n % 100), 3, 4)))\n return 'few';\n if ((n % 100) == 2)\n return 'two';\n if ((n % 100) == 1)\n return 'one';\n return 'other';\n },\n '15': function(n) {\n if (n === 0 || (isBetween((n % 100), 2, 10)))\n return 'few';\n if ((isBetween((n % 100), 11, 19)))\n return 'many';\n if (n == 1)\n return 'one';\n return 'other';\n },\n '16': function(n) {\n if ((n % 10) == 1 && n != 11)\n return 'one';\n return 'other';\n },\n '17': function(n) {\n if (n == 3)\n return 'few';\n if (n === 0)\n return 'zero';\n if (n == 6)\n return 'many';\n if (n == 2)\n return 'two';\n if (n == 1)\n return 'one';\n return 'other';\n },\n '18': function(n) {\n if (n === 0)\n return 'zero';\n if ((isBetween(n, 0, 2)) && n !== 0 && n != 2)\n return 'one';\n return 'other';\n },\n '19': function(n) {\n if ((isBetween(n, 2, 10)))\n return 'few';\n if ((isBetween(n, 0, 1)))\n return 'one';\n return 'other';\n },\n '20': function(n) {\n if ((isBetween((n % 10), 3, 4) || ((n % 10) == 9)) && !(\n isBetween((n % 100), 10, 19) ||\n isBetween((n % 100), 70, 79) ||\n isBetween((n % 100), 90, 99)\n ))\n return 'few';\n if ((n % 1000000) === 0 && n !== 0)\n return 'many';\n if ((n % 10) == 2 && !isIn((n % 100), [12, 72, 92]))\n return 'two';\n if ((n % 10) == 1 && !isIn((n % 100), [11, 71, 91]))\n return 'one';\n return 'other';\n },\n '21': function(n) {\n if (n === 0)\n return 'zero';\n if (n == 1)\n return 'one';\n return 'other';\n },\n '22': function(n) {\n if ((isBetween(n, 0, 1)) || (isBetween(n, 11, 99)))\n return 'one';\n return 'other';\n },\n '23': function(n) {\n if ((isBetween((n % 10), 1, 2)) || (n % 20) === 0)\n return 'one';\n return 'other';\n },\n '24': function(n) {\n if ((isBetween(n, 3, 10) || isBetween(n, 13, 19)))\n return 'few';\n if (isIn(n, [2, 12]))\n return 'two';\n if (isIn(n, [1, 11]))\n return 'one';\n return 'other';\n }\n };\n\n // return a function that gives the plural form name for a given integer\n var index = locales2rules[lang.replace(/-.*$/, '')];\n if (!(index in pluralRules)) {\n console.warn('plural form unknown for [' + lang + ']');\n return function() { return 'other'; };\n }\n return pluralRules[index];\n }\n\n // pre-defined 'plural' macro\n gMacros.plural = function(str, param, key, prop) {\n var n = parseFloat(param);\n if (isNaN(n))\n return str;\n\n // TODO: support other properties (l20n still doesn't...)\n if (prop != gTextProp)\n return str;\n\n // initialize _pluralRules\n if (!gMacros._pluralRules) {\n gMacros._pluralRules = getPluralRules(gLanguage);\n }\n var index = '[' + gMacros._pluralRules(n) + ']';\n\n // try to find a [zero|one|two] key if it's defined\n if (n === 0 && (key + '[zero]') in gL10nData) {\n str = gL10nData[key + '[zero]'][prop];\n } else if (n == 1 && (key + '[one]') in gL10nData) {\n str = gL10nData[key + '[one]'][prop];\n } else if (n == 2 && (key + '[two]') in gL10nData) {\n str = gL10nData[key + '[two]'][prop];\n } else if ((key + index) in gL10nData) {\n str = gL10nData[key + index][prop];\n } else if ((key + '[other]') in gL10nData) {\n str = gL10nData[key + '[other]'][prop];\n }\n\n return str;\n };\n\n\n /**\n * l10n dictionary functions\n */\n\n // fetch an l10n object, warn if not found, apply `args' if possible\n function getL10nData(key, args, fallback) {\n var data = gL10nData[key];\n if (!data) {\n console.warn('#' + key + ' is undefined.');\n if (!fallback) {\n return null;\n }\n data = fallback;\n }\n\n /** This is where l10n expressions should be processed.\n * The plan is to support C-style expressions from the l20n project;\n * until then, only two kinds of simple expressions are supported:\n * {[ index ]} and {{ arguments }}.\n */\n var rv = {};\n for (var prop in data) {\n var str = data[prop];\n str = substIndexes(str, args, key, prop);\n str = substArguments(str, args, key);\n rv[prop] = str;\n }\n return rv;\n }\n\n // replace {[macros]} with their values\n function substIndexes(str, args, key, prop) {\n var reIndex = /\\{\\[\\s*([a-zA-Z]+)\\(([a-zA-Z]+)\\)\\s*\\]\\}/;\n var reMatch = reIndex.exec(str);\n if (!reMatch || !reMatch.length)\n return str;\n\n // an index/macro has been found\n // Note: at the moment, only one parameter is supported\n var macroName = reMatch[1];\n var paramName = reMatch[2];\n var param;\n if (args && paramName in args) {\n param = args[paramName];\n } else if (paramName in gL10nData) {\n param = gL10nData[paramName];\n }\n\n // there's no macro parser yet: it has to be defined in gMacros\n if (macroName in gMacros) {\n var macro = gMacros[macroName];\n str = macro(str, param, key, prop);\n }\n return str;\n }\n\n // replace {{arguments}} with their values\n function substArguments(str, args, key) {\n var reArgs = /\\{\\{\\s*(.+?)\\s*\\}\\}/g;\n return str.replace(reArgs, function(matched_text, arg) {\n if (args && arg in args) {\n return args[arg];\n }\n if (arg in gL10nData) {\n return gL10nData[arg];\n }\n console.log('argument {{' + arg + '}} for #' + key + ' is undefined.');\n return matched_text;\n });\n }\n\n // translate an HTML element\n function translateElement(element) {\n var l10n = getL10nAttributes(element);\n if (!l10n.id)\n return;\n\n // get the related l10n object\n var data = getL10nData(l10n.id, l10n.args);\n if (!data) {\n console.warn('#' + l10n.id + ' is undefined.');\n return;\n }\n\n // translate element (TODO: security checks?)\n if (data[gTextProp]) { // XXX\n if (getChildElementCount(element) === 0) {\n element[gTextProp] = data[gTextProp];\n } else {\n // this element has element children: replace the content of the first\n // (non-empty) child textNode and clear other child textNodes\n var children = element.childNodes;\n var found = false;\n for (var i = 0, l = children.length; i < l; i++) {\n if (children[i].nodeType === 3 && /\\S/.test(children[i].nodeValue)) {\n if (found) {\n children[i].nodeValue = '';\n } else {\n children[i].nodeValue = data[gTextProp];\n found = true;\n }\n }\n }\n // if no (non-empty) textNode is found, insert a textNode before the\n // first element child.\n if (!found) {\n var textNode = document.createTextNode(data[gTextProp]);\n element.insertBefore(textNode, element.firstChild);\n }\n }\n delete data[gTextProp];\n }\n\n for (var k in data) {\n element[k] = data[k];\n }\n }\n\n // webkit browsers don't currently support 'children' on SVG elements...\n function getChildElementCount(element) {\n if (element.children) {\n return element.children.length;\n }\n if (typeof element.childElementCount !== 'undefined') {\n return element.childElementCount;\n }\n var count = 0;\n for (var i = 0; i < element.childNodes.length; i++) {\n count += element.nodeType === 1 ? 1 : 0;\n }\n return count;\n }\n\n // translate an HTML subtree\n function translateFragment(element) {\n element = element || document.documentElement;\n\n // check all translatable children (= w/ a `data-l10n-id' attribute)\n var children = getTranslatableChildren(element);\n var elementCount = children.length;\n for (var i = 0; i < elementCount; i++) {\n translateElement(children[i]);\n }\n\n // translate element itself if necessary\n translateElement(element);\n }\n\n return {\n // get a localized string\n get: function(key, args, fallbackString) {\n var index = key.lastIndexOf('.');\n var prop = gTextProp;\n if (index > 0) { // An attribute has been specified\n prop = key.substr(index + 1);\n key = key.substring(0, index);\n }\n var fallback;\n if (fallbackString) {\n fallback = {};\n fallback[prop] = fallbackString;\n }\n var data = getL10nData(key, args, fallback);\n if (data && prop in data) {\n return data[prop];\n }\n return '{{' + key + '}}';\n },\n\n // debug\n getData: function() { return gL10nData; },\n getText: function() { return gTextData; },\n\n // get|set the document language\n getLanguage: function() { return gLanguage; },\n setLanguage: function(lang, callback) {\n loadLocale(lang, function() {\n if (callback)\n callback();\n });\n },\n\n // get the direction (ltr|rtl) of the current language\n getDirection: function() {\n // http://www.w3.org/International/questions/qa-scripts\n // Arabic, Hebrew, Farsi, Pashto, Urdu\n var rtlList = ['ar', 'he', 'fa', 'ps', 'ur'];\n var shortCode = gLanguage.split('-', 1)[0];\n return (rtlList.indexOf(shortCode) >= 0) ? 'rtl' : 'ltr';\n },\n\n // translate an element or document fragment\n translate: translateFragment,\n\n // this can be used to prevent race conditions\n getReadyState: function() { return gReadyState; },\n ready: function(callback) {\n if (!callback) {\n return;\n } else if (gReadyState == 'complete' || gReadyState == 'interactive') {\n window.setTimeout(function() {\n callback();\n });\n } else if (document.addEventListener) {\n document.addEventListener('localized', function once() {\n document.removeEventListener('localized', once);\n callback();\n });\n }\n }\n };\n}) (window, document);\n\n\n\n// WEBPACK FOOTER //\n// external/webL10n/l10n.js","/* Copyright 2016 Mozilla Foundation\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { CSS_UNITS, NullL10n } from './ui_utils';\nimport { PDFPrintServiceFactory, PDFViewerApplication } from './app';\nimport { PDFJS } from 'pdfjs-lib';\n\nlet activeService = null;\nlet overlayManager = null;\n\n// Renders the page to the canvas of the given print service, and returns\n// the suggested dimensions of the output page.\nfunction renderPage(activeServiceOnEntry, pdfDocument, pageNumber, size) {\n var scratchCanvas = activeService.scratchCanvas;\n\n // The size of the canvas in pixels for printing.\n var PRINT_RESOLUTION = 150;\n var PRINT_UNITS = PRINT_RESOLUTION / 72.0;\n scratchCanvas.width = Math.floor(size.width * PRINT_UNITS);\n scratchCanvas.height = Math.floor(size.height * PRINT_UNITS);\n\n // The physical size of the img as specified by the PDF document.\n var width = Math.floor(size.width * CSS_UNITS) + 'px';\n var height = Math.floor(size.height * CSS_UNITS) + 'px';\n\n var ctx = scratchCanvas.getContext('2d');\n ctx.save();\n ctx.fillStyle = 'rgb(255, 255, 255)';\n ctx.fillRect(0, 0, scratchCanvas.width, scratchCanvas.height);\n ctx.restore();\n\n return pdfDocument.getPage(pageNumber).then(function (pdfPage) {\n var renderContext = {\n canvasContext: ctx,\n transform: [PRINT_UNITS, 0, 0, PRINT_UNITS, 0, 0],\n viewport: pdfPage.getViewport(1, size.rotation),\n intent: 'print',\n };\n return pdfPage.render(renderContext).promise;\n }).then(function () {\n return {\n width,\n height,\n };\n });\n}\n\nfunction PDFPrintService(pdfDocument, pagesOverview, printContainer, l10n) {\n this.pdfDocument = pdfDocument;\n this.pagesOverview = pagesOverview;\n this.printContainer = printContainer;\n this.l10n = l10n || NullL10n;\n this.currentPage = -1;\n // The temporary canvas where renderPage paints one page at a time.\n this.scratchCanvas = document.createElement('canvas');\n}\n\nPDFPrintService.prototype = {\n layout() {\n this.throwIfInactive();\n\n var body = document.querySelector('body');\n body.setAttribute('data-pdfjsprinting', true);\n\n var hasEqualPageSizes = this.pagesOverview.every(function (size) {\n return size.width === this.pagesOverview[0].width &&\n size.height === this.pagesOverview[0].height;\n }, this);\n if (!hasEqualPageSizes) {\n console.warn('Not all pages have the same size. The printed ' +\n 'result may be incorrect!');\n }\n\n // Insert a @page + size rule to make sure that the page size is correctly\n // set. Note that we assume that all pages have the same size, because\n // variable-size pages are not supported yet (e.g. in Chrome & Firefox).\n // TODO(robwu): Use named pages when size calculation bugs get resolved\n // (e.g. https://crbug.com/355116) AND when support for named pages is\n // added (http://www.w3.org/TR/css3-page/#using-named-pages).\n // In browsers where @page + size is not supported (such as Firefox,\n // https://bugzil.la/851441), the next stylesheet will be ignored and the\n // user has to select the correct paper size in the UI if wanted.\n this.pageStyleSheet = document.createElement('style');\n var pageSize = this.pagesOverview[0];\n this.pageStyleSheet.textContent =\n // \"size: \" is what we need. But also add \"A4\" because\n // Firefox incorrectly reports support for the other value.\n '@supports ((size:A4) and (size:1pt 1pt)) {' +\n '@page { size: ' + pageSize.width + 'pt ' + pageSize.height + 'pt;}' +\n '}';\n body.appendChild(this.pageStyleSheet);\n },\n\n destroy() {\n if (activeService !== this) {\n // |activeService| cannot be replaced without calling destroy() first,\n // so if it differs then an external consumer has a stale reference to\n // us.\n return;\n }\n this.printContainer.textContent = '';\n if (this.pageStyleSheet && this.pageStyleSheet.parentNode) {\n this.pageStyleSheet.parentNode.removeChild(this.pageStyleSheet);\n this.pageStyleSheet = null;\n }\n this.scratchCanvas.width = this.scratchCanvas.height = 0;\n this.scratchCanvas = null;\n activeService = null;\n ensureOverlay().then(function () {\n if (overlayManager.active !== 'printServiceOverlay') {\n return; // overlay was already closed\n }\n overlayManager.close('printServiceOverlay');\n });\n },\n\n renderPages() {\n var pageCount = this.pagesOverview.length;\n var renderNextPage = (resolve, reject) => {\n this.throwIfInactive();\n if (++this.currentPage >= pageCount) {\n renderProgress(pageCount, pageCount, this.l10n);\n resolve();\n return;\n }\n var index = this.currentPage;\n renderProgress(index, pageCount, this.l10n);\n renderPage(this, this.pdfDocument, index + 1, this.pagesOverview[index])\n .then(this.useRenderedPage.bind(this))\n .then(function () {\n renderNextPage(resolve, reject);\n }, reject);\n };\n return new Promise(renderNextPage);\n },\n\n useRenderedPage(printItem) {\n this.throwIfInactive();\n var img = document.createElement('img');\n img.style.width = printItem.width;\n img.style.height = printItem.height;\n\n var scratchCanvas = this.scratchCanvas;\n if (('toBlob' in scratchCanvas) && !PDFJS.disableCreateObjectURL) {\n scratchCanvas.toBlob(function (blob) {\n img.src = URL.createObjectURL(blob);\n });\n } else {\n img.src = scratchCanvas.toDataURL();\n }\n\n var wrapper = document.createElement('div');\n wrapper.appendChild(img);\n this.printContainer.appendChild(wrapper);\n\n return new Promise(function (resolve, reject) {\n img.onload = resolve;\n img.onerror = reject;\n });\n },\n\n performPrint() {\n this.throwIfInactive();\n return new Promise((resolve) => {\n // Push window.print in the macrotask queue to avoid being affected by\n // the deprecation of running print() code in a microtask, see\n // https://github.com/mozilla/pdf.js/issues/7547.\n setTimeout(() => {\n if (!this.active) {\n resolve();\n return;\n }\n print.call(window);\n // Delay promise resolution in case print() was not synchronous.\n setTimeout(resolve, 20); // Tidy-up.\n }, 0);\n });\n },\n\n get active() {\n return this === activeService;\n },\n\n throwIfInactive() {\n if (!this.active) {\n throw new Error('This print request was cancelled or completed.');\n }\n },\n};\n\n\nvar print = window.print;\nwindow.print = function print() {\n if (activeService) {\n console.warn('Ignored window.print() because of a pending print job.');\n return;\n }\n ensureOverlay().then(function () {\n if (activeService) {\n overlayManager.open('printServiceOverlay');\n }\n });\n\n try {\n dispatchEvent('beforeprint');\n } finally {\n if (!activeService) {\n console.error('Expected print service to be initialized.');\n ensureOverlay().then(function () {\n if (overlayManager.active === 'printServiceOverlay') {\n overlayManager.close('printServiceOverlay');\n }\n });\n return; // eslint-disable-line no-unsafe-finally\n }\n var activeServiceOnEntry = activeService;\n activeService.renderPages().then(function () {\n return activeServiceOnEntry.performPrint();\n }).catch(function () {\n // Ignore any error messages.\n }).then(function () {\n // aborts acts on the \"active\" print request, so we need to check\n // whether the print request (activeServiceOnEntry) is still active.\n // Without the check, an unrelated print request (created after aborting\n // this print request while the pages were being generated) would be\n // aborted.\n if (activeServiceOnEntry.active) {\n abort();\n }\n });\n }\n};\n\nfunction dispatchEvent(eventType) {\n var event = document.createEvent('CustomEvent');\n event.initCustomEvent(eventType, false, false, 'custom');\n window.dispatchEvent(event);\n}\n\nfunction abort() {\n if (activeService) {\n activeService.destroy();\n dispatchEvent('afterprint');\n }\n}\n\nfunction renderProgress(index, total, l10n) {\n var progressContainer = document.getElementById('printServiceOverlay');\n var progress = Math.round(100 * index / total);\n var progressBar = progressContainer.querySelector('progress');\n var progressPerc = progressContainer.querySelector('.relative-progress');\n progressBar.value = progress;\n l10n.get('print_progress_percent', { progress, }, progress + '%').\n then((msg) => {\n progressPerc.textContent = msg;\n });\n}\n\nvar hasAttachEvent = !!document.attachEvent;\n\nwindow.addEventListener('keydown', function(event) {\n // Intercept Cmd/Ctrl + P in all browsers.\n // Also intercept Cmd/Ctrl + Shift + P in Chrome and Opera\n if (event.keyCode === /* P= */ 80 && (event.ctrlKey || event.metaKey) &&\n !event.altKey && (!event.shiftKey || window.chrome || window.opera)) {\n window.print();\n if (hasAttachEvent) {\n // Only attachEvent can cancel Ctrl + P dialog in IE <=10\n // attachEvent is gone in IE11, so the dialog will re-appear in IE11.\n return;\n }\n event.preventDefault();\n if (event.stopImmediatePropagation) {\n event.stopImmediatePropagation();\n } else {\n event.stopPropagation();\n }\n return;\n }\n}, true);\nif (hasAttachEvent) {\n document.attachEvent('onkeydown', function(event) {\n event = event || window.event;\n if (event.keyCode === /* P= */ 80 && event.ctrlKey) {\n event.keyCode = 0;\n return false;\n }\n });\n}\n\nif ('onbeforeprint' in window) {\n // Do not propagate before/afterprint events when they are not triggered\n // from within this polyfill. (FF/IE).\n var stopPropagationIfNeeded = function(event) {\n if (event.detail !== 'custom' && event.stopImmediatePropagation) {\n event.stopImmediatePropagation();\n }\n };\n window.addEventListener('beforeprint', stopPropagationIfNeeded);\n window.addEventListener('afterprint', stopPropagationIfNeeded);\n}\n\nvar overlayPromise;\nfunction ensureOverlay() {\n if (!overlayPromise) {\n overlayManager = PDFViewerApplication.overlayManager;\n if (!overlayManager) {\n throw new Error('The overlay manager has not yet been initialized.');\n }\n\n overlayPromise = overlayManager.register('printServiceOverlay',\n document.getElementById('printServiceOverlay'), abort, true);\n document.getElementById('printCancel').onclick = abort;\n }\n return overlayPromise;\n}\n\nPDFPrintServiceFactory.instance = {\n supportsPrinting: true,\n\n createPrintService(pdfDocument, pagesOverview, printContainer, l10n) {\n if (activeService) {\n throw new Error('The print service is created and active.');\n }\n activeService = new PDFPrintService(pdfDocument, pagesOverview,\n printContainer, l10n);\n return activeService;\n },\n};\n\nexport {\n PDFPrintService,\n};\n\n\n\n// WEBPACK FOOTER //\n// web/pdf_print_service.js"],"sourceRoot":""} \ No newline at end of file diff --git a/org.adempiere.ui.zk/theme/default/css/fragment/adwindow.css.dsp b/org.adempiere.ui.zk/theme/default/css/fragment/adwindow.css.dsp index 56899e6bc2..b24c341c05 100644 --- a/org.adempiere.ui.zk/theme/default/css/fragment/adwindow.css.dsp +++ b/org.adempiere.ui.zk/theme/default/css/fragment/adwindow.css.dsp @@ -18,6 +18,9 @@ .adwindow-form > .z-grid-body { background-color: #F9F9F9; } +.adwindow-form.z-grid > .z-grid-body { + overflow: visible !important; +} .adwindow-layout { position:absolute; @@ -74,10 +77,14 @@ .adwindow-toolbar { border: 0px; padding: 2px 4px; - height: 26px; + height: 30px; background-image: none; background-color: #fff; } +.adwindow-toolbar.mobile { + position: relative; + overflow: hidden; +} .adwindow-breadcrumb { height: 30px; diff --git a/org.adempiere.ui.zk/theme/default/css/fragment/application-menu.css.dsp b/org.adempiere.ui.zk/theme/default/css/fragment/application-menu.css.dsp index f825779245..e80395a62c 100644 --- a/org.adempiere.ui.zk/theme/default/css/fragment/application-menu.css.dsp +++ b/org.adempiere.ui.zk/theme/default/css/fragment/application-menu.css.dsp @@ -107,7 +107,39 @@ background-image:url(${c:encodeThemeURL('~./zul/img/tree/item-sel.gif')}); } +.global-search-box.z-bandbox { + display: flex; +} +.global-search-box.z-bandbox > input.z-bandbox-input { + flex-grow: 1; +} +.global-search-box.z-bandbox > .z-bandbox-button { + flex-grow: 0; +} .global-search-tabpanel { - width: 500px; + width: 600px; +} +@media screen and (max-width: 599px) { + .global-search-tabpanel { + width: 100%; + } +} +.global-search-box.z-bandbox { + width: 180px; +} +@media screen and (min-width: 500px) { + .global-search-box.z-bandbox { + width: 200px; + } +} +@media screen and (min-width: 768px) { + .global-search-box.z-bandbox { + width: 250px; + } +} +@media screen and (min-width: 1024px) { + .global-search-box.z-bandbox { + width: 300px; + } } diff --git a/org.adempiere.ui.zk/theme/default/css/fragment/borderlayout.css.dsp b/org.adempiere.ui.zk/theme/default/css/fragment/borderlayout.css.dsp index 6190a94059..1409a772c8 100644 --- a/org.adempiere.ui.zk/theme/default/css/fragment/borderlayout.css.dsp +++ b/org.adempiere.ui.zk/theme/default/css/fragment/borderlayout.css.dsp @@ -1,8 +1,12 @@ .z-south-splitter, .z-west-splitter, .z-east-splitter, .z-north-splitter { background: none !important; } +.z-north-splitter, .z-south-splitter { + height: 14px; + border: none; +} -.z-south-collapsed { +.z-south-collapsed, .z-north-collapsed { height: 24px; } @@ -10,7 +14,7 @@ box-shadow:inset 0 0 8px rgba(197,197,197,0.5); } -.z-south-collapsed .z-borderlayout-icon { +.z-south-collapsed .z-borderlayout-icon, .z-north-collapsed .z-borderlayout-icon { height: 12px; line-height: 12px; } @@ -51,3 +55,24 @@ -webkit-filter: brightness(50%); filter: brightness(50%); } + +.z-north.slide { + border-bottom: 1px solid #cfcfcf; + box-shadow: 0px 0px 1px 1px #cfcfcf; + padding-bottom: 4px; +} +.z-south.slide { + border-top: 1px solid #cfcfcf; + box-shadow: 0px 0px 1px 1px #cfcfcf; + padding-top: 4px; +} +.z-west.slide { + border-right: 1px solid #cfcfcf; + box-shadow: 0px 0px 1px 1px #cfcfcf; + padding-right: 4px; +} +.z-east.slide { + border-left: 1px solid #cfcfcf; + box-shadow: 0px 0px 1px 1px #cfcfcf; + padding-left: 4px; +} \ No newline at end of file diff --git a/org.adempiere.ui.zk/theme/default/css/fragment/button.css.dsp b/org.adempiere.ui.zk/theme/default/css/fragment/button.css.dsp index 9d2139d2e6..2e8d143cc8 100644 --- a/org.adempiere.ui.zk/theme/default/css/fragment/button.css.dsp +++ b/org.adempiere.ui.zk/theme/default/css/fragment/button.css.dsp @@ -81,6 +81,9 @@ .z-button.btn-small { padding: 1px 5px; } +.z-button.btn-medium { + padding: 2px 10px; +} .z-button-disabled { color: black; cursor: default; opacity: .6; -moz-opacity: .6; -khtml-opacity: .6; filter: alpha(opacity=60); diff --git a/org.adempiere.ui.zk/theme/default/css/fragment/desktop.css.dsp b/org.adempiere.ui.zk/theme/default/css/fragment/desktop.css.dsp index af7360176a..d1c26cac2c 100644 --- a/org.adempiere.ui.zk/theme/default/css/fragment/desktop.css.dsp +++ b/org.adempiere.ui.zk/theme/default/css/fragment/desktop.css.dsp @@ -20,6 +20,11 @@ width: 100%; height: 46px; border-bottom: 1px solid #C5C5C5 !important; + padding-left: 4px; +} +.desktop-header.mobile { + height: 36px; + padding: 4px 4px; } .desktop-header-font { @@ -52,6 +57,9 @@ .desktop-user-panel { float: right; } +.desktop-user-panel.mobile .desktop-header-font.desktop-header-username { + font-weight: 600; +} .desktop-layout { position: absolute; @@ -71,6 +79,11 @@ .desktop-tabbox .z-tab { height: 24px; } +@media screen and (max-width: 360px) { + .desktop-tabbox .z-tab { + max-width: 190px; + } +} .desktop-tabbox .z-tab-selected { height: 25px; @@ -222,34 +235,16 @@ <%-- window container --%> .window-container-toolbar-btn .z-toolbarbutton-content img { - width: 22px; - height: 22px; -} - -.window-container-toolbar-btn.context-help-btn .z-toolbarbutton-content img { width: 16px; height: 16px; padding: 3px 3px; } -@media screen and (min-width: 720px) { - .desktop-header > .z-hlayout-inner { - width: 50%; - height: 100%; + +@media screen and (max-height: 767px) { + .adtab-form-borderlayout.z-borderlayout > div > .z-south-collapsed > .z-borderlayout-icon.z-icon-chevron-up { + display: none; + } + .adtab-form-borderlayout.z-borderlayout > div > .adwindow-gridview-detail.z-south { + height: 80%; } } -@media screen and (max-width: 720px) { - .desktop-header { - width: 100%; - height: 100%; - - } - .desktop-user-panel { - float: none; - } - .desktop-header > .z-hlayout-inner { - width: 100%; - height: 40%; - display: block; - } - -} diff --git a/org.adempiere.ui.zk/theme/default/css/fragment/field-editor.css.dsp b/org.adempiere.ui.zk/theme/default/css/fragment/field-editor.css.dsp index a0d4807313..0b7a156792 100644 --- a/org.adempiere.ui.zk/theme/default/css/fragment/field-editor.css.dsp +++ b/org.adempiere.ui.zk/theme/default/css/fragment/field-editor.css.dsp @@ -19,6 +19,9 @@ width: 100%; height: 21px; } +.editor-input.mobile.z-decimalbox { + padding-right: 5px; +} .editor-input:focus { border: 1px solid #0000ff; diff --git a/org.adempiere.ui.zk/theme/default/css/fragment/gadget.css.dsp b/org.adempiere.ui.zk/theme/default/css/fragment/gadget.css.dsp index ae5d65b859..d519f03bce 100644 --- a/org.adempiere.ui.zk/theme/default/css/fragment/gadget.css.dsp +++ b/org.adempiere.ui.zk/theme/default/css/fragment/gadget.css.dsp @@ -51,7 +51,7 @@ .dashboard-layout { width: 100%; height: 100%; - position: absolute; + position: relative; } .dashboard-widget { diff --git a/org.adempiere.ui.zk/theme/default/css/fragment/info-window.css.dsp b/org.adempiere.ui.zk/theme/default/css/fragment/info-window.css.dsp index 109d179bf8..2dff0a8600 100644 --- a/org.adempiere.ui.zk/theme/default/css/fragment/info-window.css.dsp +++ b/org.adempiere.ui.zk/theme/default/css/fragment/info-window.css.dsp @@ -29,3 +29,6 @@ background-color: #FFFFFF; } +.info-panel.z-window .z-borderlayout > div > .z-north { + max-height: 50%; +} diff --git a/org.adempiere.ui.zk/theme/default/css/fragment/login.css.dsp b/org.adempiere.ui.zk/theme/default/css/fragment/login.css.dsp index 57a4a84dbf..b19b5c31d7 100644 --- a/org.adempiere.ui.zk/theme/default/css/fragment/login.css.dsp +++ b/org.adempiere.ui.zk/theme/default/css/fragment/login.css.dsp @@ -79,3 +79,34 @@ background-color: #E0EAF7; position: relative; } +@media screen and (max-width: 659px) { + .login-box-body, .login-box-header, .login-box-footer { + background-image: none; + width: 90%; + } + .login-box-footer .confirm-panel, .login-box-footer-pnl { + width: 90% !important; + } + .login-box-header-txt { + display: none; + } +} +@media screen and (max-height: 600px) { + .login-box-header-txt { + display: none; + } + .login-box-body, .login-box-header, .login-box-footer { + background-image: none; + } + .login-box-body { + padding-bottom: 10px; + } + .login-box-header { + height: 0px; + } +} +@media screen and (max-width: 359px) { + .login-window .z-center > .z-center-body .z-window.z-window-embedded > .z-window-content { + padding: 0px + } +} diff --git a/org.adempiere.ui.zk/theme/default/css/fragment/parameter-process.css.dsp b/org.adempiere.ui.zk/theme/default/css/fragment/parameter-process.css.dsp index 23b82b4086..a68aa43625 100644 --- a/org.adempiere.ui.zk/theme/default/css/fragment/parameter-process.css.dsp +++ b/org.adempiere.ui.zk/theme/default/css/fragment/parameter-process.css.dsp @@ -19,6 +19,9 @@ when detect side effect, fix to only apply for parameter window*/ .bottom-container{ width: 100%; } +.report-option-container { + overflow-x: auto; +} .top-parameter-layout{ overflow: auto; } @@ -38,21 +41,30 @@ when detect side effect, fix to only apply for parameter window*/ } .bottom-container{ - overflow: auto; + overflow: hidden; } .button-container{ float: right; + overflow: hidden; + padding: 4px; } .save-parameter-container{ - float: left; + overflow-x: auto; + overflow-y: hidden; } .popup-dialog.z-window.z-window-overlapped.z-window-shadow, .popup-dialog.z-window.z-window-noborder.z-window-highlighted.z-window-shadow{ width:600px; } +@media screen and (max-width: 600px) { + .popup-dialog.z-window.z-window-overlapped.z-window-shadow, + .popup-dialog.z-window.z-window-noborder.z-window-highlighted.z-window-shadow{ + width:100%; + } +} .input-paramenter-layout{ width: 70%; diff --git a/org.adempiere.ui.zk/theme/default/css/fragment/window-size.css.dsp b/org.adempiere.ui.zk/theme/default/css/fragment/window-size.css.dsp new file mode 100644 index 0000000000..5ed9a88f46 --- /dev/null +++ b/org.adempiere.ui.zk/theme/default/css/fragment/window-size.css.dsp @@ -0,0 +1,375 @@ +.about-window { + width: 600px; + height: 450px; +} +@media screen and (max-width: 600px) { + .about-window { + width: 100%; + } +} +@media screen and (max-height: 450px) { + .about-window { + height: 100%; + } +} + +.customize-grid-view-dialog { + width: 600px; + height: 500px; +} +@media screen and (max-width: 600px) { + .customize-grid-view-dialog { + width: 100%; + } +} +@media screen and (max-height: 500px) { + .customize-grid-view-dialog { + height: 100%; + } +} + +.attachment-dialog.popup-dialog.z-window.z-window-overlapped { + width: 700px; + height: 85%; +} +@media screen and (max-width: 700px) { + .attachment-dialog.popup-dialog.z-window.z-window-overlapped { + width: 100%; + } +} +@media screen and (max-height: 600px) { + .attachment-dialog.popup-dialog.z-window.z-window-overlapped { + height: 100%; + } +} + +.chat-dialog.popup-dialog.z-window.z-window-overlapped { + height: 88%; + width: 500px; +} +@media screen and (max-width: 500px) { + .chat-dialog.popup-dialog.z-window.z-window-overlapped { + width: 100%; + } +} +@media screen and (max-height: 600px) { + .chat-dialog.popup-dialog.z-window.z-window-overlapped { + height: 100%; + } +} + +.email-dialog { + height: 80%; + width: 80%; +} +@media screen and (max-width: 600px) { + .email-dialog { + width: 100%; + } +} +@media screen and (max-height: 600px) { + .email-dialog { + height: 100%; + } +} + +.field-record-info-dialog { + width: 640px; + height: 480px; +} +@media screen and (max-width: 640px) { + .field-record-info-dialog { + width: 100%; + } +} +@media screen and (max-height: 480px) { + .field-record-info-dialog { + height: 100%; + } +} + +.record-info-dialog { + width: 500px; + height: 400px; +} +@media screen and (max-width: 500px) { + .record-info-dialog { + width: 100%; + } +} +@media screen and (max-height: 400px) { + .record-info-dialog { + height: 100%; + } +} + +.value-preference-dialog { + width: 500px; +} +@media screen and (max-width: 500px) { + .value-preference-dialog { + width: 100%; + } +} + +.pattribute-dialog { + width: 500px; +} +@media screen and (max-width: 500px) { + .pattribute-dialog { + width: 100%; + } +} + +.pattribute-instance-dialog { + width: 1000px; + height: 550px; +} +@media screen and (max-width: 1000px) { + .pattribute-instance-dialog { + width: 100%; + } +} +@media screen and (max-height: 550px) { + .pattribute-instance-dialog { + height: 100%; + } +} + +.account-dialog { + height: 500px; + width: 750px; +} +@media screen and (max-width: 750px) { + .account-dialog { + width: 100%; + } +} +@media screen and (max-height: 500px) { + .account-dialog { + height: 100%; + } +} +@media screen and (max-width: 719px) { + .account-dialog { + height: 100%; + } +} + +.invoice-history-dialog { + width: 700px; + height: 500px; +} +@media screen and (max-width: 700px) { + .invoice-history-dialog { + width: 100%; + } +} +@media screen and (max-height: 500px) { + .invoice-history-dialog { + height: 100%; + } +} + +.create-from-window { + width: 750px; + height: 550px; +} +@media screen and (max-width: 750px) { + .create-from-window { + width: 100%; + } +} +@media screen and (max-height: 550px) { + .create-from-window { + height: 100%; + } +} + +.create-from-form { + width: 750px; + height: 550px; +} +@media screen and (max-width: 750px) { + .create-from-form { + width: 100%; + } +} +@media screen and (max-height: 550px) { + .create-from-form { + height: 100%; + } +} + +.payment-form-dialog { + width: 500px; +} +@media screen and (max-width: 500px) { + .payment-form-dialog { + width: 100%; + } +} + +.process-parameter-form-dialog { + width: 500px; +} +@media screen and (max-width: 500px) { + .process-parameter-form-dialog { + width: 100%; + } +} + +.quick-entry-dialog { + width: 350px; +} +.quick-entry-dialog > .z-window-content { + overflow: auto; +} +@media screen and (max-width: 350px) { + .quick-entry-dialog { + width: 100%; + } +} +@media screen and (max-height: 500px) { + .quick-entry-dialog { + height: 100%; + } +} + +.feedback-request-dialog { + width: 400px; + height: 600px; +} +@media screen and (max-width: 400px) { + .feedback-request-dialog { + width: 100%; + } +} +@media screen and (max-height: 600px) { + .feedback-request-dialog { + height: 100%; + } +} + +.request-dialog { + width: 400px; + height: 550px; +} +@media screen and (max-width: 400px) { + .request-dialog { + width: 100%; + } +} +@media screen and (max-height: 550px) { + .request-dialog { + height: 100%; + } +} + +.image-dialog { + width: 640px; + height: 540px; +} +@media screen and (max-width: 640px) { + .image-dialog { + width: 100%; + } +} +@media screen and (max-height: 540px) { + .image-dialog { + height: 100%; + } +} + +.doc-action-dialog { + width: 410px; +} +@media screen and (max-width: 410px) { + .doc-action-dialog { + width: 100%; + } +} + +.assignment-dialog { + width: 600px; +} +@media screen and (max-width: 600px) { + .assignment-dialog { + width: 100%; + } +} + +.location-dialog { + width: 380px; + height: 420px; +} +@media screen and (max-width: 380px) { + .location-dialog { + width: 100%; + } +} +@media screen and (max-height: 420px) { + .location-dialog { + height: 100%; + } +} + +.locator-dialog { + width: 260px; + height: 350px; +} +@media screen and (max-width: 260px) { + .locator-dialog { + width: 100%; + } +} +@media screen and (max-height: 350px) { + .locator-dialog { + height: 100%; + } +} + +.media-dialog { + width: 500px; + height: 500px; +} +@media screen and (max-width: 500px) { + .media-dialog { + width: 100%; + } +} +@media screen and (max-height: 500px) { + .media-dialog { + height: 100%; + } +} + +.text-editor-dialog { + width: 800px; + height: 450px; +} +@media screen and (max-width: 800px) { + .text-editor-dialog { + width: 100%; + } +} +@media screen and (max-height: 450px) { + .text-editor-dialog { + height: 100%; + } +} + +.create-from-bank-statement.create-from-window { + width: 900px; + height: 800px; +} +@media screen and (max-width: 900px) { + .create-from-bank-statement.create-from-window { + width: 100%; + } +} +@media screen and (max-height: 800px) { + .create-from-bank-statement.create-from-window { + height: 100%; + } +} diff --git a/org.adempiere.ui.zk/theme/default/css/theme.css.dsp b/org.adempiere.ui.zk/theme/default/css/theme.css.dsp index fd9cc439f7..520033a618 100644 --- a/org.adempiere.ui.zk/theme/default/css/theme.css.dsp +++ b/org.adempiere.ui.zk/theme/default/css/theme.css.dsp @@ -87,3 +87,5 @@ table.z-vbox > tbody > tr > td > table { + + diff --git a/org.adempiere.ui.zk/theme/default/preference.zul b/org.adempiere.ui.zk/theme/default/preference.zul index 18a655c0d4..64393dbb7e 100644 --- a/org.adempiere.ui.zk/theme/default/preference.zul +++ b/org.adempiere.ui.zk/theme/default/preference.zul @@ -8,10 +8,12 @@
diff --git a/org.adempiere.ui.zk/theme/default/zul/desktop/header.zul b/org.adempiere.ui.zk/theme/default/zul/desktop/header.zul index ef83edb555..d536e975ab 100644 --- a/org.adempiere.ui.zk/theme/default/zul/desktop/header.zul +++ b/org.adempiere.ui.zk/theme/default/zul/desktop/header.zul @@ -1,19 +1,19 @@