restructured inject.js
This commit is contained in:
69
client/src/modules/communication.ts
Normal file
69
client/src/modules/communication.ts
Normal file
@@ -0,0 +1,69 @@
|
||||
import * as I from "../types/types";
|
||||
import * as xml from "./xml";
|
||||
|
||||
// rework try/catch ?
|
||||
export function sendMessage(data: I.Message, to: string): void {
|
||||
if (to === "parent")
|
||||
window.parent.postMessage(JSON.stringify(data), '*');
|
||||
else {
|
||||
if (document.getElementById(to) === null) {
|
||||
console.log(`Element with ID ${to} does not exist`);
|
||||
return;
|
||||
}
|
||||
|
||||
const receiver: any = document.getElementById(to);
|
||||
if (receiver.contentWindow !== null)
|
||||
receiver.contentWindow.postMessage(JSON.stringify(data), "*")
|
||||
}
|
||||
}
|
||||
|
||||
export function listenToMessages(inHandler?: CallableFunction): void {
|
||||
window.addEventListener('message', (e: any): void => {
|
||||
if (inHandler)
|
||||
inHandler(e);
|
||||
});
|
||||
}
|
||||
|
||||
export function sendXML(inUrl: string, inTo: string, inEvent: string, inFrom: string, inDate: number = Date.now()) {
|
||||
xml.getXMLPromise(inUrl).then((result: unknown): void => {
|
||||
const message: I.Message = {
|
||||
date: inDate,
|
||||
from: inFrom,
|
||||
message: result,
|
||||
event: inEvent
|
||||
}
|
||||
sendMessage(message, inTo);
|
||||
}).catch(function (err) {
|
||||
console.error(err);
|
||||
});
|
||||
}
|
||||
|
||||
export function sendEventToChild(inEvent: string) {
|
||||
const message: I.Message = {
|
||||
message: null,
|
||||
from: "parent",
|
||||
event: inEvent,
|
||||
date: Date.now()
|
||||
};
|
||||
sendMessage(message, "iframeSeatmap");
|
||||
}
|
||||
|
||||
export function sendEventToParent(inEvent: string) {
|
||||
const message: I.Message = {
|
||||
message: null,
|
||||
from: "child",
|
||||
event: inEvent,
|
||||
date: Date.now()
|
||||
};
|
||||
sendMessage(message, "parent");
|
||||
}
|
||||
|
||||
export function needSeatmapXML(inID: string) {
|
||||
const message: I.Message = {
|
||||
message: inID,
|
||||
from: "child",
|
||||
event: "child_needSeatmapXML",
|
||||
date: Date.now()
|
||||
};
|
||||
sendMessage(message, "parent");
|
||||
}
|
||||
16
client/src/modules/config.ts
Normal file
16
client/src/modules/config.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import * as I from "../types/types";
|
||||
|
||||
export const config: I.Config = {
|
||||
debug: true,
|
||||
branch: "staging",
|
||||
urlSeatmapStaging: "https://staging.tickets.zinomedia.de",
|
||||
urlSeatmapMaster: "https://tickets.zinomedia.de",
|
||||
urlCSSChildMaster: "https://tickets.zinomedia.de/dist/styleChild.css",
|
||||
urlCSSChildStaging: "https://staging.tickets.zinomedia.de/dist/styleChild.css",
|
||||
urlCSSParentMaster: "https://tickets.zinomedia.de/dist/styleParent.css",
|
||||
urlCSSParentStaging: "https://staging.tickets.zinomedia.de/dist/styleParent.css",
|
||||
urlJSCStaging: "https://staging.tickets.zinomedia.de/libs/jQuery-Seat-Charts/jquery.seat-charts.min.js",
|
||||
urlJSCMaster: "https://tickets.zinomedia.de/libs/jQuery-Seat-Charts/jquery.seat-charts.min.js",
|
||||
urlCSSJSCStaging: "https://staging.tickets.zinomedia.de/libs/jQuery-Seat-Charts/jquery.seat-charts.css",
|
||||
urlCSSJSCMaster: "https://tickets.zinomedia.de/libs/jQuery-Seat-Charts/jquery.seat-charts.css"
|
||||
}
|
||||
44
client/src/modules/parser.ts
Normal file
44
client/src/modules/parser.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
import * as I from "../types/types";
|
||||
|
||||
export function getVenueLocation(): string {
|
||||
let span: string[] = [];
|
||||
jQuery(".venue span").each(function () {
|
||||
span.push(jQuery(this).text());
|
||||
});
|
||||
|
||||
return span.join(", ");
|
||||
}
|
||||
|
||||
export function getInputs(inContent: string, inInputsWithValue: I.InputsWithValue): void {
|
||||
const parsedHTML: Node[] = $.parseHTML(inContent);
|
||||
let inputs: I.Inputs = {};
|
||||
|
||||
jQuery(parsedHTML).find('input').each(function (this: any) {
|
||||
const name: string = this.name;
|
||||
const value: string = this.value;
|
||||
if (value !== '')
|
||||
inputs[name] = value;
|
||||
});
|
||||
|
||||
inInputsWithValue = { ...inInputsWithValue, ...inputs };
|
||||
}
|
||||
|
||||
// todo: check with different venues
|
||||
export function getImportantNote(inInputsWithValue: I.InputsWithValue): void {
|
||||
const importantNote: string | null = $(".important_note")[0].textContent;
|
||||
|
||||
if (importantNote?.trim().length) {
|
||||
const importantNoteEncoded: string = encodeURIComponent(importantNote);
|
||||
inInputsWithValue["importantNote"] = importantNote;
|
||||
inInputsWithValue["importantNoteEncoded"] = importantNoteEncoded;
|
||||
}
|
||||
}
|
||||
|
||||
export function getAdditionalInputs(inContent: string, inInputsWithValue: I.InputsWithValue): void {
|
||||
inInputsWithValue["event"] = inContent.match(/event:"(.+?)"/)![1];
|
||||
inInputsWithValue["holdcode"] = inContent.match(/holdcode:"(.+?)"/)![1];
|
||||
inInputsWithValue["posturlRaw"] = inContent.match(/posturl:"(.+?)"/)![1];
|
||||
inInputsWithValue["posturlRawDecoded"] = decodeURIComponent(inInputsWithValue["posturlRaw"]);
|
||||
inInputsWithValue["posturl"] = decodeURIComponent(`${inInputsWithValue["posturlRaw"]}&event=${inInputsWithValue["event"]}&holdcode=${inInputsWithValue["holdcode"]}&nocache=0&inclpkg=Y&incloffer=Y&inclcartdetails=Y&inclCart=Y&inclvenue=Y`);
|
||||
inInputsWithValue["venueLocation"] = getVenueLocation();
|
||||
}
|
||||
71
client/src/modules/ui.ts
Normal file
71
client/src/modules/ui.ts
Normal file
@@ -0,0 +1,71 @@
|
||||
import * as I from "../types/types";
|
||||
import * as Communication from "./communication";
|
||||
|
||||
export function setOptionSelect(inSeatmapListing: I.Seatmap[], inId: string) {
|
||||
const seatmapDropdown: HTMLElement | null = document.getElementById(inId);
|
||||
if (seatmapDropdown) {
|
||||
for (let seatmapObj of inSeatmapListing) {
|
||||
var opt = document.createElement('option');
|
||||
opt.value = seatmapObj.id[0];
|
||||
opt.innerHTML = seatmapObj.desc[0];
|
||||
seatmapDropdown.appendChild(opt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function setEventInfo(inEventInfo: I.EventInfo, inInputswithValue: I.InputsWithValue): void {
|
||||
// console.log(inEventInfo);
|
||||
jQuery("#eventInfoDesc span.fl-heading-text")[0].childNodes[0].textContent = inEventInfo.desc[0];
|
||||
jQuery("#eventInfoDate p")[0].childNodes[0].textContent = inEventInfo.start[0];
|
||||
jQuery("#eventInfoCapacity p")[0].childNodes[0].textContent = inEventInfo.venue_config_capacity[0];
|
||||
jQuery("#eventInfoLocation p")[0].childNodes[0].textContent = inInputswithValue.venueLocation;
|
||||
}
|
||||
|
||||
export function createDialog(inChildHasVenueXML: boolean): void {
|
||||
jQuery("#dialogSeatmap").append($("<iframe id='iframeSeatmap' scrolling='no' frameborder='0' marginwidth='0' marginheight='0' allowfullscreen width='100%' height='" + window.outerHeight + "px' />")
|
||||
.attr("src", "https://staging.tickets.zinomedia.de/"))
|
||||
.dialog({
|
||||
modal: true,
|
||||
autoOpen: false,
|
||||
closeOnEscape: true,
|
||||
draggable: false,
|
||||
hide: true,
|
||||
show: true,
|
||||
resizable: false,
|
||||
title: "",
|
||||
width: "99%",
|
||||
height: "auto",
|
||||
close: () => {
|
||||
jQuery('html, body').css('overflow', 'auto');
|
||||
}
|
||||
});
|
||||
|
||||
jQuery("#openSeatmap").on("click", () => {
|
||||
if (!inChildHasVenueXML)
|
||||
Communication.sendEventToChild("parent_init_venue");
|
||||
|
||||
jQuery('html, body').css('overflow', 'hidden');
|
||||
jQuery("#dialogSeatmap").dialog('open');
|
||||
});
|
||||
}
|
||||
|
||||
export function injectBookingBtn(): void {
|
||||
jQuery('#flash_seat_map_box_id').css({
|
||||
"display": "block",
|
||||
"position": "relative",
|
||||
"width": "100%"
|
||||
});
|
||||
jQuery("#flash_seat_map_box_id").append(`
|
||||
<div id="containerBookingBtn">
|
||||
<button type="button" id="openSeatmap">
|
||||
<div>
|
||||
<img src="https://staging.tickets.zinomedia.de/dist/stadium.png">
|
||||
</div>
|
||||
Saalplanbuchung <br/><br/>
|
||||
<span>Suchen Sie Ihren Platz selbst aus</span>
|
||||
</button> <br/>
|
||||
<button type="button" id="foobarParent">foobarParent</button> <br/>
|
||||
<div id="dialogSeatmap" hidden="hidden"></div>
|
||||
</div>
|
||||
`);
|
||||
}
|
||||
100
client/src/modules/utils.ts
Normal file
100
client/src/modules/utils.ts
Normal file
@@ -0,0 +1,100 @@
|
||||
export default class Utils {
|
||||
|
||||
static waitForElement(selector: any, callback: Function, type: string = "selector", checkFrequencyInMs: number = 1000, timeoutInMs: number = 10000) {
|
||||
let startTimeInMs: number = Date.now();
|
||||
(function loopSearch(): void {
|
||||
let value: boolean;
|
||||
console.log(selector);
|
||||
|
||||
if (type === "selector")
|
||||
value = Utils.querySelector(selector);
|
||||
else if (type === "function")
|
||||
value = Utils.isFunction(selector);
|
||||
else
|
||||
value = false;
|
||||
|
||||
if (value) {
|
||||
console.log("defined");
|
||||
callback();
|
||||
}
|
||||
else {
|
||||
setTimeout(function (): void {
|
||||
console.log("repeating");
|
||||
if (timeoutInMs && Date.now() - startTimeInMs > timeoutInMs)
|
||||
return;
|
||||
loopSearch();
|
||||
}, checkFrequencyInMs);
|
||||
}
|
||||
})();
|
||||
}
|
||||
|
||||
static waitForSeatmap(callback: Function, checkFrequencyInMs: number = 100, timeoutInMs: number = 10000) {
|
||||
const seatCharts: any = (<any>window).jQuery("#containerSeatmap").seatCharts;
|
||||
let startTimeInMs: number = Date.now();
|
||||
|
||||
if (Utils.isFunction(seatCharts)) {
|
||||
console.log("defined");
|
||||
callback();
|
||||
}
|
||||
else {
|
||||
setTimeout(function (): void {
|
||||
console.log("repeating");
|
||||
if (timeoutInMs && Date.now() - startTimeInMs > timeoutInMs)
|
||||
return;
|
||||
Utils.waitForSeatmap(callback);
|
||||
}, checkFrequencyInMs);
|
||||
}
|
||||
}
|
||||
|
||||
static querySelector(selector: string): boolean {
|
||||
if (document.querySelector(selector) != null)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
static isFunction(selector: string): boolean {
|
||||
if (typeof selector === "function")
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
static async delay(ms: number) {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
static inject(content: string, type: string = "js", loc: string = "head") {
|
||||
var script: HTMLLinkElement | HTMLScriptElement;
|
||||
|
||||
if (type === "js") {
|
||||
script = document.createElement('script');
|
||||
script.type = 'text/javascript';
|
||||
script.src = content;
|
||||
}
|
||||
else if (type === "css") {
|
||||
script = document.createElement('link');
|
||||
script.type = 'text/css';
|
||||
script.rel = "stylesheet"
|
||||
script.href = content;
|
||||
}
|
||||
else if (type === "script") {
|
||||
script = document.createElement('script');
|
||||
script.type = 'text/javascript';
|
||||
script.innerHTML = content;
|
||||
}
|
||||
else
|
||||
return;
|
||||
|
||||
|
||||
if (loc === "body")
|
||||
document.body.appendChild(script);
|
||||
else if (loc === "head")
|
||||
document.head.appendChild(script);
|
||||
}
|
||||
|
||||
static getDayName(date: Date, locale: string) {
|
||||
return date.toLocaleDateString(locale, { weekday: 'long' });
|
||||
}
|
||||
}
|
||||
|
||||
56
client/src/modules/xml.ts
Normal file
56
client/src/modules/xml.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
import axios, { AxiosResponse } from 'axios';
|
||||
var xml2jsParser = require('xml2js').parseString;
|
||||
import * as I from "../types/types";
|
||||
import Utils from './utils';
|
||||
|
||||
export function getXMLPromise(url: string): Promise<unknown> {
|
||||
return axios.get(url)
|
||||
.then(function (response: void | AxiosResponse<any>) {
|
||||
|
||||
return new Promise(function (resolve: any, reject: any) {
|
||||
const AxiosResponse = <AxiosResponse>response;
|
||||
if (AxiosResponse.status === 200 && AxiosResponse.headers["content-type"] === "text/xml;charset=utf-8") {
|
||||
xml2jsParser(AxiosResponse.data, { normalizeTags: true, normalize: true, mergeAttrs: true }, function (err: any, result: any) {
|
||||
if (err)
|
||||
reject(err);
|
||||
else {
|
||||
resolve(result);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
})
|
||||
.catch(function (error) {
|
||||
console.log(error);
|
||||
})
|
||||
}
|
||||
|
||||
export function getSeatmapListing(inVenueXML: I.VenueXML): I.Seatmap[] {
|
||||
return inVenueXML.seatmap_config[0].seatmap;
|
||||
}
|
||||
|
||||
export function getEventInfo(inVenueXML: I.VenueXML): I.EventInfo {
|
||||
const eventObj: I.Event = inVenueXML.event[0];
|
||||
const event = inVenueXML.event[0];
|
||||
const venue_config = inVenueXML.venue_config[0];
|
||||
const dateObj: Date = new Date(parseInt(event.year[0]), parseInt(event.month[0])-1, parseInt(event.hour[0]), parseInt(event.minute[0]));
|
||||
const start: string[] = [ dateObj.toLocaleString(["de-DE"], { weekday: "long", day: "2-digit", month: "2-digit", year: "numeric", hour: "2-digit", minute: "2-digit", timeZoneName: "short" }) ];
|
||||
const weekday = [ Utils.getDayName(dateObj, "de-DE") ];
|
||||
|
||||
const eventExtend: I.EventExtend = {
|
||||
venue_config_capacity: venue_config.capacity,
|
||||
venue_config_code: venue_config.code,
|
||||
venue_config_desc: venue_config.desc,
|
||||
venue_config_id: venue_config.id,
|
||||
venue_config_nav_image: venue_config.nav_image,
|
||||
venue_config_nav_image_height: venue_config.nav_image_height,
|
||||
venue_config_nav_image_width: venue_config.nav_image_width,
|
||||
start: start,
|
||||
weekday: weekday,
|
||||
};
|
||||
|
||||
let eventInfo: I.EventInfo = { ...eventObj, ...eventExtend };
|
||||
|
||||
return eventInfo;
|
||||
}
|
||||
Reference in New Issue
Block a user