UNPKG

@aurigma/design-editor-iframe

Version:

Using this module you can embed Design Editor (a part of Customer's Canvas) to your page through the IFrame API.

995 lines 64 kB
var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; var __values = (this && this.__values) || function(o) { var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); }; import { EditorLoader } from "../EditorLoader"; import * as Convert from "./Convert"; import { ArgumentException } from "@aurigma/design-atoms-model/Exception"; import { Color } from "@aurigma/design-atoms-model/Colors/Color"; import { RotatedRectangleF } from "@aurigma/design-atoms-model/Math"; import { ProductParser, SerializationProvider } from "@aurigma/design-atoms/Serialization"; /** * Channel container types. * @public */ export var ChannelContainerType; (function (ChannelContainerType) { ChannelContainerType[ChannelContainerType["Texture"] = 0] = "Texture"; ChannelContainerType[ChannelContainerType["SpotColor"] = 1] = "SpotColor"; })(ChannelContainerType || (ChannelContainerType = {})); /** * PDF page boxes. * @public */ export var PdfBox; (function (PdfBox) { /** CropBox */ PdfBox["Crop"] = "Crop"; /** TrimBox */ PdfBox["Trim"] = "Trim"; /** BleedBox */ PdfBox["Bleed"] = "Bleed"; })(PdfBox || (PdfBox = {})); /** * Text alignment options. * @public */ export var CropMarkTextAlignment; (function (CropMarkTextAlignment) { CropMarkTextAlignment[CropMarkTextAlignment["Left"] = 0] = "Left"; CropMarkTextAlignment[CropMarkTextAlignment["Center"] = 1] = "Center"; CropMarkTextAlignment[CropMarkTextAlignment["Right"] = 2] = "Right"; })(CropMarkTextAlignment || (CropMarkTextAlignment = {})); //#endregion //Properties of this class and its are constant. /** * A basic component containing the name and ID of a component. * @public */ var ModelComponent = /** @class */ (function () { /** @internal */ function ModelComponent(rawComponent) { this.id = rawComponent["id"]; this.name = rawComponent["name"]; } return ModelComponent; }()); export { ModelComponent }; /** * A Customer's Canvas product. * @public */ var Product = /** @class */ (function (_super) { __extends(Product, _super); /** @internal */ function Product(rawProduct, _context) { var _this = _super.call(this, rawProduct) || this; _this._context = _context; _this.surfaces = rawProduct["surfaces"].map(function (rawSurface) { return new Surface(rawSurface, _this, _this._context); }); _this.currentSurface = _this.surfaces.filter(function (s) { return s.id === rawProduct["currentSurfaceId"]; })[0]; return _this; } /** * Swaps two surfaces (pages) in the product. * @param lhsSurface - The first surface (page) to swap. * @param rhsSurface - The second surface (page) to swap. * @returns The product instance where the surfaces (pages) were swapped. * @example * ``` js * let product = await editor.getProduct(); * * // Swap the first and last pages in the product. * product = await product.swapSurfaces(product.surfaces[0], product.surfaces[product.surfaces.length - 1]) * // If an error occurred while swapping pages in the product. * .catch(error => console.error("Swapping surfaces failed with exception: ", error)); * ``` */ Product.prototype.swapSurfaces = function (lhsSurface, rhsSurface) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this._context.client.callProcedure("swapSurfaces", lhsSurface.id, rhsSurface.id)]; case 1: _a.sent(); return [4 /*yield*/, this._context.editor.getProduct()]; case 2: return [2 /*return*/, _a.sent()]; } }); }); }; /** * Replaces a product. * @param surfaces - An array of the new surfaces. * @returns The product instance with the new surfaces. * @example * ``` js * let product = await editor.getProduct(); * * // Replace the product with two new pages. * product = await product.setSurfaces([ * { width: 300, height: 300 }, * { designFile: "postcard" } * ]) * // If an error occurred while replacing pages in the product. * .catch(error => console.error("Setting surfaces failed with exception: ", error)); * ``` */ Product.prototype.setSurfaces = function (surfaces) { var _this = this; var transferProductDef = Convert.fromSurfaces(surfaces); return EditorLoader .getInitData(this._context.editorUrl, transferProductDef, this._context.config) .then(function (serverConfig) { return JSON.parse(serverConfig)["product"]; }) .then(function (transferProduct) { return _this._context.client.callProcedure("setSurfaces", transferProduct); }) .then(function () { return _this._context.editor.getProduct(); }); }; /** * Adds a number of surfaces (pages) to the product. * @param surfaces - An array of surfaces (pages) to add. * @param position - A position in the surface array where new surfaces should be added. The index of the first surface is `0`. By default, this method adds pages to the end of the surface array. * @returns The product instance where the surfaces (pages) were added. * @example * ``` js * let product = await editor.getProduct(); * * // Add an empty page and the "postcard" template to the beginning. * product = await product.addSurfaces( * [{ width: 300, height: 300 }, { designFile: "postcard" }], * 0 * ) * // If an error occurred while adding pages to the product. * .catch(error => console.error("Adding surfaces failed with exception: ", error)); * ``` */ Product.prototype.addSurfaces = function (surfaces, position) { var _this = this; var transferProductDef = Convert.fromSurfaces(surfaces); var surfacesIdentifiers = null; var surfacesName = null; if (Convert.isStateSurface(surfaces)) { surfacesIdentifiers = surfaces.surfaces; surfacesName = surfaces.name; } return EditorLoader .getInitData(this._context.editorUrl, transferProductDef, this._context.config) .then(function (serverConfig) { return JSON.parse(serverConfig)["product"]; }) .then(function (transferProduct) { return _this._context.client.callProcedure("addSurfaces", transferProduct, position, surfacesIdentifiers, true, surfacesName); }) .then(function () { return _this._context.editor.getProduct(); }); }; /** * Adds the given surface (page) to the product. * @param surface - A surface (page) to add. * @param position - A position in the surface array where the new surface (page) should be added. The index of the first surface is `0`. By default, this method adds pages to the end of the surface array. * @returns The product instance where the surface (page) was added. * @example * ``` js * // Let us add a back side to the postcard. * editor.getProduct() * // When we get the product. * .then(function(product) { * // If postcard has no back side. * if (product.surfaces.length < 2) { * // Adding the back to the loaded product. * return product.addSurface( * { * // Defining the template file. * printAreas: [{ designFile: "postcard_side2"}] * }) * // If the back side is added to the postcard. * .then(function(newProduct) { * // Replace the loaded product with the new one. * product = newProduct; * }); * } * }) * // If there was an error while getting the product or adding a back side to the postcard. * .catch(function (error) { * console.error("Adding surface failed with exception: ", error); * }); * ``` */ Product.prototype.addSurface = function (surface, position) { var surfaces; if (Convert.isStateSurface(surface)) { surfaces = { stateId: surface.stateId, surfaces: surface.surface != null ? [surface.surface] : ["0"], name: surface === null || surface === void 0 ? void 0 : surface.name }; } else { surfaces = [surface]; } return this.addSurfaces(surfaces, position); }; /** * Removes the given surface (page) from the product. * @param surface - A surface (page) to remove. * @returns The product instance where the surface (page) was removed from. * @example * ``` js * let product = await editor.getProduct(); * * // Remove the current surface. * product = await product.removeSurface(product.currentSurface) * // If there was an error thrown while removing the surface. * .catch(error => console.error("Removing the surface failed with exception: ", error)); * ``` */ Product.prototype.removeSurface = function (surface) { var _this = this; return this._context.client.callProcedure("removeSurface", surface.id) .then(function () { return _this._context.editor.getProduct(); }); }; /** * Opens the given product surface in the designer. * @param surface - A surface (page) to open. * @returns The product with the given surface (page) opened. * @example * ``` js * editor.getProduct() * .then(function (product) { * // Get the current surface index. * const indexOfCurrentSurface = product.surfaces.lastIndexOf(product.currentSurface); * if (indexOfCurrentSurface < 0) * throw "Surface not found!"; * * let indexOfNextSurface = indexOfCurrentSurface + 1; * if (indexOfNextSurface > (product.surfaces.length - 1)) * indexOfNextSurface = 0; * * // Switch to the next surface. * return product.switchTo(product.surfaces[indexOfNextSurface]); * }) * .then(function(result) { * console.log("Surface switched"); * }) * .catch(function (error) { * console.error("Switching the surfaces failed with exception: ", error); * }); * ``` */ Product.prototype.switchTo = function (surface) { var _this = this; return this._context.client.callProcedure("switchToSurface", surface.id) .then(function () { return _this._context.editor.getProduct(); }); }; /** * Reads product tags. * @returns The dictionary of product tags. */ Product.prototype.getTags = function () { return this._context.client.callProcedure("getTags"); }; /** * Specifies tags for the product. * @param tags - The tags that you want to specify for the product. * @example * ``` js * let newTags = { * "product": "postcard", * "design": "flowers", * "colorTheme": "red" * }; * * let product = await editor.getProduct(); * await product.setTags(newTags) * .catch(error => console.error("Setting tags failed with exception: ", error)); * ``` */ Product.prototype.setTags = function (tags) { return this._context.client.callProcedure("setTags", tags); }; /** * Sets mockups for several product pages. * @param mockupsData - The product surface with mockups and preview mockups. * @param options - Additional options for managing history and surface size. * @returns A new product instance containing the changed surfaces. * @example * ``` js * let newMockups = [ * { * surface: product.surfaces[0], * mockup: null * }, { * surface: product.surfaces[1], * mockup: { up: "mockup1" } * }, { * surface: product.surfaces[2], * mockup: { up: "mockup2" } * } * ]; * let options = { * addToHistory: false, * resetHistory: true, * updateSurfaceSize: true * }; * let product = await editor.getProduct(); * product = await product.setMockups(newMockups, options) * .catch(error => console.error("Failed to set up the mockups: ", error)); * ``` */ Product.prototype.setMockups = function (mockupsData, options) { return __awaiter(this, void 0, void 0, function () { var mockupsData_1, mockupsData_1_1, data, setNewMockups, mockupsData_2, mockupsData_2_1, data, mockup, previewMockups, previewMockups_1, previewMockups_1_1, previewMockup, transferProduct, getInitDataConfig, initDataJson, params; var e_1, _a, e_2, _b, e_3, _c; return __generator(this, function (_d) { switch (_d.label) { case 0: try { for (mockupsData_1 = __values(mockupsData), mockupsData_1_1 = mockupsData_1.next(); !mockupsData_1_1.done; mockupsData_1_1 = mockupsData_1.next()) { data = mockupsData_1_1.value; Convert.normalizeMockupTemplate(data); } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (mockupsData_1_1 && !mockupsData_1_1.done && (_a = mockupsData_1.return)) _a.call(mockupsData_1); } finally { if (e_1) throw e_1.error; } } setNewMockups = false; try { for (mockupsData_2 = __values(mockupsData), mockupsData_2_1 = mockupsData_2.next(); !mockupsData_2_1.done; mockupsData_2_1 = mockupsData_2.next()) { data = mockupsData_2_1.value; mockup = data.mockup; previewMockups = data.previewMockups || []; if (!Convert.isEmptyMockup(mockup)) { setNewMockups = true; } try { for (previewMockups_1 = (e_3 = void 0, __values(previewMockups)), previewMockups_1_1 = previewMockups_1.next(); !previewMockups_1_1.done; previewMockups_1_1 = previewMockups_1.next()) { previewMockup = previewMockups_1_1.value; if (Convert.isEmptyMockup(previewMockup)) continue; setNewMockups = true; } } catch (e_3_1) { e_3 = { error: e_3_1 }; } finally { try { if (previewMockups_1_1 && !previewMockups_1_1.done && (_c = previewMockups_1.return)) _c.call(previewMockups_1); } finally { if (e_3) throw e_3.error; } } } } catch (e_2_1) { e_2 = { error: e_2_1 }; } finally { try { if (mockupsData_2_1 && !mockupsData_2_1.done && (_b = mockupsData_2.return)) _b.call(mockupsData_2); } finally { if (e_2) throw e_2.error; } } transferProduct = null; if (!setNewMockups) return [3 /*break*/, 2]; getInitDataConfig = { watermark: { visibility: { canvas: false, proof: false } } }; if (this._context.config.userId) getInitDataConfig.userId = this._context.config.userId; if (this._context.config.tokenId) getInitDataConfig.tokenId = this._context.config.tokenId; return [4 /*yield*/, EditorLoader.getInitData(this._context.editorUrl, Convert.fromMockupsData(mockupsData), getInitDataConfig)]; case 1: initDataJson = _d.sent(); transferProduct = JSON.parse(initDataJson)["product"]; _d.label = 2; case 2: params = { updateRevertData: options != null ? options.updateRevertData : null, addToHistory: options != null ? options.addToHistory : null, resetHistory: options != null ? options.resetHistory : null, transferProduct: transferProduct, surfacesToBeCleared: !setNewMockups ? mockupsData.map(function (d) { return d.surface.id; }) : null, updateSurfaceSize: options != null ? options.updateSurfaceSize : null }; return [4 /*yield*/, this._context.client.callProcedure("updateMockups", params)]; case 3: _d.sent(); return [2 /*return*/, this._context.editor.getProduct()]; } }); }); }; /** * Applies a color theme to the product. * @param theme - A name of a color theme defined for the current product or through the **clientConfig.json** file. * @param options - Options for managing the history of user actions. * @example * ``` js * // Define a color theme. * const productTheme = { * "violet": { * "C01": "rgb(102,45,145)", * "C02": "rgb(150,67,214)", * "C03": "rgb(190,107,255)", * "C04": "rgb(32,18,77)" * } * }; * * // Enable the violet theme. * const editor = await CustomersCanvas.IframeApi.loadEditor(iframe, productDefinition, * { productThemes: productTheme, defaultProductTheme: "violet" }) * // If an error occurred while loading the editor. * .catch(e => console.log(e)); * * // If the editor has been successfully loaded, change the color theme. * await editor.applyProductTheme({ * "C01": "rgb(241,160,175)", * "C02": "rgb(255,200,214)", * "C03": "rgb(255,255,255)", * "C04": "rgb(224,102,102)" * }, * // Don't save the theme change in the history. * { * addToHistory: false * }); * ``` */ Product.prototype.applyProductTheme = function (theme, options) { if (options === void 0) { options = { addToHistory: true }; } return this._context.client.callProcedure("applyProductTheme", theme, options); }; /** * Lists all design elements in the product. * @param options - Additional parameters. You can pass `options.includeMockup` with the value `false` to not add mockup items to the list. By default, mockup items will be added to the resulting array. * @returns An array of elements from all product pages. * @example * ``` js * let product = await editor.getProduct(); * // Get the item list. * const items = await product.getAllItems({includeMockup: false}); * console.log("The product contains " + items.length + " design elements"); * ``` */ Product.prototype.getAllItems = function (options) { if (options === void 0) { options = { includeMockup: true }; } return __awaiter(this, void 0, void 0, function () { var items; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this._context.client.callProcedure("getAllItems", options)]; case 1: items = (_a.sent()); return [2 /*return*/, items.map(function (i) { return new Item(i); })]; } }); }); }; Product.prototype.getProductModel = function () { return __awaiter(this, void 0, void 0, function () { var _a, _b; return __generator(this, function (_c) { switch (_c.label) { case 0: _b = (_a = SerializationProvider.getProductSerializer()).deserialize; return [4 /*yield*/, this._context.client.callProcedure("getProductModel")]; case 1: return [2 /*return*/, _b.apply(_a, [_c.sent()])]; } }); }); }; Product.prototype.setProductModel = function (product) { return this._context.client.callProcedure("setProductModel", SerializationProvider.getProductSerializer().serialize(product)); }; /** * Gets the bounding rectangles for design elements with regard to their rotation. * @param ids - An array of item identifiers. * @returns An array of item bounds, in points. * @example In the following example, `toRectangleF()` returns the bounds without taking into account the item rotation, i.e. the vertically or horizontally oriented rectangle, whereas `rotatedRect` contains the rotation `angle` and `bounds`. * ``` js * const ids = (await editor.getSelectedItems()).map(item => item.id); * if (ids.length > 0) { * * var product = await editor.getProduct(); * var rectangles = await product.getItemRectangles(ids); * var message = ""; * for (let i = 0; i < rectangles.length; i++) { * const rotatedRect = rectangles[i]; * const rect = rotatedRect.toRectangleF(); * message += "Item with " + ids[i] + * " has: width: " + rect.width.toFixed(2) + * ", height: " + rect.height.toFixed(2) + * ", location: (" + rect.left.toFixed(2) + ", " + rect.top.toFixed(2) + ")" + * ", angle: " + rotatedRect.angle.toFixed(2) + "\n"; * } * * console.log(message); * } * ``` */ Product.prototype.getItemRectangles = function (ids) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this._context.client.callProcedure("getRectangles", ids)]; case 1: return [2 /*return*/, (_a.sent()).map(function (rect) { return new RotatedRectangleF(rect.centerX, rect.centerY, rect.width, rect.height, rect.angle); })]; } }); }); }; Product.prototype.getItems = function (predicate, args) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this._context.client.callProcedure("getItems", predicate.toString(), args)]; case 1: return [2 /*return*/, (_a.sent()).map(function (serializedItem) { return new ProductParser().parseItem(JSON.parse(serializedItem)); })]; } }); }); }; Product.prototype.setItem = function (item) { return this._context.client.callProcedure("setItem", SerializationProvider.getProductSerializer().serializeModelComponent(item)); }; Product.prototype.getItemById = function (id) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.getItems(function (item, args) { return item.id === args.id; }, { id: id })]; case 1: return [2 /*return*/, (_a.sent())[0]]; } }); }); }; Product.prototype.getItemByName = function (name) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.getItems(function (item, args) { return item.name === args.name; }, { name: name })]; case 1: return [2 /*return*/, (_a.sent())[0]]; } }); }); }; Product.prototype.removeItems = function (predicate, args) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this._context.client.callProcedure("removeItems", predicate.toString(), args)]; case 1: return [2 /*return*/, (_a.sent())]; } }); }); }; Product.prototype.removeItemById = function (id) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.removeItems(function (item, args) { return item.id === args.id; }, { id: id })]; case 1: _a.sent(); return [2 /*return*/]; } }); }); }; Product.prototype.removeItemByName = function (name) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.removeItems(function (item, args) { return item.name === args.name; }, { name: name })]; case 1: _a.sent(); return [2 /*return*/]; } }); }); }; /** * Lists all variable items in the product. * @returns An array of variable items. The `isVariable` property of these design elements is set to `true`. Also, this array contains in-string and interpolation placeholders. * @example * ``` js * let product = await editor.getProduct(); * let items = await product.getVariableItems(); * if (items.length) * items.forEach(item => console.log(item.name)); * else * console.log("This product contains no variable items."); * ``` */ Product.prototype.getVariableItems = function () { return this._context.client.callProcedure("getVariableItems"); }; Object.defineProperty(Product.prototype, "currentSurfaceIndex", { get: function () { return this.surfaces.indexOf(this.currentSurface); }, enumerable: true, configurable: true }); /** * Sets an image or a plain color to the background. * @param surfaces - An array of surfaces where the background should be changed. * @param data - Either an object representing the image metadata or a string representing the color in CCS format (for example: <code>"DeepSkyBlue"</code>, <code>"rgb(48,194,255)"</code>, <code>"#30C2FF"</code>). * @returns An array of shape items. * @example * ``` js * changeBackground = async () => { * * // Get the product loaded into the editor. * let product = await editor.getProduct(); * * // Get metadata of an image in the public gallery. * const metaData = await editor.configuration.getImageMetadata("public:backgrounds/azure.jpg"); * * // Apply the image to the background of the first surface. * product.changeBackground([product.surfaces[0]], metaData); * * // Apply the color to the background of the second surface. * product.changeBackground([product.surfaces[1]], "#30C2FF"); * } * ``` */ Product.prototype.changeBackground = function (surfaces, data) { return __awaiter(this, void 0, void 0, function () { var changeBackgroundParams; return __generator(this, function (_a) { switch (_a.label) { case 0: changeBackgroundParams = { surfaceIds: surfaces.map(function (s) { return s.id; }), data: data instanceof Color ? data.toString() : data }; return [4 /*yield*/, this._context.client.callProcedure("changeBackground", changeBackgroundParams)]; case 1: return [2 /*return*/, _a.sent()]; } }); }); }; /** * Replaces surfaces and returns a new product instance with the updated surfaces. * * @remarks By default, `updateSurfaces` moves only texts and image placeholders to new positions and drops other design elements. Note that this method changes the content of placeholders having the same layer names on the current {@link Surface} and in the new layout. To maintain the rest elements, set the `replaceAll` param to `true`. In this case, the rest of placeholders take content in a random order according to their type. If the old layout had more placeholders than the new layout, then extra placeholders are removed. * * If the current and the new surfaces have different sizes, you can specify whether to update the surface size to match the new one by using the `updateSurfaceSize` param. * @param params - Additional parameters for changing surfaces. * @returns A new product instance containing the changed surface. * @example In this example, we take surfaces `1` and `4` from the specified state file and insert them instead of surfaces `0` and `1` in the loaded product. * ``` js * let product = await editor.getProduct(); * let options = { * replaceAll: true, * definition: "7a6ecf23-1286-4e90-8f18-c7c1c77e3cb0", * surfaces: [0, 1], * newProductSurfaces: [1, 4] * }; * * await product.updateSurfaces(options); * ``` */ Product.prototype.updateSurfaces = function (params) { return __awaiter(this, void 0, void 0, function () { var transferProductDef, transferProductJson, _a, _b; return __generator(this, function (_c) { switch (_c.label) { case 0: transferProductDef = typeof params.definition === "string" ? [params.definition] : params.definition; _b = (_a = JSON).parse; return [4 /*yield*/, EditorLoader.getInitData(this._context.editorUrl, transferProductDef, this._context.config, null, true)]; case 1: transferProductJson = _b.apply(_a, [_c.sent()])["product"]; params["transferProductJson"] = transferProductJson; return [4 /*yield*/, this._context.client.callProcedure("updateSurfaces", params)]; case 2: _c.sent(); return [4 /*yield*/, this._context.editor.getProduct()]; case 3: return [2 /*return*/, _c.sent()]; } }); }); }; Product.prototype.getViolationData = function () { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this._context.client.callProcedure("getViolationData")]; case 1: return [2 /*return*/, _a.sent()]; } }); }); }; return Product; }(ModelComponent)); export { Product }; /** * Surface insertion mode. * @remarks You can use this structure in {@link Product.updateSurfaces|updateSurfaces}. * @public */ export var UpdateSurfaceBehavior; (function (UpdateSurfaceBehavior) { /** The number of pages remains the same, and the sizes of the `surfaces` and `newProductSurfaces` arrays must match. */ UpdateSurfaceBehavior["keepCurrentSurfaceLength"] = "keepCurrentSurfaceLength"; /** First deletes all the surfaces of the loaded product and then takes the pages from the new product. */ UpdateSurfaceBehavior["changeSurfaceLength"] = "changeSurfaceLength"; })(UpdateSurfaceBehavior || (UpdateSurfaceBehavior = {})); /** * A surface representing a product page. * @example * ``` js * const surface = { * width: 200, height: 150, * printAreas: [{ * bounds: { x:0, y:0, width: 200, height: 150} * }], * mockup: { * down: "envelope" * }, * previewMockups: [{ down: "previewEnvelope" }] * } * ``` * @public */ var Surface = /** @class */ (function (_super) { __extends(Surface, _super); /** @internal */ function Surface(rawSurface, _parentProduct, _context) { var _this = _super.call(this, rawSurface) || this; _this._parentProduct = _parentProduct; _this._context = _context; /** An array of channel containers for print embellishments. */ _this.containers = []; _this.width = rawSurface["width"]; _this.height = rawSurface["height"]; _this.mockup = new SurfaceMockup(rawSurface["mockup"]); _this.previewMockups = (rawSurface["previewMockups"] || []).map(function (raw) { return new SurfaceMockup(raw); }); _this.containers = (rawSurface["containers"] || []).map(function (raw) { return new Container(raw, _context); }); // For backward compatibility. _this.printAreas = (rawSurface["printAreas"] || []).map(function (raw) { return new PrintArea(raw, _this); }); return _this; } /** * Sets a new surface mockup and returns a new product instance containing the changed surface. * @param mockup - A mockup to set. * @param previewMockups - A collection of preview mockups for proof images. * @param options - Additional configuration of mockups. In the current implementation, you can only pass `options.updateRevertData`. This option defines whether this mockup should be reverted or not when the user reverts product changes. If `true`, the new mockup is stored as one to restore when the product is reverted. Otherwise, the previously stored mockup is restored on a product revert. The default value is `true`. * @returns A new product instance containing the changed surface. * @example * ``` js * const mockup = { * up: "envelopeMockup" * } * * let product = await editor.getProduct(); * product = await product.surfaces[0].setMockup(mockup) * .catch(error => console.error("Failed to set up the mockup: ", error)); * ``` */ Surface.prototype.setMockup = function (mockup, previewMockups, options) { return this._parentProduct.setMockups([{ surface: this, mockup: mockup, previewMockups: previewMockups }], options); }; Surface.prototype.changeBackground = function (data) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this._parentProduct.changeBackground([this], data)]; case 1: return [2 /*return*/, (_a.sent())[0]]; } }); }); }; /** * Sets a new print area for the surface and returns a new product instance containing the changed surface. * * @remarks By default, `setPrintAreas` moves only texts and image placeholders to new positions and drops other design elements. Note that this method changes the content of placeholders having the same layer names on the current {@link Surface} and in the new layout. To maintain the rest elements, set the `replaceAll` option to `true`. In this case, the rest of placeholders take content in a random order according to their type. If the old layout had more placeholders than the new layout, then extra placeholders are removed. * * If the current print area and the new print area have different sizes, you can specify whether to update the surface size to match the new print area by using the `updateSurfaceSize` option. * @param printAreas - New print areas. * @param options - Additional configuration settings for the print areas. * @returns A new product instance containing the changed surface. * @example * ``` js * const newPrintAreas = [{ designFile: "stamp" }]; * const options = { * replaceAll: true, * preserveSafetyLines: false, * updateSurfaceSize: true * }; * let produt = await editor.getProduct(); * product = product.surfaces[0].setPrintAreas(newPrintAreas, options); * .catch(error => console.error("Failed to set up the print area: ", error)); * ``` */ Surface.prototype.setPrintAreas = function (printAreas, options) { var _this = this; var transferProductDef = Convert.fromPrintAreas(printAreas); return EditorLoader.getInitData(this._context.editorUrl, transferProductDef, this._context.config, null, true) .then(function (serverConfig) { return JSON.parse(serverConfig)["product"]; }) .then(function (transferProduct) { return _this._context.client.callProcedure("updatePrintAreas", _this.id, transferProduct, options); }) .then(function () { return _this._context.editor.getProduct(); }); }; Surface.prototype.getContainer = function (name) { return this.containers.filter(function (c) { return c.name === name; })[0]; }; Surface.prototype.getContainers = function () { return this.containers; }; Surface.prototype.addContainer = function (containerDefiniton) { return __awaiter(this, void 0, void 0, function () { var container, _a; return __generator(this, function (_b) { switch (_b.label) { case 0: if (containerDefiniton == null) return [2 /*return*/]; container = new Container(containerDefiniton, this._context); this.containers.push(container); containerDefiniton.type = container.type; _a = container; return [4 /*yield*/, this._context.client.callProcedure("insertContainer", containerDefiniton)]; case 1: _a.id = _b.sent(); return [2 /*return*/, container]; } }); }); }; Surface.prototype.insertContainer = function (containerDefiniton, index) { return __awaiter(this, void 0, void 0, function () { var parsedIndex, container, _a; return __generator(this, function (_b) { switch (_b.label) { case 0: parsedIndex = typeof (index) == "string" ? parseInt(index) : index; if (!this.isIndexOfContainers(parsedIndex) && parsedIndex != this.containers.length /*вставка на последнее место в массиве*/) { throw new ArgumentException("insertContainer: index '" + index + "' is wrong. Value must be an integer number in containers range."); } if (this.isIndexInRestrictedRange(parsedIndex)) { throw new ArgumentException("insertContainer: index '" + parsedIndex + "' is wrong. You cannot insert a container instead of background container."); } if (parsedIndex < this.findFirstChannelContainerIndex()) { throw new ArgumentException("insertContainer: index '" + parsedIndex + "' is wrong. You cannot insert a channel container before the last surface container."); } container = new Container(containerDefiniton, this._context); containerDefiniton.type = container.type; this.containers.splice(parsedIndex, 0, container); _a = container; return [4 /*yield*/, this._context.client.callProcedure("insertContainer", containerDefiniton, parsedIndex)]; case 1: _a.id = _b.sent(); return [2 /*return*/, container]; } }); }); }; Surface.prototype.removeContainer = function (index) { var parsedIndex = typeof (index) == "string" ? parseInt(index) : index; if (!this.isIndexOfContainers(parsedIndex)) { throw new ArgumentException("removeContainer: index '" + parsedIndex + "' is wrong. Value must be an integer number in containers range."); } if (this.isLastContainer(parsedIndex)) throw new ArgumentException("removeContainer: you cannot delete the last container."); this.containers.splice(parsedIndex, 1); this._context.client.callProcedure("removeContainer", parsedIndex); }; Surface.prototype.moveContainer = function (initialIndex, destinationIndex) { var _this = this; if (initialIndex === destinationIndex) return; var parseIndex = function (index) { return typeof index === "string" ? parseInt(index) : index; }; var initialParsedIndex = parseIndex(initialIndex); var destinationParsedIndex = parseIndex(destinationIndex); [initialParsedIndex, destinationParsedIndex].forEach(function (value) { if (!_this.isIndexOfContainers(value)) { throw new ArgumentException("moveContainer: index '" + value + "' is wrong. Value must be an integer number in containers range."); } if (_this.isIndexInRestrictedRange(value)) { throw new ArgumentException("moveContainer: index '" + initialParsedIndex + "' is wrong. You cannot move background container."); } }); if (typeof (this.containers[initialParsedIndex].type) != typeof (this.containers[destinationParsedIndex].type)) throw new ArgumentException("moveContainer: initial index '" + initialParsedIndex + "' and destination index '" + destinationParsedIndex + "' are wrong. You cannot move channel container with surface container."); var initialIndexContainer = this.containers.splice(initialParsedIndex, 1)[0]; this.containers.splice(destinationParsedIndex, 0, initialIndexContainer); this._context.client.callProcedure("moveContainer", initialParsedIndex, destinationParsedIndex); return this.containers[destinationParsedIndex]; }; Surface.prototype.insertItem = function (item, index, containerIndex) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this._context.client.callProcedure("insertItem", SerializationProvider.getProductSerializer().serializeModelComponent(item), index, containerIndex, this._parentProduct.surfaces.indexOf(this))]; case 1: return [2 /*return*/, _a.sent()]; } }); }); }; Surface.prototype.findFirstChannelContainerIndex = function () { var index = this.containers.findIndex(function (container) { return container.type === ChannelContainerType.SpotColor || container.type === ChannelContainerType.Texture; }); if (index !== -1) { return index; } throw new Error("findFirstChannelContainerIndex: no channel container found."); }; Surface.prototype.isIndexOfContainers = function (index) { return typeof index === "number" && !isNaN(index) && index >= 0 && index < this.containers.length; }; Surface.prototype.isIndexInRestrictedRange = function (index) { if (index == 0 && this.containers[index].name == Container.BG_CONTAINER_NAME) return true; return false; }; Surface.prototype.isLastContainer = function (index) { return index == 0 && this.containers.length == 1; }; return Surface; }(ModelComponent)); export { Surface }; // For backward compatibility only. /** * A print area. * @example * ``` js * // Initialize a product with the "card.psd" template and a channel container. * const productDefinition = { * surfaces: [{ * printAreas: [{ * name: "postcard", *