Merge branch '1.8.0': get back XR to HTML stylesheet to be able to visualize ZF2
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
|
||||
1.7.2
|
||||
=====
|
||||
2019-07-06
|
||||
2019-07-08
|
||||
|
||||
Support BuyerReference (r+w), as well as SpecifiedLegalOrganization (w) and DefinedTradeContact (w)
|
||||
use dom4j to format output xml document
|
||||
@@ -9,6 +9,7 @@ corrected some exception logging glitches
|
||||
upgrade PDFBox to 2.0.15+
|
||||
extraction to use proper filename instead of alias #98
|
||||
NullPointerException in ZUGFeRDImporter.extractLowLevel #96
|
||||
Removed Bankleitzahl from ZF2
|
||||
|
||||
|
||||
1.7.1
|
||||
|
||||
8
pom.xml
8
pom.xml
@@ -1,10 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.mustangproject.ZUGFeRD</groupId>
|
||||
<artifactId>mustang</artifactId>
|
||||
<version>1.7.2-SNAPSHOT</version>
|
||||
<version>1.7.3-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
<name>Mustang</name>
|
||||
<description>The Mustang project is a java library to read and write ZUGFeRD meta data inside your invoice PDFs
|
||||
@@ -203,8 +202,7 @@
|
||||
<version>2.4.3</version>
|
||||
<configuration>
|
||||
<transformers>
|
||||
<transformer
|
||||
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
||||
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
||||
<mainClass>org.mustangproject.toecount.Toecount</mainClass>
|
||||
</transformer>
|
||||
</transformers>
|
||||
|
||||
@@ -412,8 +412,6 @@ public class ZUGFeRD2PullProvider implements IXMLProvider, IProfileProvider {
|
||||
+ " </ram:PayeePartyCreditorFinancialAccount>\n" //$NON-NLS-1$
|
||||
+ " <ram:PayeeSpecifiedCreditorFinancialInstitution>\n" //$NON-NLS-1$
|
||||
+ " <ram:BICID>" + payment.getOwnBIC() + "</ram:BICID>\n" //$NON-NLS-1$ //$NON-NLS-2$
|
||||
+ " <ram:GermanBankleitzahlID>" + payment.getOwnBLZ() //$NON-NLS-1$
|
||||
+ "</ram:GermanBankleitzahlID>\n" //$NON-NLS-1$
|
||||
// + " <ram:Name>"+trans.getOwnBankName()+"</ram:Name>\n" //$NON-NLS-1$
|
||||
// //$NON-NLS-2$
|
||||
+ " </ram:PayeeSpecifiedCreditorFinancialInstitution>\n" //$NON-NLS-1$
|
||||
|
||||
@@ -128,8 +128,9 @@ public class ZUGFeRDImporter {
|
||||
|
||||
private void extractFiles(Map<String, PDComplexFileSpecification> names) throws IOException {
|
||||
for (String alias : names.keySet()) {
|
||||
String filename=names.get(alias).getFilename();
|
||||
|
||||
PDComplexFileSpecification fileSpec = names.get(alias);
|
||||
String filename=fileSpec.getFilename();
|
||||
/**
|
||||
* currently (in the release candidate of version 1) only one attached file with
|
||||
* the name ZUGFeRD-invoice.xml is allowed
|
||||
@@ -137,7 +138,6 @@ public class ZUGFeRDImporter {
|
||||
if ((filename.equals("ZUGFeRD-invoice.xml") || (filename.equals("zugferd-invoice.xml")) || filename.equals("factur-x.xml"))) { //$NON-NLS-1$
|
||||
containsMeta = true;
|
||||
|
||||
PDComplexFileSpecification fileSpec = names.get(filename);
|
||||
PDEmbeddedFile embeddedFile = fileSpec.getEmbeddedFile();
|
||||
// String embeddedFilename = filePath + filename;
|
||||
// File file = new File(filePath + filename);
|
||||
@@ -154,7 +154,6 @@ public class ZUGFeRDImporter {
|
||||
}
|
||||
if (filename.startsWith("additional_data")) {
|
||||
|
||||
PDComplexFileSpecification fileSpec = names.get(filename);
|
||||
PDEmbeddedFile embeddedFile = fileSpec.getEmbeddedFile();
|
||||
additionalXMLs.put(filename, embeddedFile.toByteArray());
|
||||
|
||||
|
||||
134
src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDVisualizer.java
Normal file
134
src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDVisualizer.java
Normal file
@@ -0,0 +1,134 @@
|
||||
/** **********************************************************************
|
||||
*
|
||||
* Copyright 2018 Jochen Staerk
|
||||
*
|
||||
* Use is subject to license terms.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*********************************************************************** */
|
||||
package org.mustangproject.ZUGFeRD;
|
||||
|
||||
import javax.xml.transform.*;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
import javax.xml.transform.stream.StreamSource;
|
||||
import java.io.*;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class ZUGFeRDVisualizer {
|
||||
|
||||
static final ClassLoader CLASS_LOADER = ZUGFeRDVisualizer.class.getClassLoader();
|
||||
private static final String RESOURCE_PATH = ""; //$NON-NLS-1$
|
||||
private static final Logger LOG = Logger.getLogger(ZUGFeRDVisualizer.class.getName());
|
||||
// private static File createTempFileResult(final Transformer transformer, final StreamSource toTransform,
|
||||
// final String suffix) throws TransformerException, IOException {
|
||||
// File result = File.createTempFile("ZUV_", suffix); //$NON-NLS-1$
|
||||
// result.deleteOnExit();
|
||||
//
|
||||
// try (FileOutputStream fos = new FileOutputStream(result)) {
|
||||
// transformer.transform(toTransform, new StreamResult(fos));
|
||||
// }
|
||||
// return result;
|
||||
// }
|
||||
private TransformerFactory mFactory = null;
|
||||
private Templates mXsltXRTemplate = null;
|
||||
private Templates mXsltHTMLTemplate = null;
|
||||
|
||||
public ZUGFeRDVisualizer() {
|
||||
mFactory = new net.sf.saxon.TransformerFactoryImpl();
|
||||
//fact = TransformerFactory.newInstance();
|
||||
mFactory.setURIResolver(new ClasspathResourceURIResolver());
|
||||
try {
|
||||
mXsltXRTemplate = mFactory.newTemplates(new StreamSource(CLASS_LOADER.getResourceAsStream(RESOURCE_PATH + "stylesheets/cii-xr.xsl")));
|
||||
mXsltHTMLTemplate = mFactory.newTemplates(new StreamSource(CLASS_LOADER.getResourceAsStream(RESOURCE_PATH + "stylesheets/xrechnung-html.xsl")));
|
||||
} catch (TransformerConfigurationException ex) {
|
||||
LOG.log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
|
||||
public String visualize(String xmlFilename) throws FileNotFoundException, TransformerException, UnsupportedEncodingException {
|
||||
/**
|
||||
* *
|
||||
* http://www.unece.org/fileadmin/DAM/cefact/xml/XML-Naming-And-Design-Rules-V2_1.pdf
|
||||
* http://www.ferd-net.de/upload/Dokumente/FACTUR-X_ZUGFeRD_2p0_Teil1_Profil_EN16931_1p03.pdf
|
||||
* http://countwordsfree.com/xmlviewer
|
||||
*/
|
||||
ByteArrayOutputStream iaos = new ByteArrayOutputStream();
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
applySchematronXsl(new FileInputStream(xmlFilename), iaos);
|
||||
// take the copy of the stream and re-write it to an InputStream
|
||||
PipedInputStream in = new PipedInputStream();
|
||||
PipedOutputStream out;
|
||||
try {
|
||||
out = new PipedOutputStream(in);
|
||||
new Thread(new Runnable() {
|
||||
public void run () {
|
||||
try {
|
||||
// write the original OutputStream to the PipedOutputStream
|
||||
// note that in order for the below method to work, you need
|
||||
// to ensure that the data has finished writing to the
|
||||
// ByteArrayOutputStream
|
||||
iaos.writeTo(out);
|
||||
}
|
||||
catch (IOException e) {
|
||||
// logging and exception handling should go here
|
||||
}
|
||||
finally {
|
||||
// close the PipedOutputStream here because we're done writing data
|
||||
// once this thread has completed its run
|
||||
if (out != null) {
|
||||
// close the PipedOutputStream cleanly
|
||||
try {
|
||||
out.close();
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
applySchematronXsl2(in, baos);
|
||||
} catch (IOException e1) {
|
||||
// TODO Auto-generated catch block
|
||||
e1.printStackTrace();
|
||||
}
|
||||
|
||||
return baos.toString("UTF-8");
|
||||
}
|
||||
|
||||
public void applySchematronXsl(final InputStream xmlFile,
|
||||
final OutputStream HTMLOutstream) throws TransformerException {
|
||||
Transformer transformer = mXsltXRTemplate.newTransformer();
|
||||
|
||||
transformer.transform(new StreamSource(xmlFile), new StreamResult(HTMLOutstream));
|
||||
}
|
||||
|
||||
public void applySchematronXsl2(final InputStream xmlFile,
|
||||
final OutputStream HTMLOutstream) throws TransformerException {
|
||||
Transformer transformer = mXsltHTMLTemplate.newTransformer();
|
||||
|
||||
transformer.transform(new StreamSource(xmlFile), new StreamResult(HTMLOutstream));
|
||||
}
|
||||
|
||||
private static class ClasspathResourceURIResolver implements URIResolver {
|
||||
ClasspathResourceURIResolver() {
|
||||
// Do nothing, just prevents synthetic access warning.
|
||||
}
|
||||
|
||||
@Override
|
||||
public Source resolve(String href, String base) throws TransformerException {
|
||||
return new StreamSource(CLASS_LOADER.getResourceAsStream(RESOURCE_PATH + href));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -106,8 +106,7 @@ public class Toecount {
|
||||
+ "\t\t[--source-xml <filename>]: set input XML file\r\n"
|
||||
+ "\t\t[--out <filename>]: set output PDF file\r\n"
|
||||
+ "\t\t[--format <fx|zf>]: enable factur-x or ZUGFeRD\r\n"
|
||||
+ "\t\t[--version <1|2>]: set ZUGFeRD version\r\n"
|
||||
+ "\t\t[--profile <...>]: set ZUGFeRD profile\r\n"
|
||||
+ "\t\t[--version <1|2>]: set ZUGFeRD version\r\n" + "\t\t[--profile <...>]: set ZUGFeRD profile\r\n"
|
||||
+ "\t\t\tFor ZUGFeRD v1: <B>ASIC, <C>OMFORT or <E>XTENDED\r\n"
|
||||
+ "\t\t\tFor ZUGFeRD v2: <M>INIMUM, BASIC <W>L, <B>ASIC, <C>IUS, <E>N16931, E<X>TENDED\r\n");
|
||||
}
|
||||
@@ -116,11 +115,15 @@ public class Toecount {
|
||||
* Asks the user (repeatedly, if neccessary) on the command line for a String
|
||||
* (offering a defaultValue) conforming to a Regex pattern
|
||||
*
|
||||
* @param prompt the question to be asked to the user
|
||||
* @param defaultValue the default return value if user hits enter
|
||||
* @param pattern a regex of acceptable values
|
||||
* @param prompt
|
||||
* the question to be asked to the user
|
||||
* @param defaultValue
|
||||
* the default return value if user hits enter
|
||||
* @param pattern
|
||||
* a regex of acceptable values
|
||||
* @return the user answer conforming to pattern
|
||||
* @throws Exception if pattern not compielable or IOexception on input
|
||||
* @throws Exception
|
||||
* if pattern not compielable or IOexception on input
|
||||
*/
|
||||
protected static String getStringFromUser(String prompt, String defaultValue, String pattern) throws Exception {
|
||||
String input = "";
|
||||
@@ -159,11 +162,16 @@ public class Toecount {
|
||||
/**
|
||||
* Prompts the user for a input or output filename
|
||||
*
|
||||
* @param the text the user is asked
|
||||
* @param a default Filename
|
||||
* @param expectedExtension will warn if filename does not match expected file extension
|
||||
* @param ensureFileExists will warn if file does NOT exist (for input files)
|
||||
* @param ensureFileNotExists will warn if file DOES exist (for output files)
|
||||
* @param the
|
||||
* text the user is asked
|
||||
* @param a
|
||||
* default Filename
|
||||
* @param expectedExtension
|
||||
* will warn if filename does not match expected file extension
|
||||
* @param ensureFileExists
|
||||
* will warn if file does NOT exist (for input files)
|
||||
* @param ensureFileNotExists
|
||||
* will warn if file DOES exist (for output files)
|
||||
* @return String
|
||||
*/
|
||||
protected static String getFilenameFromUser(String prompt, String defaultFilename, String expectedExtension,
|
||||
@@ -324,6 +332,8 @@ public class Toecount {
|
||||
performConvert(sourceName, outName);
|
||||
} else if (upgradeRequested) {
|
||||
performUpgrade(sourceName, outName);
|
||||
} else if (action.equals("visualize")) {
|
||||
performVisualization(sourceName, outName);
|
||||
} else {
|
||||
// no argument or argument unknown
|
||||
printUsage();
|
||||
@@ -337,6 +347,47 @@ public class Toecount {
|
||||
|
||||
}
|
||||
|
||||
private static void performVisualization(String sourceName, String outName) {
|
||||
// Get params from user if not already defined
|
||||
if (sourceName == null) {
|
||||
sourceName = getFilenameFromUser("ZUGFeRD XML source", "zugferd-invoice.xml", "xml", true, false);
|
||||
} else {
|
||||
System.out.println("ZUGFeRD XML source set to " + sourceName);
|
||||
}
|
||||
if (outName == null) {
|
||||
outName = getFilenameFromUser("ZUGFeRD 2.0 XML target", "factur-x.html", "html", false, true);
|
||||
} else {
|
||||
System.out.println("ZUGFeRD 1.0 XML source set to " + outName);
|
||||
}
|
||||
|
||||
// Verify params
|
||||
try {
|
||||
ensureFileExists(sourceName);
|
||||
ensureFileNotExists(outName);
|
||||
|
||||
// stylesheets/ZUGFeRD_1p0_c1p0_s1p0.xslt
|
||||
} catch (IOException e) {
|
||||
Logger.getLogger(Toecount.class.getName()).log(Level.SEVERE, null, e);
|
||||
}
|
||||
|
||||
ZUGFeRDVisualizer zvi = new ZUGFeRDVisualizer();
|
||||
String xml = null;
|
||||
try {
|
||||
xml = zvi.visualize(sourceName);
|
||||
Files.write(Paths.get(outName), xml.getBytes());
|
||||
} catch (FileNotFoundException e) {
|
||||
Logger.getLogger(Toecount.class.getName()).log(Level.SEVERE, null, e);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
Logger.getLogger(Toecount.class.getName()).log(Level.SEVERE, null, e);
|
||||
} catch (TransformerException e) {
|
||||
Logger.getLogger(Toecount.class.getName()).log(Level.SEVERE, null, e);
|
||||
} catch (IOException e) {
|
||||
Logger.getLogger(Toecount.class.getName()).log(Level.SEVERE, null, e);
|
||||
}
|
||||
System.out.println("Written to " + outName);
|
||||
|
||||
}
|
||||
|
||||
private static void performUpgrade(String xmlName, String outName) throws IOException, TransformerException {
|
||||
|
||||
// Get params from user if not already defined
|
||||
@@ -464,7 +515,6 @@ public class Toecount {
|
||||
System.out.println("Format set to " + format);
|
||||
}
|
||||
|
||||
|
||||
if (zfVersion == null) {
|
||||
try {
|
||||
zfVersion = getStringFromUser("Version (1 or 2)", "1", "1|2");
|
||||
@@ -478,13 +528,12 @@ public class Toecount {
|
||||
|
||||
if (zfProfile == null) {
|
||||
try {
|
||||
if (format.equals("zf")&&(zfIntVersion == 1)) {
|
||||
zfProfile = getStringFromUser("Profile b)asic, c)omfort or e)xtended", "e",
|
||||
"B|b|C|c|E|e");
|
||||
if (format.equals("zf") && (zfIntVersion == 1)) {
|
||||
zfProfile = getStringFromUser("Profile b)asic, c)omfort or e)xtended", "e", "B|b|C|c|E|e");
|
||||
} else {
|
||||
zfProfile = getStringFromUser(
|
||||
"Profile [M]INIMUM, BASIC [W]L, [B]ASIC,\n" + "[C]IUS, [E]N16931, E[X]TENDED",
|
||||
"E", "M|m|W|w|B|b|C|c|E|e|X|x|");
|
||||
"Profile [M]INIMUM, BASIC [W]L, [B]ASIC,\n" + "[C]IUS, [E]N16931, E[X]TENDED", "E",
|
||||
"M|m|W|w|B|b|C|c|E|e|X|x|");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Logger.getLogger(Toecount.class.getName()).log(Level.SEVERE, null, e);
|
||||
@@ -500,11 +549,11 @@ public class Toecount {
|
||||
ensureFileExists(xmlName);
|
||||
ensureFileNotExists(outName);
|
||||
|
||||
if ((format.equals("fx"))&&(zfIntVersion>1)) {
|
||||
if ((format.equals("fx")) && (zfIntVersion > 1)) {
|
||||
throw new Exception("Factur-X is only available in version 1 (roughly corresponding to ZF2)");
|
||||
}
|
||||
|
||||
if ((format.equals("zf"))&&(zfIntVersion == 1)) {
|
||||
if ((format.equals("zf")) && (zfIntVersion == 1)) {
|
||||
if (zfProfile.equals("b")) {
|
||||
zfConformanceLevelProfile = ZUGFeRDConformanceLevel.BASIC;
|
||||
} else if (zfProfile.equals("c")) {
|
||||
@@ -514,7 +563,7 @@ public class Toecount {
|
||||
} else {
|
||||
throw new Exception(String.format("Unknown ZUGFeRD profile '%s'", zfProfile));
|
||||
}
|
||||
} else if (((format.equals("zf"))&&(zfIntVersion == 2))||(format.equals("fx"))) {
|
||||
} else if (((format.equals("zf")) && (zfIntVersion == 2)) || (format.equals("fx"))) {
|
||||
if (zfProfile.equals("m")) {
|
||||
zfConformanceLevelProfile = ZUGFeRDConformanceLevel.MINIMUM;
|
||||
} else if (zfProfile.equals("w")) {
|
||||
@@ -544,7 +593,6 @@ public class Toecount {
|
||||
ze.setFacturX();
|
||||
}
|
||||
|
||||
|
||||
ze.setZUGFeRDXMLData(Files.readAllBytes(Paths.get(xmlName)));
|
||||
|
||||
ze.export(outName);
|
||||
|
||||
2202
src/main/resources/stylesheets/cii-xr.xsl
Normal file
2202
src/main/resources/stylesheets/cii-xr.xsl
Normal file
File diff suppressed because it is too large
Load Diff
1188
src/main/resources/stylesheets/xrechnung-html.xsl
Normal file
1188
src/main/resources/stylesheets/xrechnung-html.xsl
Normal file
File diff suppressed because it is too large
Load Diff
917
xrechnung-viewer.css
Normal file
917
xrechnung-viewer.css
Normal file
@@ -0,0 +1,917 @@
|
||||
/* Grundformatierung ********************************************/
|
||||
|
||||
*,
|
||||
*:after,
|
||||
*:before
|
||||
{
|
||||
box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
}
|
||||
|
||||
.clear:after
|
||||
{
|
||||
content: ".";
|
||||
clear: both;
|
||||
display: block;
|
||||
visibility: hidden;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
html,
|
||||
body
|
||||
{
|
||||
height: 100%;
|
||||
min-width: 320px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
color: #000;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
body
|
||||
{
|
||||
overflow-y: scroll;
|
||||
background-color: rgba(4, 101, 161, 0.08);
|
||||
}
|
||||
|
||||
h4
|
||||
{
|
||||
color: inherit;
|
||||
font-size: inherit;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
|
||||
/* Grundaufbau *************************************************/
|
||||
|
||||
.menue
|
||||
{
|
||||
position: relative;
|
||||
z-index: 2000;
|
||||
background-color: #000;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.innen
|
||||
{
|
||||
max-width: 1080px;
|
||||
margin: 0 auto;
|
||||
padding: 0 2%;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Formatierungen *************************************************/
|
||||
|
||||
.color2
|
||||
{
|
||||
color: rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
|
||||
.schwarz
|
||||
{
|
||||
color: #555 !important;
|
||||
}
|
||||
|
||||
.normal
|
||||
{
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.bold
|
||||
{
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.abstandUnten
|
||||
{
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.abstandUntenKlein
|
||||
{
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.noPaddingTop
|
||||
{
|
||||
padding-top: 0 !important;
|
||||
}
|
||||
|
||||
.ausrichtungRechts
|
||||
{
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Menü ********************************************************/
|
||||
|
||||
button
|
||||
{
|
||||
position: relative;
|
||||
font-family: serif;
|
||||
padding-top: 15px;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
margin-right: 2%;
|
||||
}
|
||||
|
||||
.btnAktiv
|
||||
{
|
||||
font-size: 22px;
|
||||
color: #ffb619;
|
||||
height: 50px;
|
||||
outline: none;
|
||||
border: none;
|
||||
background: none;
|
||||
}
|
||||
|
||||
.btnAktiv:after
|
||||
{
|
||||
content: "";
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 50px;
|
||||
left: 50%;
|
||||
z-index: 10;
|
||||
font-size: 0;
|
||||
line-height: 0;
|
||||
height: 0;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
transform: translateX(-50%);
|
||||
border: 15px solid #000;
|
||||
border-right-color: transparent;
|
||||
border-bottom-color: transparent;
|
||||
border-left-color: transparent;
|
||||
}
|
||||
|
||||
.btnInaktiv,
|
||||
.tab
|
||||
{
|
||||
font-size: 22px;
|
||||
color: #fff;
|
||||
height: 50px;
|
||||
z-index: 0;
|
||||
outline: none;
|
||||
border: none;
|
||||
background: none;
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
|
||||
.btnInaktiv:hover,
|
||||
.tab:hover
|
||||
{
|
||||
color: #ffb619;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.divHide
|
||||
{
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Content *********************************************************************/
|
||||
|
||||
.inhalt
|
||||
{
|
||||
font-family: sans-serif;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.haftungausschluss
|
||||
{
|
||||
color: #000;
|
||||
text-align: center;
|
||||
padding: 7px;
|
||||
margin-bottom: 30px;
|
||||
width: 100%;
|
||||
border: 1px solid #ffb619;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.box
|
||||
{
|
||||
position: relative;
|
||||
display: table-cell;
|
||||
padding: 0;
|
||||
border: 1px solid rgba(4, 101, 161, 0.2);
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.subBox
|
||||
{
|
||||
border-top: none;
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.subBox:last-child
|
||||
{
|
||||
border-left: none;
|
||||
}
|
||||
|
||||
.first > .boxzeile > .subBox
|
||||
{
|
||||
border-top: 1px solid rgba(4, 101, 161, 0.2) !important;
|
||||
}
|
||||
|
||||
.boxtitel
|
||||
{
|
||||
display: inline-block;
|
||||
background-color: #0465A1;
|
||||
padding: 7px 10px;
|
||||
color: #fff;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.boxBorderTop
|
||||
{
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
.boxBorderLeft
|
||||
{
|
||||
border-left: none;
|
||||
}
|
||||
|
||||
.boxtitelSub
|
||||
{
|
||||
color: #000;
|
||||
background-color: rgba(4, 101, 161, 0.1);
|
||||
border-right: 1px solid rgba(4, 101, 161, 0.2);
|
||||
border-bottom: 1px solid rgba(4, 101, 161, 0.2);
|
||||
}
|
||||
|
||||
.boxinhalt
|
||||
{
|
||||
padding: 15px 20px;
|
||||
}
|
||||
|
||||
.boxtabelle
|
||||
{
|
||||
display: table;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.borderSpacing
|
||||
{
|
||||
border-spacing: 0 5px;
|
||||
}
|
||||
|
||||
.boxabstandtop
|
||||
{
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.boxzeile
|
||||
{
|
||||
display: table-row;
|
||||
}
|
||||
|
||||
.boxzeile .box:last-child
|
||||
{
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.boxdaten
|
||||
{
|
||||
display: table-cell;
|
||||
padding: 5px 0;
|
||||
vertical-align: middle;
|
||||
height: 38px;
|
||||
/*
|
||||
-ms-word-break: break-all;
|
||||
word-break: break-all;
|
||||
word-break: break-word;
|
||||
-webkit-hyphens: auto;
|
||||
-moz-hyphens: auto;
|
||||
hyphens: auto;
|
||||
*/
|
||||
}
|
||||
|
||||
.boxdaten.wert
|
||||
{
|
||||
padding: 5px 10px;
|
||||
}
|
||||
|
||||
.boxcell
|
||||
{
|
||||
display: table-cell;
|
||||
}
|
||||
|
||||
.boxdatenBlock
|
||||
{
|
||||
display: block;
|
||||
padding: 3px 0;
|
||||
/*
|
||||
-ms-word-break: break-all;
|
||||
word-break: break-all;
|
||||
word-break: break-word;
|
||||
-webkit-hyphens: auto;
|
||||
-moz-hyphens: auto;
|
||||
hyphens: auto;
|
||||
*/
|
||||
}
|
||||
|
||||
.noBreak
|
||||
{
|
||||
-ms-word-break: keep-all;
|
||||
word-break: keep-all;
|
||||
word-break: keep-all;
|
||||
-webkit-hyphens: none;
|
||||
-moz-hyphens: none;
|
||||
hyphens: none;
|
||||
}
|
||||
|
||||
.boxabstand
|
||||
{
|
||||
display: table-cell;
|
||||
width: 30px;
|
||||
}
|
||||
|
||||
.legende
|
||||
{
|
||||
color: rgba(0, 0, 0, 0.6);
|
||||
width: 170px;
|
||||
font-size: 13px;
|
||||
line-height: 16px;
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
.wert
|
||||
{
|
||||
background-color: rgba(4, 101, 161, 0.03);
|
||||
}
|
||||
|
||||
.boxtabelleEinspaltig
|
||||
{
|
||||
width: 49%;
|
||||
}
|
||||
|
||||
.boxtabelleZweispaltig,
|
||||
.boxtabelleDreispaltig
|
||||
{
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.box5050
|
||||
{
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.boxEinspaltig
|
||||
{
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.boxZweispaltig
|
||||
{
|
||||
width: 48.5%;
|
||||
}
|
||||
|
||||
.boxSpalte1 {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.boxSpalte2 {
|
||||
width: 50%;
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
.paddingLeft {
|
||||
padding-left: 0.1em;
|
||||
}
|
||||
|
||||
.noPadding {
|
||||
padding-top: 0 !important;
|
||||
padding-bottom: 0 !important;
|
||||
}
|
||||
|
||||
.rechnungsZeile
|
||||
{
|
||||
display: table-row;
|
||||
}
|
||||
|
||||
.rechnungsZeile .boxdaten
|
||||
{
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.rechnungSp1
|
||||
{
|
||||
width: 65%;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.rechnungSp2
|
||||
{
|
||||
width: 10%;
|
||||
}
|
||||
|
||||
.rechnungSp3
|
||||
{
|
||||
width: 25%;
|
||||
font-size: 16px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.detailSp1,
|
||||
.detailSp2
|
||||
{
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.detailSp2
|
||||
{
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.line1Bottom
|
||||
{
|
||||
border-bottom: 1px solid #000;
|
||||
}
|
||||
|
||||
.line1BottomLight
|
||||
{
|
||||
padding-bottom: 5px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.line2Bottom
|
||||
{
|
||||
border-bottom: 2px solid #000;
|
||||
}
|
||||
|
||||
.paddingTop
|
||||
{
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
.paddingBottom
|
||||
{
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
.grund
|
||||
{
|
||||
font-size: 16px;
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: 0 20px 15px 20px;
|
||||
}
|
||||
|
||||
.grundDetail
|
||||
{
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: 0 20px 15px 20px;
|
||||
}
|
||||
|
||||
/* Übersichtformatierungen */
|
||||
#uebersichtLastschrift.box,
|
||||
#uebersichtUeberweisung.box
|
||||
{
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
#uebersichtUeberweisung.box
|
||||
{
|
||||
border-left: none;
|
||||
}
|
||||
|
||||
|
||||
/* Formatierungen Detailseite */
|
||||
|
||||
.detailsSpalte1,
|
||||
.detailsSpalte2
|
||||
{
|
||||
width: 30%;
|
||||
float: left;
|
||||
font-size: 90%;
|
||||
line-height: 115%;
|
||||
margin-right: 5%;
|
||||
}
|
||||
|
||||
.detailsSpalte3
|
||||
{
|
||||
width: 30%;
|
||||
float: left;
|
||||
font-size: 90%;
|
||||
line-height: 115%;
|
||||
}
|
||||
|
||||
.detailsSpalte1 .legende,
|
||||
.detailsSpalte2 .legende,
|
||||
.detailsSpalte3 .legende
|
||||
{
|
||||
width: 145px;
|
||||
}
|
||||
|
||||
.titelPosition
|
||||
{
|
||||
font-size: 17px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
|
||||
/* Laufzettelformatierungen */
|
||||
#laufzettelHistorie .boxtabelle:not(:nth-child(2))
|
||||
{
|
||||
border-top: 1px solid rgba(4, 101, 161, 0.2);
|
||||
padding-top: 10px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* 1023px und kleiner ************************************************/
|
||||
|
||||
@media screen and (max-width : 1023px) {
|
||||
|
||||
.box
|
||||
{
|
||||
display: block;
|
||||
width: 100%;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.boxabstandtop
|
||||
{
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.subBox:first-child
|
||||
{
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
|
||||
.subBox:last-child
|
||||
{
|
||||
border-left: 1px solid rgba(4, 101, 161, 0.2);
|
||||
}
|
||||
|
||||
.first > .boxzeile > .subBox
|
||||
{
|
||||
border-top: none !important;
|
||||
}
|
||||
|
||||
.first > .boxzeile > .subBox:first-child
|
||||
{
|
||||
border-top: 1px solid rgba(4, 101, 161, 0.2) !important;
|
||||
}
|
||||
|
||||
.first > .boxzeile
|
||||
{
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
#uebersichtUeberweisung.box
|
||||
{
|
||||
border-left: 1px solid rgba(4, 101, 161, 0.2);
|
||||
}
|
||||
|
||||
#uebersichtLastschrift.box
|
||||
{
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.boxzeile
|
||||
{
|
||||
display: block;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.boxzeile:after
|
||||
{
|
||||
visibility: hidden;
|
||||
display: block;
|
||||
font-size: 0;
|
||||
content: " ";
|
||||
clear: both;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
#details > .boxtabelle > .boxzeile
|
||||
{
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
.boxcell
|
||||
{
|
||||
display: block;
|
||||
}
|
||||
|
||||
.boxcell:last-child
|
||||
{
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.boxZweispaltig
|
||||
{
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.legende
|
||||
{
|
||||
display: block;
|
||||
float: left;
|
||||
width: 170px;
|
||||
padding: 5px 0;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.wert
|
||||
{
|
||||
display: block;
|
||||
float: left;
|
||||
width: calc(100% - 170px);
|
||||
padding: 11px 10px !important;
|
||||
line-height: 1.3;
|
||||
min-height: 38px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.boxdaten .legende
|
||||
{
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.rechnungsZeile .boxdaten
|
||||
{
|
||||
padding: 5px 0;
|
||||
}
|
||||
|
||||
.boxabstand
|
||||
{
|
||||
display: none;
|
||||
}
|
||||
|
||||
.boxtabelleEinspaltig {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.boxSpalte1 {
|
||||
display: block;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.boxSpalte2 {
|
||||
display: block;
|
||||
width: auto;
|
||||
padding-left: 0px;
|
||||
margin-top: 1.2rem;
|
||||
}
|
||||
|
||||
.detailsSpalte1,
|
||||
.detailsSpalte2,
|
||||
.detailsSpalte3
|
||||
{
|
||||
width: 100%;
|
||||
float: none;
|
||||
padding-right: 0px;
|
||||
}
|
||||
|
||||
.detailsSpalte2,
|
||||
.detailsSpalte3
|
||||
{
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.detailsSpalte2,
|
||||
.detailsSpalte3
|
||||
{
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.tableNumberAlignRight
|
||||
{
|
||||
display: block;
|
||||
width: 130px;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* 800px und kleiner ************************************************/
|
||||
|
||||
@media screen and (max-width : 800px) {
|
||||
|
||||
button
|
||||
{
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
.btnAktiv,
|
||||
.btnInaktiv,
|
||||
.tab
|
||||
{
|
||||
font-size: 20px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.btnAktiv:after
|
||||
{
|
||||
top: 40px;
|
||||
}
|
||||
|
||||
.rechnungSp1
|
||||
{
|
||||
width: 55%;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.rechnungSp2
|
||||
{
|
||||
width: 10%;
|
||||
}
|
||||
|
||||
.rechnungSp3
|
||||
{
|
||||
width: 35%;
|
||||
text-align: right;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.grund
|
||||
{
|
||||
font-size: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 450px und kleiner ************************************************/
|
||||
|
||||
@media screen and (max-width : 450px)
|
||||
{
|
||||
|
||||
html,
|
||||
body
|
||||
{
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.menue
|
||||
{
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
button
|
||||
{
|
||||
padding-top: 5px;
|
||||
}
|
||||
|
||||
.btnAktiv,
|
||||
.btnInaktiv,
|
||||
.tab
|
||||
{
|
||||
font-size: 17px;
|
||||
height: 35px;
|
||||
}
|
||||
|
||||
.btnAktiv:after
|
||||
{
|
||||
top: 35px;
|
||||
}
|
||||
|
||||
.legende
|
||||
{
|
||||
font-size: 12px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.wert
|
||||
{
|
||||
font-size: 12px;
|
||||
line-height: 1.3;
|
||||
width: 100%;
|
||||
margin-bottom: 10px
|
||||
}
|
||||
|
||||
.boxzeile
|
||||
{
|
||||
margin-bottom: 0px
|
||||
}
|
||||
|
||||
.boxdaten
|
||||
{
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.haftungausschluss
|
||||
{
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.boxinhalt
|
||||
{
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
.boxabstandtop
|
||||
{
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.boxtitel
|
||||
{
|
||||
padding: 7px 8px;
|
||||
}
|
||||
|
||||
.box
|
||||
{
|
||||
margin-bottom: 10px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.boxabstandtop
|
||||
{
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.boxdaten,
|
||||
.boxdatenBlock
|
||||
{
|
||||
padding: 2px 0;
|
||||
}
|
||||
|
||||
.rechnungSp1
|
||||
{
|
||||
width: 50%;
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
.rechnungSp2
|
||||
{
|
||||
width: 15%;
|
||||
}
|
||||
|
||||
.rechnungSp3
|
||||
{
|
||||
width: 35%;
|
||||
font-size: inherit;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.grund
|
||||
{
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
.titelPosition
|
||||
{
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.abstandUnten
|
||||
{
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.detailsSpalte1,
|
||||
.detailsSpalte2,
|
||||
.detailsSpalte3
|
||||
{
|
||||
font-size: inherit;
|
||||
line-height: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
/* 380px und kleiner ************************************************/
|
||||
|
||||
@media screen and (max-width : 380px) {
|
||||
|
||||
html,
|
||||
body
|
||||
{
|
||||
font-size: 11px;
|
||||
line-height: 100%;
|
||||
}
|
||||
|
||||
.btnAktiv,
|
||||
.btnInaktiv,
|
||||
.tab
|
||||
{
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.boxdaten
|
||||
.boxdatenBlock
|
||||
{
|
||||
padding: 2px 0;
|
||||
}
|
||||
|
||||
.boxinhalt
|
||||
{
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
.boxtitel
|
||||
{
|
||||
padding: 5px 7px;
|
||||
}
|
||||
}
|
||||
145
xrechnung-viewer.js
Normal file
145
xrechnung-viewer.js
Normal file
@@ -0,0 +1,145 @@
|
||||
|
||||
/* Tab-Container aufbauen **************************************************/
|
||||
|
||||
var a = new Array("uebersicht", "details", "zusaetze", "anlagen", "laufzettel");
|
||||
var b = new Array("menueUebersicht", "menueDetails", "menueZusaetze", "menueAnlagen", "menueLaufzettel");
|
||||
|
||||
function show(e) {
|
||||
var i = 0;
|
||||
var j = 1;
|
||||
for (var t = 0; t < b.length; t++) {
|
||||
if (b[t] === e.id) {
|
||||
i = t;
|
||||
if (i > 0) {
|
||||
j = 0;
|
||||
} else {
|
||||
j = i + 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
e.setAttribute("class", "btnAktiv");
|
||||
for (var k = 0; k < b.length; k++) {
|
||||
if (k === i && (document.getElementById(a[k]) != null)) {
|
||||
document.getElementById(a[k]).style.display = "block";
|
||||
if (i === j)
|
||||
j = i + 1;
|
||||
} else {
|
||||
if (document.getElementById(a[k]) != null) {
|
||||
document.getElementById(a[j]).style.display = "none";
|
||||
document.getElementById(b[j]).setAttribute("class", "btnInaktiv");
|
||||
j += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
window.onload = function () {
|
||||
document.getElementById(b[0]).setAttribute("class", "btnAktiv");
|
||||
}
|
||||
|
||||
/* Eingebettete Binaerdaten runterladen ************************************/
|
||||
|
||||
|
||||
function base64_to_binary (data) {
|
||||
var chars = atob(data);
|
||||
var bytes = new Array(chars.length);
|
||||
for (var i = 0; i < chars.length; i++) {
|
||||
bytes[i] = chars.charCodeAt(i);
|
||||
}
|
||||
return new Uint8Array(bytes);
|
||||
}
|
||||
|
||||
function downloadData (element_id) {
|
||||
var data_element = document.getElementById(element_id);
|
||||
var mimetype = data_element.getAttribute('mimeType');
|
||||
var filename = data_element.getAttribute('filename');
|
||||
var text = data_element.innerHTML;
|
||||
var binary = base64_to_binary(text);
|
||||
var blob = new Blob([binary], {
|
||||
type: mimetype, size: binary.length
|
||||
});
|
||||
|
||||
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
|
||||
// IE
|
||||
window.navigator.msSaveOrOpenBlob(blob, filename);
|
||||
} else {
|
||||
// Non-IE
|
||||
var url = window.URL.createObjectURL(blob);
|
||||
window.open(url);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Polyfill IE atob/btoa ************************************/
|
||||
|
||||
(function (root, factory) {
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// AMD. Register as an anonymous module.
|
||||
define([], function () {
|
||||
factory(root);
|
||||
});
|
||||
} else factory(root);
|
||||
// node.js has always supported base64 conversions, while browsers that support
|
||||
// web workers support base64 too, but you may never know.
|
||||
})(typeof exports !== "undefined" ? exports: this, function (root) {
|
||||
if (root.atob) {
|
||||
// Some browsers' implementation of atob doesn't support whitespaces
|
||||
// in the encoded string (notably, IE). This wraps the native atob
|
||||
// in a function that strips the whitespaces.
|
||||
// The original function can be retrieved in atob.original
|
||||
try {
|
||||
root.atob(" ");
|
||||
}
|
||||
catch (e) {
|
||||
root.atob = (function (atob) {
|
||||
var func = function (string) {
|
||||
return atob(String(string).replace(/[\t\n\f\r ]+/g, ""));
|
||||
};
|
||||
func.original = atob;
|
||||
return func;
|
||||
})(root.atob);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// base64 character set, plus padding character (=)
|
||||
var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
|
||||
// Regular expression to check formal correctness of base64 encoded strings
|
||||
b64re = /^(?:[A-Za-z\d+\/]{4})*?(?:[A-Za-z\d+\/]{2}(?:==)?|[A-Za-z\d+\/]{3}=?)?$/;
|
||||
|
||||
root.btoa = function (string) {
|
||||
string = String(string);
|
||||
var bitmap, a, b, c,
|
||||
result = "", i = 0,
|
||||
rest = string.length % 3; // To determine the final padding
|
||||
|
||||
for (; i < string.length;) {
|
||||
if ((a = string.charCodeAt(i++)) > 255 || (b = string.charCodeAt(i++)) > 255 || (c = string.charCodeAt(i++)) > 255)
|
||||
throw new TypeError("Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.");
|
||||
|
||||
bitmap = (a << 16) | (b << 8) | c;
|
||||
result += b64.charAt(bitmap >> 18 & 63) + b64.charAt(bitmap >> 12 & 63) + b64.charAt(bitmap >> 6 & 63) + b64.charAt(bitmap & 63);
|
||||
}
|
||||
|
||||
// If there's need of padding, replace the last 'A's with equal signs
|
||||
return rest ? result.slice(0, rest - 3) + "===".substring(rest): result;
|
||||
};
|
||||
|
||||
root.atob = function (string) {
|
||||
// atob can work with strings with whitespaces, even inside the encoded part,
|
||||
// but only \t, \n, \f, \r and ' ', which can be stripped.
|
||||
string = String(string).replace(/[\t\n\f\r ]+/g, "");
|
||||
if (! b64re.test(string))
|
||||
throw new TypeError("Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.");
|
||||
|
||||
// Adding the padding if missing, for semplicity
|
||||
string += "==".slice(2 - (string.length & 3));
|
||||
var bitmap, result = "", r1, r2, i = 0;
|
||||
for (; i < string.length;) {
|
||||
bitmap = b64.indexOf(string.charAt(i++)) << 18 | b64.indexOf(string.charAt(i++)) << 12 | (r1 = b64.indexOf(string.charAt(i++))) << 6 | (r2 = b64.indexOf(string.charAt(i++)));
|
||||
|
||||
result += r1 === 64 ? String.fromCharCode(bitmap >> 16 & 255): r2 === 64 ? String.fromCharCode(bitmap >> 16 & 255, bitmap >> 8 & 255): String.fromCharCode(bitmap >> 16 & 255, bitmap >> 8 & 255, bitmap & 255);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
});
|
||||
Reference in New Issue
Block a user