mirror of
https://github.com/Hopiu/django-markdownx.git
synced 2026-03-17 14:00:22 +00:00
353 lines
7.1 KiB
TypeScript
353 lines
7.1 KiB
TypeScript
"use strict";
|
|
|
|
interface EventListener {
|
|
|
|
object: Element | Document,
|
|
listeners: {
|
|
type: string,
|
|
listener: any,
|
|
capture: boolean,
|
|
} []
|
|
|
|
}
|
|
|
|
|
|
export interface RequestBase {
|
|
|
|
url: string;
|
|
data: FormData;
|
|
progress(event: any): any;
|
|
error(response: string): any;
|
|
success(response: string): any;
|
|
send(): void;
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
* Looks for a cookie, and if found, returns the values.
|
|
*
|
|
* ... note:: Only the first item in the array is returned
|
|
* to eliminate the need for array deconstruction
|
|
* in the target.
|
|
*
|
|
* @param {string} name - The name of the cookie.
|
|
* @returns {string | null}
|
|
*/
|
|
export function getCookie (name: string): string | null {
|
|
|
|
if (document.cookie && document.cookie.length) {
|
|
|
|
const cookies: string = document.cookie
|
|
.split(';')
|
|
.filter(cookie => cookie.indexOf(`${name}=`) === 0)[0];
|
|
|
|
try{
|
|
|
|
return decodeURIComponent(
|
|
cookies.trim().substring(name.length + 1)
|
|
);
|
|
|
|
} catch (e) {
|
|
|
|
if (e instanceof TypeError) {
|
|
console.info(`No cookie with key "${name}". Wrong name?`);
|
|
return null
|
|
}
|
|
|
|
throw e
|
|
}
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
* @example
|
|
*
|
|
*
|
|
* @param rows
|
|
* @returns
|
|
*/
|
|
export function zip (...rows: any[]) {
|
|
|
|
if (rows[0].constructor == Array)
|
|
return [...rows[0]].map((_, c) => rows.map(row => row[c]));
|
|
|
|
// ToDo: To be updated to Objects.values in ECMA2017 after the method is fully ratified.
|
|
const asArray = rows.map(row => Object.keys(row).map(key => row[key]));
|
|
|
|
return [...asArray[0]].map((_, c) => asArray.map(row => row[c]));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
*
|
|
* @param collections
|
|
* @returns
|
|
*/
|
|
export function mountEvents (...collections: EventListener[]): any[] {
|
|
|
|
return collections.map(events =>
|
|
events.listeners
|
|
.map(series =>
|
|
events.object
|
|
.addEventListener(
|
|
series.type,
|
|
series.listener,
|
|
series.capture
|
|
)
|
|
)
|
|
)
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
*
|
|
* @param {JSON} data
|
|
* @param {Boolean} csrf
|
|
* @returns {FormData}
|
|
*/
|
|
export function preparePostData(data: Object, csrf: Boolean=true) {
|
|
|
|
let form: FormData = new FormData();
|
|
|
|
if (csrf) {
|
|
let csrfToken = getCookie('csrftoken');
|
|
if (!csrfToken) csrfToken = (<HTMLInputElement>document.querySelector("input[name='csrfmiddlewaretoken']")).value;
|
|
form.append("csrfmiddlewaretoken", csrfToken);
|
|
}
|
|
|
|
Object.keys(data).map(key => form.append(key, data[key]));
|
|
|
|
return form
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
*
|
|
* @returns {XMLHttpRequest}
|
|
* @throws TypeError - AJAX request is not supported.
|
|
*/
|
|
function AJAXRequest () : XMLHttpRequest {
|
|
|
|
// Chrome, Firefox, IE7+, Opera, Safari
|
|
// and everything else that has come post 2010.
|
|
if ("XMLHttpRequest" in window) return new XMLHttpRequest();
|
|
|
|
|
|
// ToDo: Deprecate.
|
|
// Other IE versions (with all their glories).
|
|
// Microsoft.XMLHTTP points to Msxml2.XMLHTTP and is
|
|
// redundant - but you never know with Microsoft.
|
|
try {
|
|
return new ActiveXObject("Msxml2.XMLHTTP.6.0")
|
|
} catch (e) {}
|
|
|
|
try {
|
|
return new ActiveXObject("Msxml2.XMLHTTP.3.0")
|
|
} catch (e) {}
|
|
|
|
try {
|
|
return new ActiveXObject("Microsoft.XMLHTTP")
|
|
} catch (e) {}
|
|
|
|
// Just throw the computer outta the window!
|
|
alert("Your browser belongs to history!");
|
|
throw new TypeError("This browser does not support AJAX requests.")
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
* Handles AJAX POST requests.
|
|
*/
|
|
export class Request implements RequestBase {
|
|
|
|
public url;
|
|
public data;
|
|
private xhr: any = AJAXRequest();
|
|
|
|
/**
|
|
*
|
|
* @param url
|
|
* @param data
|
|
*/
|
|
constructor(url: string, data: FormData) {
|
|
|
|
this.url = url;
|
|
this.data = data;
|
|
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param event
|
|
*/
|
|
progress(event: any): void {
|
|
|
|
if (event.lengthComputable) {
|
|
// TODO: Show only when debug is on
|
|
// console.log((event.loaded / event.total) * 100 + '% uploaded');
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param response
|
|
*/
|
|
error(response: any): void {
|
|
|
|
console.error(response)
|
|
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param response
|
|
*/
|
|
success(response: any): void {
|
|
|
|
console.info(response)
|
|
|
|
}
|
|
|
|
/**
|
|
*
|
|
*/
|
|
send (): void {
|
|
|
|
const SUCCESS: any = this.success,
|
|
ERROR: any = this.error,
|
|
PROGRESS: any = this.progress;
|
|
|
|
this.xhr.open('POST', this.url, true);
|
|
this.xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
|
|
|
|
this.xhr.upload.onprogress = (event: any) => PROGRESS(event);
|
|
|
|
this.xhr.onerror = (event: any): void => {
|
|
|
|
ERROR(this.xhr.responseText)
|
|
|
|
};
|
|
|
|
this.xhr.onload = (event: any): void => {
|
|
|
|
let data: any = null;
|
|
|
|
if (this.xhr.readyState == XMLHttpRequest.DONE) {
|
|
|
|
if (!this.xhr.responseType || this.xhr.responseType === "text") {
|
|
|
|
data = this.xhr.responseText
|
|
|
|
} else if (this.xhr.responseType === "document") {
|
|
|
|
data = this.xhr.responseXML
|
|
|
|
} else {
|
|
|
|
data = this.xhr.response
|
|
|
|
}
|
|
|
|
}
|
|
|
|
SUCCESS(data)
|
|
|
|
};
|
|
|
|
this.xhr.send(this.data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
*
|
|
* @param {Element} element
|
|
* @param {string} type
|
|
*/
|
|
export function triggerEvent(element: Element, type: string): void {
|
|
|
|
// modern browsers, IE9+
|
|
let event = document.createEvent('HTMLEvents');
|
|
event.initEvent(type, false, true);
|
|
element.dispatchEvent(event);
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
*
|
|
* @param {string} type
|
|
* @param {Element | Document} element
|
|
* @param {any} args
|
|
*/
|
|
export function triggerCustomEvent(type:string, element: Element | Document=document, args: any=null){
|
|
|
|
// modern browsers, IE9+
|
|
const event = new CustomEvent(type, {'detail': args});
|
|
element.dispatchEvent(event);
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
*
|
|
* @param {Element} element
|
|
* @param {string[]} className
|
|
*/
|
|
export function addClass (element: Element, ...className: string[]): void {
|
|
|
|
className.map(cname => {
|
|
|
|
if (element.classList)
|
|
element.classList.add(cname);
|
|
|
|
else {
|
|
let classes: string[] = element.className.split(' ');
|
|
|
|
if (classes.indexOf(cname) < 0) classes.push(cname);
|
|
|
|
element.className = classes.join(' ')
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
*
|
|
* @param {Element} element
|
|
* @param {string[]} className
|
|
*/
|
|
export function removeClass (element: Element, ...className: string[]): void {
|
|
|
|
className.map(cname => {
|
|
|
|
if (element.classList)
|
|
element.classList.remove(cname);
|
|
|
|
else {
|
|
let classes: string[] = element.className.split(' '),
|
|
idx: number = classes.indexOf(cname);
|
|
|
|
if (idx > -1) classes.splice(idx, 1);
|
|
|
|
element.className = classes.join(' ')
|
|
}
|
|
|
|
})
|
|
|
|
}
|