@syncfusion/ej2-pdf
Version:
Feature-rich JavaScript PDF library with built-in support for loading and manipulating PDF document.
374 lines (373 loc) • 14.8 kB
JavaScript
import { _XmlWriter } from '../import-export/xml-writer';
import { _PdfStream } from '../../core/base-stream';
import { PdfBasicSchema } from './pdf-basic-schema';
import { PdfDublinCoreSchema } from './pdf-dublin-core-schema';
import { PdfSchema } from './pdf-schema';
import { PdfPagedTextSchema } from './pdf-paged-text-schema';
import { PdfBasicJobTicketSchema } from './pdf-basic-job-ticket-schema';
import { PdfRightsManagementSchema } from './pdf-rights-management-schema';
import { PdfCustomSchema } from './pdf-custom-schema';
import { _bytesToString, _stringToBytes } from '../utils';
/**
* Represents the container for all XMP metadata in a PDF document.
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data, password);
* // Create XMP metadata
* let documentProperties: PdfDocumentInformation = document.getDocumentInformation(false);
* // Gets XMP metadata
* let xmp: PdfXmpMetadata = documentProperties.xmpMetadata;
* // Sets basic schema properties
* xmp.basicSchema.creatorTool = 'MyApp 1.0';
* xmp.basicSchema.createDate = new Date();
* // Sets Dublin Core properties
* xmp.dublinCoreSchema.title = {'en-US': 'My Document'};
* xmp.dublinCoreSchema.creator = ['John Doe'];
* // Save the document
* document.save('output.pdf');
* // Destroy the document
* document.destroy();
* ```
*/
var PdfXmpMetadata = /** @class */ (function () {
/**
* Initializes a new `PdfXmpMetadata` instance.
*
* @private
*/
function PdfXmpMetadata() {
/**
* Custom schemas instance on the XMP metadata.
*
* @private
*/
this._customSchemas = [];
/**
* Internal flag checks the metadata is updated or not.
*
* @private
*/
this._isUpdated = false;
this._namespaceRegistry = new Set();
}
Object.defineProperty(PdfXmpMetadata.prototype, "dublinCoreSchema", {
/**
* Gets or creates the Dublin Core metadata schema.
*
* @public
* @returns {PdfDublinCoreSchema} The Dublin Core schema.
*
* ```typescript
// Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data, password);
* // Access the document properties
* let documentProperties: PdfDocumentInformation = document.getDocumentInformation(false);
* // Gets the xmp metadata
* let xmp = documentProperties.xmpMetadata;
* // Access Dublin Core schema
* xmp.dublinCoreSchema.creator = ['John Doe'];
* ```
*/
get: function () {
if (!this._dublinCoreSchema) {
this._dublinCoreSchema = new PdfDublinCoreSchema(this);
}
return this._dublinCoreSchema;
},
enumerable: true,
configurable: true
});
Object.defineProperty(PdfXmpMetadata.prototype, "basicSchema", {
/**
* Gets or creates the Basic XMP schema.
*
* @public
* @returns {PdfBasicSchema} The Basic schema.
*
* ```typescript
// Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data, password);
* // Access the document properties
* let documentProperties: PdfDocumentInformation = document.getDocumentInformation(false);
* // Gets the xmp metadata
* let xmp = documentProperties.xmpMetadata;
* // Access Basic schema
* xmp.basicSchema.creatorTool = 'MyApp 1.0';
* ```
*/
get: function () {
if (!this._basicSchema) {
this._basicSchema = new PdfBasicSchema(this);
}
return this._basicSchema;
},
enumerable: true,
configurable: true
});
Object.defineProperty(PdfXmpMetadata.prototype, "pdfSchema", {
/**
* Gets or creates the PDF-specific metadata schema.
*
* @public
* @returns {PdfSchema} The PDF schema.
*
* ```typescript
// Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data, password);
* // Access the document properties
* let documentProperties: PdfDocumentInformation = document.getDocumentInformation(false);
* // Gets the xmp metadata
* let xmp = documentProperties.xmpMetadata;
* // Access PDF schema
* xmp.pdfSchema.keywords = 'test, document';
* ```
*/
get: function () {
if (!this._pdfSchema) {
this._pdfSchema = new PdfSchema(this);
}
return this._pdfSchema;
},
enumerable: true,
configurable: true
});
Object.defineProperty(PdfXmpMetadata.prototype, "pagedTextSchema", {
/**
* Gets or creates the Paged-Text metadata schema.
*
* @public
* @returns {PdfPagedTextSchema} The Paged-Text schema.
*
* ```typescript
// Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data, password);
* // Access the document properties
* let documentProperties: PdfDocumentInformation = document.getDocumentInformation(false);
* // Gets the xmp metadata
* let xmp = documentProperties.xmpMetadata;
* // Access Paged-Text schema
* xmp.pagedTextSchema.pageCount = 10;
* ```
*/
get: function () {
if (!this._pagedTextSchema) {
this._pagedTextSchema = new PdfPagedTextSchema(this);
}
return this._pagedTextSchema;
},
enumerable: true,
configurable: true
});
Object.defineProperty(PdfXmpMetadata.prototype, "basicJobTicketSchema", {
/**
* Gets or creates the Basic Job Ticket schema.
*
* @public
* @returns {PdfBasicJobTicketSchema} The Basic Job Ticket schema.
*
* ```typescript
// Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data, password);
* // Access the document properties
* let documentProperties: PdfDocumentInformation = document.getDocumentInformation(false);
* // Gets the xmp metadata
* let xmp = documentProperties.xmpMetadata;
* // Access Basic Job Ticket schema
* xmp.basicJobTicketSchema.jobRef = ['Job001'];
* ```
*/
get: function () {
if (!this._basicJobTicketSchema) {
this._basicJobTicketSchema = new PdfBasicJobTicketSchema(this);
}
return this._basicJobTicketSchema;
},
enumerable: true,
configurable: true
});
Object.defineProperty(PdfXmpMetadata.prototype, "rightsManagementSchema", {
/**
* Gets or creates the Rights Management schema.
*
* @public
* @returns {PdfRightsManagementSchema} The Rights Management schema.
*
* ```typescript
* // Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data, password);
// Load an existing PDF document
* let document: PdfDocument = new PdfDocument(data, password);
* // Access the document properties
* let documentProperties: PdfDocumentInformation = document.getDocumentInformation(false);
* // Gets the xmp metadata
* let xmp = documentProperties.xmpMetadata;
* // Access Rights Management schema
* xmp.rightsManagementSchema.isMarked = true;
* ```
*/
get: function () {
if (!this._rightsManagementSchema) {
this._rightsManagementSchema = new PdfRightsManagementSchema(this);
}
return this._rightsManagementSchema;
},
enumerable: true,
configurable: true
});
Object.defineProperty(PdfXmpMetadata.prototype, "customSchema", {
/**
* Gets the internal custom schema.
*
* @private
* @returns {PdfCustomSchema} The internal custom schema.
*/
get: function () {
if (!this._customSchema) {
this._customSchema = new PdfCustomSchema(this, 'pdfx', 'http://ns.adobe.com/pdfx/1.3/');
}
return this._customSchema;
},
enumerable: true,
configurable: true
});
/**
* Builds the complete XMP packet as a byte array.
* Generates the XML structure with all active schemas and returns the serialized bytes.
*
* @private
* @returns {Uint8Array} The XMP packet bytes.
*/
PdfXmpMetadata.prototype._build = function () {
// Auto-fill createDate and modifyDate if not already set
var now = new Date();
if (!this._basicSchema || this._basicSchema._getProperty('xap:CreateDate') === undefined) {
this.basicSchema.createDate = now;
}
if (!this._basicSchema || this._basicSchema._getProperty('xap:ModifyDate') === undefined) {
this.basicSchema.modifyDate = now;
}
// Auto-fill format if not already set
if (!this._dublinCoreSchema || this._dublinCoreSchema._getProperty('dc:format') === undefined) {
this.dublinCoreSchema.format = 'application/pdf';
}
this._xmlWriter = new _XmlWriter();
this._namespaceRegistry.clear();
this._xmlWriter._writeStartElement('xmpmeta', 'x', 'adobe:ns:meta/');
this._xmlWriter._writeStartElement('RDF', 'rdf', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
this._writeSchemas(this._xmlWriter);
this._xmlWriter._writeEndElement();
this._xmlWriter._writeEndElement();
var xmlBytes = this._xmlWriter._save();
var xmlContent = _bytesToString(xmlBytes);
// Remove XML declaration if present (to add it at top)
xmlContent = xmlContent.replace(/^<\?xml\s+version\s*=\s*["']1\.0["']\s+encoding\s*=\s*["']utf-8["']\s*\?>/, '');
var xmlDeclaration = '<?xml version="1.0" encoding="utf-8"?>';
var prefix = '<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>';
var suffix = '<?xpacket end="r"?>';
var xmlString = xmlDeclaration +
prefix +
xmlContent +
suffix;
this._buffer = _stringToBytes(xmlString.replace(/(>)(<)(\/*)/g, '$1\n$2$3'));
return this._buffer;
};
/**
* Writes all active schemas to the XML writer.
* Iterates schemas in deterministic order and delegates to _writeSchema.
*
* @private
* @param {_XmlWriter} writer The XML writer instance.
* @returns {void}
*/
PdfXmpMetadata.prototype._writeSchemas = function (writer) {
var schemas = [];
if (this._basicSchema && this._basicSchema._properties.size > 0) {
schemas.push(this._basicSchema);
}
if (this._dublinCoreSchema && this._dublinCoreSchema._properties.size > 0) {
schemas.push(this._dublinCoreSchema);
}
if (this._pdfSchema && this._pdfSchema._properties.size > 0) {
schemas.push(this._pdfSchema);
}
if (this._pagedTextSchema && this._pagedTextSchema._properties.size > 0) {
schemas.push(this._pagedTextSchema);
}
if (this._basicJobTicketSchema && this._basicJobTicketSchema._properties.size > 0) {
schemas.push(this._basicJobTicketSchema);
}
if (this._rightsManagementSchema && this._rightsManagementSchema._properties.size > 0) {
schemas.push(this._rightsManagementSchema);
}
if (this._customSchemas && this._customSchemas.length > 0) {
for (var _i = 0, _a = this._customSchemas; _i < _a.length; _i++) {
var custom = _a[_i];
var customHasData = custom.customData instanceof Map // eslint-disable-line
? (custom.customData.size > 0) // eslint-disable-line
: (custom._properties && custom._properties.size > 0); // eslint-disable-line
if (customHasData) {
schemas.push(custom);
}
}
}
for (var _b = 0, schemas_1 = schemas; _b < schemas_1.length; _b++) {
var schema = schemas_1[_b];
this._writeSchema(writer, schema);
}
};
/**
* Writes a single schema's RDF Description block.
* Handles namespace registration and delegates property serialization to the schema.
*
* @private
* @param {_XmlWriter} writer The XML writer instance.
* @param {PdfXmpSchema} schema The schema to write.
* @returns {void}
*/
PdfXmpMetadata.prototype._writeSchema = function (writer, schema) {
writer._writeStartElement('Description', 'rdf', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
writer._writeAttributeString('about', '', 'rdf', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
var prefix = schema._prefix; // eslint-disable-line
var namespaceUri = schema._getNamespaceUri(); // eslint-disable-line
if (!this._namespaceRegistry.has(prefix)) {
writer._writeAttributeString(prefix, namespaceUri, 'xmlns', 'http://www.w3.org/2000/xmlns/');
this._namespaceRegistry.add(prefix);
}
schema._writeXml(writer); // eslint-disable-line
writer._writeEndElement();
};
/**
* Serializes the XMP metadata to a PDF stream object.
* Calls _build() and creates an uncompressed PdfStream with appropriate dictionary entries.
*
* @private
* @returns {void}
*/
PdfXmpMetadata.prototype._serializeToStream = function () {
var bytes = this._build();
this._xmpStream = new _PdfStream(bytes);
this.xmpStream = this._xmpStream.bytes;
};
/**
* Destroys the metadata object and releases all resources.
* Clears all schema references, registry, and buffers.
*
* @private
* @returns {void}
*/
PdfXmpMetadata.prototype._destroy = function () {
this._xmlWriter = undefined;
this._buffer = undefined;
this._namespaceRegistry.clear();
this._dublinCoreSchema = undefined;
this._basicSchema = undefined;
this._pdfSchema = undefined;
this._pagedTextSchema = undefined;
this._basicJobTicketSchema = undefined;
this._rightsManagementSchema = undefined;
this._customSchema = undefined;
this._xmpStream = undefined;
};
return PdfXmpMetadata;
}());
export { PdfXmpMetadata };