// TODO: This file was created by bulk-decaffeinate.
// Sanity-check the conversion and remove this comment.
/*
* decaffeinate suggestions:
* DS001: Remove Babel/TypeScript constructor workaround
* DS101: Remove unnecessary use of Array.from
* DS102: Remove unnecessary code created because of implicit returns
* DS103: Rewrite code to no longer use __guard__
* DS205: Consider reworking code to avoid use of IIFEs
* DS206: Consider reworking classes to avoid initClass
* DS207: Consider shorter variations of null checks
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
var $;
$ = jQuery;
window.$su = $;
Array.prototype.unique = function () {
return this.reduce(function (acc, value) {
if (!acc.includes(value)) {
acc.push(value);
}
return acc;
}, []);
};
Array.prototype.merge = function (other) {
return Array.prototype.push.apply(this, other);
};
//http://stackoverflow.com/a/4026828/375490
Array.prototype.diff = function (a) {
return this.filter((i) => !(a.indexOf(i) > -1));
};
String.prototype.toBoolean = function () {
switch (this.toLowerCase()) {
case "true":
case "yes":
case "1":
return true;
case "false":
case "no":
case "0":
return false;
default:
throw "can't convert string to boolean. Unknown string: " + this;
}
};
Function.prototype.delay = function (delay) {
let timeout = null;
return (...args) => {
if (timeout !== null) {
clearTimeout(timeout);
}
var current_timeout = (timeout = setTimeout(() => {
current_timeout = timeout = null;
return this(...Array.from(args || []));
}, delay));
return function () {
if (current_timeout !== null) {
return clearTimeout(current_timeout);
}
};
};
};
Function.prototype.fix = function () {
let f;
return (f = (...args) => this(f, ...Array.from(args)));
};
Function.prototype.curry = function (...args) {
return (...args2) => this(...Array.from(args), ...Array.from(args2));
};
Function.prototype.lazy = function () {
return (...args) => (args.length === 0 ? this() : this.curry(...Array.from(args || [])).lazy());
};
Function.prototype.unlazy = function () {
return (...args) => (args.length === 0 ? this() : this(...Array.from(args || []))());
};
Function.prototype.composition = function (func) {
return (...args) => this(func(...Array.from(args || [])));
};
$.fn.getClasses = function () {
const class_list = {};
for (let element of Array.from(this)) {
const element_class_list = __guard__($(element).attr("class"), (x) => x.split(/\s+/));
if (element_class_list != null) {
for (let class_name of Array.from(element_class_list)) {
class_list[class_name] = null;
}
}
}
return Object.keys(class_list);
};
//http://su.localhost/chaplain/application/type/2
//serialize form elements into json array
$.fn.serializeJSON = function () {
const data = {};
$(this)
.serializeArray()
.forEach(function (field) {
let value;
if (field.name.indexOf("[]") !== -1) {
const key = field.name.substr(0, field.name.length - 2);
value = data[key] != null ? data[key] : [];
value.push(field.value);
return (data[key] = value);
} else {
return (data[field.name] = field.value);
}
});
return data;
};
$(() => SF.init());
var SF = (window.SF = {});
SF.load = {};
SF.load.loaded_prettify = false;
SF.load.prettify = function (callback) {
if (SF.load.loaded_prettify) {
callback();
return;
}
SF.load.loaded_prettify = true;
$("head").append('');
return $.ajax({
url: "third-party/Bootstrap/docs/assets/js/google-code-prettify/prettify.js",
dataType: "script",
async: true,
cache: true,
success() {
return callback();
},
});
};
SF.init = function ($selector = null) {
const has_selector = !!$selector;
if (!has_selector) {
$selector = $("html");
}
const has_bootstrap = has_selector && $selector.closest(".su_bootstrap_safe").length > 0;
document.createElement("picture");
$selector.find("select:not(.no-select2)").each(function () {
hasNoValue = $(this).find("option[selected]").length == 0;
if ($(this).attr("data-placeholder") && !$(this).prop("multiple")) {
const option = hasNoValue ? "" : "";
$(this).prepend(option);
}
$(this).select2({
theme: "bootstrap",
width: "100%",
});
});
if ($selector.find("pre.prettyprint, code.prettyprint, xmp.prettyprint").length) {
SF.load.prettify(() => prettyPrint());
}
if ($.fn.tooltip) {
$selector.find(has_bootstrap ? "a[rel=tooltip]" : ".su_bootstrap_safe a[rel=tooltip]").tooltip({
live: true,
});
}
if ($.fn.popover) {
$.fn.popover.Constructor.DEFAULTS = $.extend({}, $.fn.popover.Constructor.DEFAULTS, {
trigger: "hover",
});
$selector.find(has_bootstrap ? "a[rel=popover]" : ".su_bootstrap_safe a[rel=popover]").popover({
offset: 10,
});
}
if ($.fn.suAjaxForm) {
$("form.su-base-ajax-form").each(function () {
return $(this).suAjaxForm();
});
}
if ($.fn.suToggleDisplay) {
$(".su-base-toggle-display").suToggleDisplay();
}
if ($.fn.suAction) {
$("body .su-base-action[data-action]").each(function () {
return $(this).suAction();
});
}
if ($.fn.bootstrapSwitch) {
$(".switch").bootstrapSwitch();
}
const syncCheckBox = function () {
return $(this).parents(".add-on").toggleClass("active", $(this).is(":checked"));
};
$selector
.find(has_bootstrap ? ".add-on :checkbox" : ".su_bootstrap_safe .add-on :checkbox")
.each(syncCheckBox)
.click(syncCheckBox);
$selector.off("click.su.modal");
$selector.on("click.su.modal", "a[data-controller-modal]", function () {
const stackable = $(this).is("[data-controller-modal-stackable]");
const center = $(this).is("[data-controller-modal-center]");
SF.modal.controller(SF.html.fixUrl($(this).attr("href")), stackable, center);
return false;
});
$selector.on("blur", ".sf_validate_currency", function () {
const $this = $(this);
return $this.val(parseFloat($this.val()).toFixed(2));
});
if (typeof filepicker !== "undefined" && filepicker !== null) {
$selector.find("input[type='filepicker'], input[type='filepicker-dragdrop'], input[type='filepicker-convert']").each(function () {
return filepicker.constructWidget(this);
});
}
//determine navbar-fixed-top
if (!has_selector) {
const setNavBarMargin = () => $("html").css("marginTop", SF.admin.toolbar.marginNeeded());
setNavBarMargin();
//scrollspy for non-fixed navbars
const navbar = $(".navbar.navbar-scroll-by-fixed:not(.navbar-fixed-top):first");
if (navbar.length > 0) {
const nav_top = navbar.offset().top - SF.admin.toolbar.marginNeeded();
const $win = $(window);
let is_fixed = false;
$win.on("scroll", function () {
const scroll_top = $win.scrollTop();
if (scroll_top >= nav_top && !is_fixed) {
is_fixed = true;
navbar.addClass("navbar-fixed-top");
return setNavBarMargin();
} else if (scroll_top <= nav_top && is_fixed) {
is_fixed = false;
navbar.removeClass("navbar-fixed-top");
return setNavBarMargin();
}
});
}
$(window).resize(() => setNavBarMargin());
}
if ($.fn.modal) {
$.fn.modal.Constructor.prototype.enforceFocus = function () {};
}
// Ensure links open in _parent (from {
const result = [];
for (let value of Array.from(data_array)) {
const new_prototype = prototype.clone(true);
closure(new_prototype, value);
new_prototype.removeClass("su_prototype").addClass("__su_prototype_child");
if (reverse) {
result.push(prototype.after(new_prototype));
} else {
result.push(prototype.before(new_prototype));
}
}
return result;
})();
} else {
return (() => {
const result1 = [];
for (let key in data_array) {
const value = data_array[key];
const new_prototype = prototype.clone(true);
closure(new_prototype, value, key);
new_prototype.removeClass("su_prototype").addClass("__su_prototype_child");
if (reverse) {
result1.push(prototype.after(new_prototype));
} else {
result1.push(prototype.before(new_prototype));
}
}
return result1;
})();
}
};
SF.proto.prepend = (prototype, data_array, closure) => SF.proto.build(prototype, data_array, closure, false, true);
SF.proto.append = (prototype, data_array, closure) => SF.proto.build(prototype, data_array, closure, false, false);
SF.proto.defaultClosure = (prototype, data) =>
(() => {
const result = [];
for (let key in data) {
const value = data[key];
if (key === "id") {
prototype.attr("data-id", value);
}
const target = $(`.su_prototype_${key}`, prototype);
if (!target.length) {
throw `bad data ${key}: ${value}`;
}
if (target.get(0).tagName === "img") {
result.push(target.attr("src", value));
} else if (target.get(0).tagName === "A") {
result.push(target.attr("href", target.attr("href") + value));
} else {
result.push(target.text(value));
}
}
return result;
})();
let Cls = (SF.macro = class macro {
static initClass() {
this.prototype.state = {};
}
constructor(selector, trigger_closure) {
this.setStateWithTrigger = this.setStateWithTrigger.bind(this);
if (trigger_closure == null) {
trigger_closure = function () {};
}
this.trigger_closure = trigger_closure;
if (!selector.hasClass(this.selectorClass())) {
console.warn(`Bad selector for macro class ${this.selectorClass()}`);
}
this.selector = () => selector;
const subselector_cache = {};
this.subselector = function (subselector) {
if (!Array.from(subselector_cache).includes(subselector)) {
subselector_cache[subselector] = $(subselector, this.selector());
}
return subselector_cache[subselector];
};
}
selectorClass() {
return "su_macro";
}
setState(state_) {
const should_update = JSON.stringify(state_) !== JSON.stringify(this.state);
if (should_update) {
this.state = state_;
}
return should_update;
}
updateState(state_delta) {
return this.setState($.extend({}, this.state, state_delta));
}
setStateWithTrigger(state) {
if (this.setState(state)) {
return this.trigger_closure(state);
}
}
});
Cls.initClass();
SF.macro.proto = class proto extends SF.macro {
constructor(selector, build_closure) {
super(selector, function () {});
if (build_closure == null) {
build_closure = SF.proto.defaultClosure;
}
this.build_closure = build_closure;
}
selectorClass() {
return "su_macro_prototype";
}
clear() {
return this.getChildren().remove();
}
build(data) {
const new_prototype = this.subselector("> .su_prototype").clone(true);
this.build_closure(new_prototype, data);
new_prototype.removeClass("su_prototype").addClass("__su_prototype_child");
return new_prototype;
}
fromArray(data_array, is_hidden) {
if (is_hidden == null) {
is_hidden = false;
}
this.clear();
return this.appendArray(data_array, is_hidden);
}
prepend(data, is_hidden) {
if (is_hidden == null) {
is_hidden = false;
}
const object = this.build(data);
if (is_hidden) {
object.hide();
}
object.prependTo(this.selector());
return object;
}
prependArray(data_array, is_hidden) {
if (is_hidden == null) {
is_hidden = false;
}
return Array.from(data_array.reverse()).map((data) => this.prepend(data, is_hidden));
}
append(data, is_hidden) {
if (is_hidden == null) {
is_hidden = false;
}
const object = this.build(data);
if (is_hidden) {
object.hide();
}
object.appendTo(this.selector());
return object;
}
appendArray(data_array, is_hidden) {
if (is_hidden == null) {
is_hidden = false;
}
return Array.from(data_array).map((data) => this.append(data, is_hidden));
}
getChildren() {
return this.selector().children(".__su_prototype_child");
}
};
(function () {
let timeout = undefined;
Cls = SF.macro.suggest = class suggest extends SF.macro {
static initClass() {
timeout = null;
}
constructor(selector, input_selector, suggest_url, suggest_build_closure, onSelection) {
super(selector, function () {});
this.hide = this.hide.bind(this);
this.input_selector = input_selector;
this.suggest_url = suggest_url;
this.suggest_build_closure = suggest_build_closure;
this.onSelection = onSelection;
this.selector().find(".typeahead").show();
const that = this;
this.prototype_macro = new SF.macro.proto(this.subselector(".su_macro_prototype"), function (prototype, data) {
prototype.attr("data-id", data.Id);
if (that.suggest_build_closure) {
return that.suggest_build_closure(prototype, data);
} else {
return prototype.find(".name").text(data.Name);
}
});
this.input_selector.blur(() => {
return setTimeout(this.hide, 250);
});
const _this = this;
this.subselector(".su_prototype").click(function (e) {
e.preventDefault();
return _this.suggestionSelected($(this));
});
}
selectorClass() {
return "su_macro_suggestion";
}
suggestionSelected(val) {
this.input_selector.val("");
this.hide();
if (this.onSelection) {
this.onSelection(val);
}
return this.input_selector.focus();
}
setSuggestions(term) {
return () => {
return SF.action.post(this.suggest_url, { term }, (data) => {
this.prototype_macro.fromArray(data.results);
return this.selector().toggle(data.results.length > 0);
});
};
}
setDelayedSuggestions(term) {
if (timeout) {
clearTimeout(timeout);
}
return (timeout = setTimeout(this.setSuggestions(term), 200));
}
hide() {
return this.selector().hide();
}
};
Cls.initClass();
return Cls;
})();
SF.macro.pagination = {};
SF.macro.pagination.basic = class basic extends SF.macro {
constructor(...args) {
super(...Array.from(args || []));
this.setState = this.setState.bind(this);
this.setState({
page: null,
page_max: null,
});
}
selectorClass() {
return "su_macro_pagination";
}
setState(state) {
let page, page_max, selector;
let enabled, target_page;
if (!super.setState(({ page, page_max } = state))) {
return false;
}
//next/prev page
for ({ target_page, selector, enabled } of [
{ target_page: page - 1, selector: this.subselector(".su_prev"), enabled: page > 1 },
{ target_page: page + 1, selector: this.subselector(".su_next"), enabled: page < page_max },
]) {
selector.unbind("click");
SF.html.setEnabledState(selector.parent("li"), enabled);
if (enabled) {
((target_page) => {
return selector.click(() =>
this.setStateWithTrigger({
page: target_page,
page_max,
})
);
})(target_page);
}
}
//page list
if (page_max === 0) {
page_max = 1;
}
let first_page = 1;
let last_page = page_max;
if (page_max > 11) {
// we can't show all of them
if (page >= page_max - 5) {
first_page = page_max - 11;
} else if (page - 5 > 0) {
first_page = page - 5;
} else {
first_page = 1;
}
last_page = page < 6 ? 10 : first_page + 11;
}
SF.proto.build(this.subselector(".su_prototype"), __range__(first_page, last_page, true), (prototype, page_) => {
const link = $("a", prototype);
link.text(page_);
if (page_ === page) {
link.parent("li").addClass("active");
}
return link.click(() => {
return this.setStateWithTrigger({
page: page_,
page_max,
});
});
});
this.selector().toggle(page_max !== 1);
return true;
}
};
SF.macro.pagination.public = class basic extends SF.macro {
constructor(...args) {
super(...Array.from(args || []));
this.setState = this.setState.bind(this);
this.setState({
page: null,
page_max: null,
});
}
selectorClass() {
return "su__pagination";
}
setState(state) {
let page, page_max, selector;
let enabled, target_page;
if (!super.setState(({ page, page_max } = state))) {
return false;
}
//next/prev page
for ({ target_page, selector, enabled } of [
{ target_page: page - 1, selector: this.subselector(".su__pagination__prev"), enabled: page > 1 },
{ target_page: page + 1, selector: this.subselector(".su__pagination__next"), enabled: page < page_max },
]) {
selector.unbind("click");
selector.toggleClass("disabled", !enabled);
if (enabled) {
((target_page) => {
return selector.click(() =>
this.setStateWithTrigger({
page: target_page,
page_max,
})
);
})(target_page);
}
}
//page list
if (page_max === 0) {
page_max = 1;
}
let first_page = 1;
let last_page = page_max;
if (page_max > 11) {
// we can't show all of them
if (page >= page_max - 5) {
first_page = page_max - 11;
} else if (page - 5 > 0) {
first_page = page - 5;
} else {
first_page = 1;
}
last_page = page < 6 ? 10 : first_page + 11;
}
SF.proto.build(this.subselector(".su_prototype"), __range__(first_page, last_page, true), (prototype, page_) => {
prototype.text(page_);
prototype.toggleClass("active", page_ === page);
return prototype.click(() => {
return this.setStateWithTrigger({
page: page_,
page_max,
});
});
});
this.selector().toggle(page_max !== 1);
return true;
}
};
SF.macro.sortby = class sortby extends SF.macro {
constructor(...args) {
super(...Array.from(args || []));
this.setState = this.setState.bind(this);
this.subselector(".su__sortby__option").click(({ target }) => {
const should_ascending = $(target).hasClass("su__sortby__option--desc") || !$(target).hasClass("su__sortby__option--asc");
const key = $(target).attr("data-key");
return this.setStateWithTrigger({
key,
is_ascending: should_ascending,
});
});
true;
}
selectorClass() {
return "su_macro_sortby";
}
setState(state) {
let is_ascending, key;
if (!super.setState(({ key, is_ascending } = state))) {
return false;
}
const class_to_add = is_ascending ? "su__sortby__option--asc" : "su__sortby__option--desc";
this.subselector(".su__sortby__option").removeClass("su__sortby__option--asc su__sortby__option--desc").filter(`[data-key='${key}']`).addClass(class_to_add);
return true;
}
};
SF.macro.sortby_table = class sortby extends SF.macro {
constructor(...args) {
super(...Array.from(args || []));
this.setState = this.setState.bind(this);
this.subselector(".su_macro_sortby_type a").click((eventObject) => {
const clicked_type = $(eventObject.target).closest(".su_macro_sortby_type");
const should_ascending = clicked_type.hasClass("su_selected_descending") || !clicked_type.hasClass("su_selected_ascending");
const key = clicked_type.attr("data-key");
return this.setStateWithTrigger({
key,
is_ascending: should_ascending,
});
});
true;
}
selectorClass() {
return "su_macro_sortby";
}
setState(state) {
let is_ascending, key;
if (!super.setState(({ key, is_ascending } = state))) {
return false;
}
const class_to_add = is_ascending ? "su_selected_ascending" : "su_selected_descending";
this.subselector(".su_macro_sortby_type").removeClass("su_selected_ascending su_selected_descending").filter(`[data-key='${key}']`).addClass(class_to_add);
return true;
}
};
SF.macro.search = class search extends SF.macro {
constructor(selector, trigger_closure) {
super(selector, trigger_closure);
this.setState = this.setState.bind(this);
let cancel_closure = null;
const updateWithValue = (value) => {
return this.setStateWithTrigger({
value,
});
};
const delayedUpdateWithValue = updateWithValue.delay(250);
selector.keyup(function (event_object) {
//enter, shift, control, option, capslock, 4 arrows, command, command
if (![13, 16, 17, 18, 20, 37, 38, 39, 40, 91, 93].includes(event_object.which)) {
return (cancel_closure = delayedUpdateWithValue(selector.val()));
}
});
selector.keydown(function (event_object) {
if (cancel_closure !== null) {
cancel_closure();
}
if (event_object.which === 13) {
return updateWithValue(selector.val());
}
});
this.selector()
.siblings(".su-clear-search")
.click(function () {
if (cancel_closure !== null) {
cancel_closure();
}
return updateWithValue("");
});
this.setState({
value: "",
});
}
selectorClass() {
return "su_macro_search";
}
setState(state) {
let value;
this.selector()
.siblings(".su-clear-search")
.toggle(state.value.length > 0);
this.selector()
.siblings(".su-search-icon")
.toggle(state.value.length === 0);
if (!super.setState(({ value } = state))) {
return false;
}
this.selector().val(value);
return true;
}
};
SF.macro.html = {};
SF.macro.html.tags = class tags extends SF.macro {
constructor(selector, trigger_closure, suggest_url, suggest_proto_closure, is_case_sensitive) {
super(selector, trigger_closure);
this.addTagFromInput = this.addTagFromInput.bind(this);
this.setInitTags = this.setInitTags.bind(this);
this.inArray = this.inArray.bind(this);
this.suggest_url = suggest_url;
this.suggest_proto_closure = suggest_proto_closure;
if (is_case_sensitive == null) {
is_case_sensitive = false;
}
this.is_case_sensitive = is_case_sensitive;
this.setState({
added_tags: [],
removed_tags: [],
init_tags: [],
});
if (this.suggest_url) {
this.suggest = new SF.macro.suggest(this.subselector(".su_macro_suggestion"), this.subselector("input.su_tag_input"), this.suggest_url, this.suggest_proto_closure, ($tag) => {
this.addTag($tag.text());
if (this.suggest) {
return this.suggest.setDelayedSuggestions();
}
});
}
//make sure enter doesn't submit form
this.selector()
.closest("form")
.find("input")
.keypress(function (e) {
switch (e.keyCode) {
case 13:
return false;
default:
return true;
}
});
const _this = this;
this.subselector(".su_post_tag .su_delete_tag").click(function () {
const tag = $(this).closest(".su_post_tag").attr("data-tag");
return _this.deleteTag(tag);
});
let backspace_event_enabled = true;
this.subselector("input.su_tag_input").keydown((e) => {
if (e.keyCode === 188) {
return false;
} // comma
backspace_event_enabled = this.subselector("input.su_tag_input").val().length === 0;
return true;
});
this.subselector("input.su_tag_input").keyup((e) => {
let tag = this.subselector("input.su_tag_input").val();
switch (e.keyCode) {
case 13:
case 32: //enter & space
this.addTagFromInput();
if (this.suggest) {
this.suggest.setDelayedSuggestions();
}
break;
case 27:
if (this.suggest) {
this.suggest.hide();
}
break;
case 8: //backspace
if (backspace_event_enabled) {
tag = this.subselector(".su_post_tag:not(.su_prototype)").last().attr("data-tag");
this.deleteTag(tag);
this.subselector("input.su_tag_input").val(tag);
}
if (this.suggest) {
this.suggest.setDelayedSuggestions(tag);
}
break;
default:
if (this.suggest) {
this.suggest.setDelayedSuggestions(tag);
}
}
return true;
});
this.subselector("input.su_tag_input").focus(() => {
if (this.suggest) {
this.suggest.setSuggestions()();
}
return this.selector().addClass("active");
});
const make_inactive = () => {
if (!this.subselector("input.su_tag_input").is(":focus")) {
return this.selector().removeClass("active");
}
};
this.subselector("input.su_tag_input").blur(() => {
setTimeout(this.addTagFromInput, 250);
return setTimeout(make_inactive, 250);
});
this.selector().click(() => {
return this.subselector("input.su_tag_input").focus();
});
}
selectorClass() {
return "su_macro_html_tags";
}
getTags() {
let added_tags, removed_tags;
return ({ added_tags, removed_tags } = this.state);
}
getCurrentTags() {
let tags = this.state.init_tags;
tags = tags.diff(this.state.removed_tags);
tags.merge(this.state.added_tags);
return tags;
}
addTag(tag, add_to_state) {
if (add_to_state == null) {
add_to_state = true;
}
tag = $.trim(tag);
if (tag === "" || this.inArray(tag, this.state.added_tags)) {
return;
}
if (this.subselector(`.su_post_tag[data-tag='${tag}']`).length > 0) {
return;
}
const prototype = this.subselector(".su_post_tag.su_prototype");
const new_proto = prototype.clone(true);
new_proto.removeClass("su_prototype");
new_proto.attr("data-tag", tag);
new_proto.find(".su_tag").text(tag);
prototype.before(new_proto);
if (this.suggest) {
this.suggest.hide();
}
if (add_to_state) {
if (this.inArray(tag, this.state.removed_tags)) {
return this.state.removed_tags.splice(this.state.removed_tags.indexOf(tag), 1);
} else {
if (!this.inArray(tag, this.state.init_tags)) {
return this.state.added_tags.push(tag);
}
}
}
}
addTagFromInput() {
const words = this.subselector("input.su_tag_input").val().split(" ");
for (let word of Array.from(words)) {
this.addTag(word);
}
return this.subselector("input.su_tag_input").val("");
}
deleteTag(tag) {
if ($.trim(tag).length === 0) {
return;
}
if (this.inArray(tag, this.state.added_tags)) {
this.state.added_tags.splice(this.state.added_tags.indexOf(tag), 1);
} else {
if (!this.inArray(tag, this.state.removed_tags)) {
this.state.removed_tags.push(tag);
}
}
return this.subselector(`.su_post_tag[data-tag='${tag}']`).remove();
}
setInitTags(tags) {
this.clearTags();
for (let tag of Array.from(tags)) {
this.addTag(tag, false);
}
return (this.state.init_tags = tags);
}
refreshInitTags() {
return this.setInitTags(this.getCurrentTags);
}
clearTags() {
this.updateState({
added_tags: [],
removed_tags: [],
});
return this.subselector(".su_post_tag:not(.su_prototype)").remove();
}
inArray(value, array) {
let item;
if (this.is_case_sensitive) {
for (item of Array.from(array)) {
if (value === item) {
return true;
}
}
} else {
for (item of Array.from(array)) {
if (value.toLowerCase() === item.toLowerCase()) {
return true;
}
}
}
return false;
}
setState(state) {
let added_tags, removed_tags;
if (!super.setState(({ added_tags, removed_tags } = state))) {
return false;
}
return true;
}
};
SF.macro.form = {};
// Form Steps macro (used for doing forms a piece at a time when it's all on one page)
SF.macro.form.steps = class steps extends SF.macro {
constructor(selector, continue_closure, back_closure, header_closure, animate, add_review_step) {
super(selector, function () {});
this.setState = this.setState.bind(this);
if (animate == null) {
animate = true;
}
this.animate = animate;
if (add_review_step == null) {
add_review_step = true;
}
this.add_review_step = add_review_step;
const $steps = this.subselector(".su_macro_form_step");
if (!$steps.length) {
throw "no steps with class of su_macro_form_step found";
}
let step = 1;
let _this = this;
$steps.each(function () {
$(this).attr("data-step", step++);
if (_this.animate) {
return $(this).addClass("fade");
}
});
this.btn_continue = this.subselector(".su_macro_form_step_continue");
if (!this.btn_continue.length) {
throw "missing continue button of class su_macro_form_step_continue";
}
this.btn_back = this.subselector(".su_macro_form_step_back");
if (!this.btn_back.length) {
throw "missing continue button of class su_macro_form_step_back";
}
this.btn_continue.click(() => {
if (continue_closure) {
return continue_closure(this.state);
}
//default action
return this.updateState({
step: this.state.step + 1,
});
});
this.btn_back.click(() => {
if (back_closure) {
return back_closure(this.state);
}
//default action
return this.updateState({
step: this.state.step - 1,
});
});
//max step
const step_max = this.add_review_step ? $steps.size() + 1 : $steps.size();
//add headers
let tmp_step = 1;
this.step_headers = $("
");
while (tmp_step <= step_max) {
let title = this.getStep(tmp_step).attr("data-step-title");
if (this.add_review_step && tmp_step === step_max) {
title = "Review & Finalize";
}
let header = `${tmp_step}`;
if (title) {
header += ". " + title;
}
var $header = $(``);
const closure = (step_clicked) => {
_this = this;
return $header.click(function () {
if (header_closure) {
return header_closure(step_clicked, _this.state);
}
return _this.updateState({
step: step_clicked,
});
});
};
closure(tmp_step);
this.step_headers.append($header);
tmp_step++;
}
this.selector().prepend(this.step_headers);
//end headers
//set state
this.setState({
step: 1,
step_max,
completed: [],
});
}
selectorClass() {
return "su_macro_form_steps";
}
getStep(step) {
if (step === this.state.step_max && this.add_review_step) {
return this.subselector(".su_macro_form_step");
} else {
return this.subselector(`.su_macro_form_step[data-step='${step}']`);
}
}
getStepHeader(step) {
return this.subselector(`.su_macro_form_steps_header_item[data-step='${step}']`);
}
completedStep(step) {
const { completed } = this.state;
completed.push(step);
return this.updateState({
completed,
});
}
setState(state) {
let completed, step, step_max;
if (state.step < 1) {
state.step = 1;
}
if (state.step > state.step_max) {
state.step = state.step_max;
}
if (!super.setState(({ step, step_max, completed } = state))) {
return false;
}
//show/hide buttons
this.btn_back.toggle(step > 1);
this.btn_continue.text(step === step_max ? this.btn_continue.attr("data-text-finalize") : this.btn_continue.attr("data-text-continue"));
//steps
const $step = this.getStep(step);
if (!$step.length) {
throw `no step for ${step}`;
}
const $steps = $(".su_macro_form_step");
$steps.hide();
if (this.animate) {
$steps.removeClass("in");
}
$step.show();
if (this.animate) {
(() => $step.addClass("in")).delay(100)();
}
//step headers
this.step_headers.find("> li").removeClass("su-step-active su-step-complete su-step-incomplete");
const $step_header = this.getStepHeader(step);
$step_header.addClass("su-step-active");
let tmp_step = 1;
return (() => {
const result = [];
while (tmp_step <= step_max) {
this.getStepHeader(tmp_step).addClass(Array.from(completed).includes(tmp_step) ? "su-step-complete" : "su-step-incomplete");
result.push(tmp_step++);
}
return result;
})();
}
};
SF.html = {};
SF.html.setEnabledState = (obj, is_enabled) => obj.toggleClass("disabled", !is_enabled);
SF.html.fixUrl = function (url) {
if (!/^(https?:)?\/\//.test(url)) {
if (url.substring(0, 1) === "/") {
url = url.substring(1);
}
url = window.SF_BASE_PATH + url;
}
return url;
};
SF.html.truncate = function (obj, original_text, truncate_length) {
if (original_text.length > truncate_length) {
obj.text(original_text.substring(0, truncate_length) + "...");
return obj.attr("title", original_text);
} else {
return obj.text(original_text);
}
};
SF.html.reload = function (params = null) {
if (params) {
let key, param, value;
if (params.charAt(0) === "?") {
params = params.substring(1);
}
let query = window.location.search;
const query_state = {};
if (query.charAt(0) === "?") {
query = query.substring(1);
}
for (param of Array.from(query.split("&"))) {
[key, value] = Array.from(param.split("="));
query_state[key] = value;
}
params = params.split("&");
for (param of Array.from(params)) {
[key, value] = Array.from(param.split("="));
if (!(value.length > 0)) {
throw "param needs a value of format key=value";
}
query_state[key] = value;
}
params = [];
for (key in query_state) {
value = query_state[key];
params.push(`${key}=${value}`);
}
return (window.location.search = "?" + params.join("&"));
} else {
return window.location.reload();
}
};
SF.html.redirect = function (href) {
window.location.href = SF.html.fixUrl(href);
};
SF.html.toggle = {};
SF.html.toggle.checkbox = class checkbox {
constructor(toggle, selector, listener = null) {
this.toggle = toggle;
this.selector = selector;
this.toggle = $(this.toggle);
this.toggle.click(() => {
if (this.toggle.prop("checked") === true) {
this.checkAll();
} else {
this.uncheckAll();
}
if (listener) {
return listener();
}
});
$(document).on("click", this.selector, () => {
const checked_length = this.getChecked().length;
const are_all_checked = this.getAll().length === checked_length;
this.toggle.prop("checked", are_all_checked);
this.toggle.prop("indeterminate", !are_all_checked && checked_length);
if (listener) {
return listener();
}
});
}
getAll() {
return $(this.selector);
}
getChecked() {
return $(this.selector + ":checked");
}
checkAll() {
this.getAll().prop("checked", true).change();
return this.toggle.prop("checked", true);
}
uncheckAll() {
this.getAll().prop("checked", false).change();
this.toggle.prop("checked", false);
return this.toggle.prop("indeterminate", false);
}
};
SF.history = new (function () {
let should_use_persistent_history = true;
let is_init = false;
this.disablePersistentState = () => (should_use_persistent_history = false);
this.init = function (default_params) {
this.disablePersistentState = function () {
if (is_init) {
throw "history has already been init'ed";
}
};
if (!is_init) {
let stateChange, updateQuery;
should_use_persistent_history &= window.History.enabled;
const registered_params = {};
let current_query_pieces = {};
const stateChangeWithNewQueryState = function (query_state) {
let key, value;
const unprocessed_query_keys = (() => {
const result = [];
for (key in query_state) {
value = query_state[key];
if (value !== current_query_pieces[key]) {
result.push(key);
}
}
return result;
})().unique();
current_query_pieces = {};
for (key in query_state) {
value = query_state[key];
current_query_pieces[key] = decodeURIComponent((value + "").replace(/\+/g, "%20"));
}
const run_closures = [];
for (key of Array.from(unprocessed_query_keys)) {
if (registered_params[key]) {
for (let current_closure of Array.from(registered_params[key])) {
if (!Array.from(run_closures).includes(current_closure)) {
run_closures.push(current_closure);
}
}
}
}
return Array.from(run_closures).map((run_closure) => run_closure(current_query_pieces));
};
if (should_use_persistent_history) {
updateQuery = function (param_array) {
let key, value;
const function_name = Object.keys(current_query_pieces).length > 0 ? "pushState" : "replaceState";
window.History[function_name](
{},
"",
`${location.pathname}?` +
(() => {
const result = [];
for (key in param_array) {
value = param_array[key];
result.push(`${key}=${encodeURIComponent(value)}`);
}
return result;
})().join("&")
);
return parent.History[function_name](
{},
"",
`${location.pathname}?` +
(() => {
const result1 = [];
for (key in param_array) {
value = param_array[key];
if (key.substr(0, 1) !== "_") {
result1.push(`${key}=${encodeURIComponent(value)}`);
}
}
return result1;
})().join("&")
);
};
stateChange = function () {
const state = window.History.getState().hash;
const qindex = state.indexOf("?");
if (qindex === -1) {
updateQuery({});
return;
}
const query = state.substr(qindex + 1);
const query_state = {};
if (query !== "") {
for (let query_piece of Array.from(query.split("&"))) {
const [key, value] = Array.from(query_piece.split("="));
query_state[key] = value;
}
}
return stateChangeWithNewQueryState(query_state);
};
} else {
updateQuery = (query_state) => stateChangeWithNewQueryState($.extend({}, query_state));
}
this.get = () => $.extend({}, current_query_pieces);
this.getKey = (key) => current_query_pieces[key];
this.register = function (key_array, closure) {
const call_obj = {};
for (let key of Array.from(key_array)) {
call_obj[key] = current_query_pieces[key];
if (!registered_params[key]) {
registered_params[key] = [];
}
registered_params[key].push(closure);
}
return closure(call_obj);
};
this.unregister = (key_array) =>
(() => {
const result = [];
for (let key of Array.from(key_array)) {
if (registered_params[key]) {
result.push(delete registered_params[key]);
} else {
result.push(undefined);
}
}
return result;
})();
this.set = (key_value_map) => updateQuery($.extend({}, current_query_pieces, key_value_map));
this.unset = function (key) {
if (!this.isset(key)) {
throw "bad key " + key;
}
const new_query_pieces = $.extend({}, current_query_pieces);
delete new_query_pieces[key];
return updateQuery(new_query_pieces);
};
this.isset = (key) => current_query_pieces.hasOwnProperty(key);
if (should_use_persistent_history) {
$(window).bind("statechange", stateChange);
stateChange();
}
is_init = true;
} else {
// already init'd
this.unregister(Object.keys(default_params));
this.set($.extend({}, default_params));
}
return this.set($.extend({}, default_params, this.get()));
};
return this;
})();
SF.action = {};
SF.action.handle = (success_closure, error_closure, finally_closure) =>
function (data) {
if (!data.success) {
if (error_closure) {
error_closure(data.error);
} else {
if (data.error != null) {
alert(`${data.error.type}: ${data.error.message}`);
}
}
} else {
if (success_closure) {
success_closure(data);
}
}
if (finally_closure) {
finally_closure(data);
}
};
SF.action.get = (action, action_data, success_closure, error_closure) =>
$.ajax({
type: "GET",
url: action,
data: action_data,
success: SF.action.handle(success_closure, error_closure),
dataType: "json",
});
SF.action.post = (action, action_data, success_closure, error_closure) =>
$.ajax({
type: "POST",
url: action,
data: action_data,
success: SF.action.handle(success_closure, error_closure),
dataType: "json",
});
SF.bootstrap = {};
SF.bootstrap.alert = {};
SF.bootstrap.alert.basic = function (message, type) {
if (type == null) {
type = "danger";
}
const possible_types = ["danger", "warning", "success", "info"];
if (!Array.from(possible_types).includes(type)) {
throw `${type} not a valid type. Possible types are ${possible_types}`;
}
if (message.html) {
message = message.html();
}
//attribute "data-alert" from twitter/bootstrap gives a nice close animation automatically
const element = $(`${message}
`);
return element;
};
SF.bootstrap.alert.floating = function (message, type) {
let icon;
if (type == null) {
type = "danger";
}
const element = SF.bootstrap.alert.basic(message, type);
if ($("#alert-region").length === 0) {
$("body").prepend("");
}
if (type === "danger") {
icon = `\
\
`;
} else {
icon = `\
\
`;
}
$("#alert-region").append(element.prepend(icon));
element.delay(6000).fadeOut(1000);
return element;
};
SF.bootstrap.modal = {};
SF.bootstrap.modal.setSize = function (modal, width, height) {
const $modal_dialog = modal.find(".modal-dialog");
$modal_dialog.css({
"max-width": "100%",
width: width,
});
return () => console.log("unbind modal.setSize is deprecated");
};
SF.controller = {};
SF.controller.hide = function ($ele = null) {
SF.cache.refresh();
let $modal = [];
if ($ele != null) {
const $controller_embed = $ele.closest(".su-controller-embed");
if ($controller_embed.length) {
const target = $controller_embed.data("target");
const $parent = $controller_embed.parent();
$parent.hide() && $controller_embed.remove();
$(`[data-controller-embed][data-target='${target}']`).removeClass("active");
return;
}
$modal = $ele.closest(".modal");
}
if (!$modal.length) {
$modal = $("#su_controller_modal");
}
if ($modal.length) {
return $modal.modal("hide");
}
};
SF.modal = {};
SF.modal.controller = function (url, stackable, use_center, data) {
if (stackable == null) {
stackable = false;
}
if (use_center == null) {
use_center = false;
}
if (data == null) {
data = {};
}
if (window.NProgress != null) {
NProgress.start();
}
if (!stackable) {
$("#su_controller_modal").modal("hide");
}
const center_class = use_center ? " center" : "";
const modal_element = $(`\
\
`);
$("> .modal-dialog > .modal-content > .modal-header > .modal-title", modal_element).text("Loading");
modal_element.appendTo($("body"));
modal_element.modal("show");
let is_aborted = false;
data.template = "bare";
const request = $.ajax({
type: "POST",
url,
data,
error(jqXHR, textStatus, errorThrown) {
if (is_aborted) {
return;
}
if (jqXHR.status === 403) {
errorThrown = "You don't have permission to access this feature";
}
$("> .modal-dialog > .modal-content > .modal-body > .loading", modal_element).remove();
$("> .modal-dialog > .modal-content > .modal-header > .modal-title", modal_element).text("Error!");
$("> .modal-dialog > .modal-content > .modal-body", modal_element).append($("").text(errorThrown ? errorThrown : "No Response from Server"));
return modal_element.unbind("hidden.bs.modal").on("hidden.bs.modal", function () {
modal_element.remove();
if (window.NProgress != null) {
return NProgress.done();
}
});
},
success(data) {
let unbind_resize;
$("> .modal-dialog > .modal-content > .modal-body > .loading", modal_element).remove();
$("> .modal-dialog > .modal-content > .modal-footer", modal_element).removeClass("hidden");
const controller_element = $(data);
const modal_head_element = $($.trim(controller_element.attr("data-head")));
const body_scripts = $("script", controller_element).remove();
const bare_title = controller_element.attr("data-title");
const bare_icon = controller_element.attr("data-icon");
if (bare_title === "") {
throw "bare_title isn't set";
}
const modal_css = controller_element.attr("data-modal-css");
if (modal_css != null) {
const css_info = JSON.parse(modal_css);
unbind_resize = SF.bootstrap.modal.setSize(modal_element, css_info.width, css_info.height);
}
$("> .modal-dialog > .modal-content > .modal-header > .modal-title", modal_element).html(`${bare_title}`);
$("> .modal-dialog > .modal-content > .modal-body", modal_element).append(controller_element.children());
$("> .modal-dialog > .modal-content > .modal-footer", modal_element).append($($.trim(controller_element.attr("data-footer"))));
if (window.jQuery !== $) {
window.jQuery.noConflict(true);
}
const $head = $("head");
$head.append(modal_head_element);
$head.append(body_scripts);
SF.init(modal_element);
if (window.NProgress != null) {
NProgress.done();
}
return modal_element.unbind("hidden.bs.modal").on("hidden.bs.modal", function () {
$(controller_element.attr("data-head-exit")).appendTo($("head"));
modal_element.remove();
if (unbind_resize) {
unbind_resize();
}
SF.cache.refresh();
if (window.NProgress != null) {
return NProgress.done();
}
});
},
});
modal_element.on("hidden.bs.modal", function () {
is_aborted = true;
request.abort();
modal_element.remove();
if (window.NProgress != null) {
return NProgress.done();
}
});
return null;
};
SF.modal.progress = function (title, cancel_closure = null) {
let modal_element = $(`\
\
`);
if (cancel_closure != null) {
modal_element.on("hidden.cancel", cancel_closure);
} else {
modal_element.find(".close").hide();
modal_element.attr("data-keyboard", "false");
}
let current_percent = 0;
modal_element.on("hidden.close", function () {
modal_element.remove();
modal_element = null;
return (current_percent = null);
});
modal_element.modal("show");
this.set = function (percent) {
if (modal_element == null) {
return;
}
modal_element.find(".progress-bar").css("width", `${percent}%`);
current_percent = percent;
return null;
};
this.get = () => current_percent;
this.close = function () {
if (modal_element == null) {
return;
}
modal_element.off("hidden.cancel");
modal_element.modal("hide");
return null;
};
return this;
};
let cache_dirty_key_list = [];
const cache_closure_list = {};
let cache_closure_args = {};
SF.cache = {};
SF.cache.dirty = function (key, arg = null) {
if (!Array.from(cache_dirty_key_list).includes(key)) {
cache_dirty_key_list.push(key);
}
if (arg) {
if (cache_closure_args[key] == null) {
cache_closure_args[key] = [];
}
cache_closure_args[key] = arg;
}
return null;
};
SF.cache.registerHandle = function (key, closure) {
if (cache_closure_list[key] == null) {
cache_closure_list[key] = [];
}
cache_closure_list[key].push(closure);
return null;
};
SF.cache.unregisterHandles = function (key) {
cache_closure_list[key] = [];
return null;
};
SF.cache.refresh = function () {
for (let key of Array.from(cache_dirty_key_list)) {
if (cache_closure_list[key] != null) {
for (let cache_closure of Array.from(cache_closure_list[key])) {
if (cache_closure_args[key] != null) {
cache_closure(cache_closure_args[key]);
} else {
cache_closure();
}
}
}
}
cache_dirty_key_list = [];
cache_closure_args = {};
return null;
};
window.CKEDITOR_BASEPATH = SF.html.fixUrl("/third-party/CKEditor/");
SF.admin = {};
SF.admin.toolbar = {};
SF.admin.toolbar.marginNeeded = function () {
let margin_needed = 0;
$(".navbar-fixed-top:not(.dashboard-navbar)").each(function () {
if ($(this).css("position") === "fixed") {
$(this).css("marginTop", margin_needed);
return (margin_needed += $(this).outerHeight());
}
});
return margin_needed;
};
SF.admin.menu = {};
SF.admin.menu.expand = function () {
const $body = $("body");
if (!$body.hasClass("mobile-view")) {
return $body.removeClass("sb-l-m");
}
};
SF.admin.table = class table {
constructor(element, tableSource, sort_column, build_closure) {
this.update = this.update.bind(this);
this.element = element;
this.tableSource = tableSource;
if (build_closure == null) {
build_closure = function () {};
}
this.build_closure = build_closure;
this.inited = false;
this.prototypeSelector = "tbody tr.su_prototype";
this.sortbySelector = "#su-sortby";
this.setSortColumn(sort_column);
this.setSortDirection(1);
this.paginationSelector = "#su-pagination";
this.searchSelector = "#su-search";
this.resultsNumSelector = "#su-results-num";
this.historyKeyPrefix = "";
this.history_keys = {
page: 1,
search: "",
};
this.additional_request_data = {};
this.cacheHandle = "su-update-table";
this.update_closure = function () {};
}
init() {
let that = this;
const sortby = new SF.macro.sortby_table($(this.sortbySelector), ({ key, is_ascending }) =>
SF.history.set({
[that.prefixHistoryKey("page")]: 1,
[that.prefixHistoryKey("sort_by")]: key,
[that.prefixHistoryKey("is_ascending")]: +is_ascending,
})
);
this.pagination = new SF.macro.pagination.basic($(this.paginationSelector), ({ page }) =>
SF.history.set({
[that.prefixHistoryKey("page")]: page,
})
);
const search = new SF.macro.search($(this.searchSelector), ({ value }) =>
SF.history.set({
[that.prefixHistoryKey("search")]: value,
})
);
const history_keys = $.extend(this.getPrefixedHistory(), {
[that.prefixHistoryKey("sort_by")]: this.sort_column,
[that.prefixHistoryKey("is_ascending")]: this.sort_direction,
});
SF.history.init(history_keys);
SF.history.register([that.prefixHistoryKey("search")], (updated_params) =>
search.setState({
value: updated_params[that.prefixHistoryKey("search")],
})
);
this.sortable_columns = $(this.sortbySelector)
.find(".su_macro_sortby_type")
.map(function () {
return $(this).attr("data-key");
})
.get();
SF.history.register([that.prefixHistoryKey("sort_by"), that.prefixHistoryKey("is_ascending")], function () {
let { [that.prefixHistoryKey("sort_by")]: sort_by, [that.prefixHistoryKey("is_ascending")]: is_ascending } = SF.history.get();
if (!that.sortable_columns.includes(sort_by)) {
SF.history.set({
[that.prefixHistoryKey("sort_by")]: that.sort_column,
});
sort_by = that.sort_column;
}
sortby.setState({
key: sort_by,
is_ascending: Boolean(Number(is_ascending)),
});
});
SF.history.register(Object.keys(history_keys), this.update);
SF.cache.unregisterHandles(this.cacheHandle);
SF.cache.registerHandle(this.cacheHandle, this.update);
that = this;
$(document).keydown((e) => that.handleKeyPress(e, that));
const $pagination = this.pagination.selector();
const object = { "←": ".su_prev", "→": ".su_next" };
for (let arrow in object) {
const selector = object[arrow];
const $button = $pagination.find(selector);
$button.attr("data-toggle", "tooltip");
$button.attr("title", `Use ${arrow} key to navigate`);
}
return (this.inited = true);
}
addHistoryKeys(new_keys) {
return (this.history_keys = $.extend(this.history_keys, new_keys));
}
setPrototypeSelector(prototypeSelector) {
this.prototypeSelector = prototypeSelector;
return this.checkInit();
}
setSortSelector(sortbySelector) {
this.sortbySelector = sortbySelector;
return this.checkInit();
}
setSortColumn(sort_column) {
this.sort_column = sort_column;
return this.checkInit();
}
setSortDirection(direction) {
this.checkInit();
return (this.sort_direction = Number(direction));
}
setPaginationSelector(paginationSelector) {
this.paginationSelector = paginationSelector;
return this.checkInit();
}
setSearchSelector(searchSelector) {
this.searchSelector = searchSelector;
return this.checkInit();
}
setResultsNumSelector(resultsNumSelector) {
this.resultsNumSelector = resultsNumSelector;
return this.checkInit();
}
setHistoryKeyPrefix(historyKeyPrefix) {
this.historyKeyPrefix = historyKeyPrefix;
return this.checkInit();
}
setCacheHandle(cacheHandle) {
this.cacheHandle = cacheHandle;
return this.checkInit();
}
onUpdate(update_closure) {
this.update_closure = update_closure;
return this.checkInit();
}
addRequestData(new_data) {
return $.extend(this.additional_request_data, new_data);
}
handleKeyPress(e, table) {
if (!table.element.parents().last().is("html")) {
return;
}
if (e.altKey || e.ctrlKey || e.shiftKey) {
return;
}
if (e.srcElement.nodeName !== "BODY") {
return;
}
switch (e.which) {
case 37: //# left
var { state } = table.pagination;
if (state.page < 2) {
return;
}
SF.history.set({
[this.prefixHistoryKey("page")]: parseInt(state.page) - 1,
});
break;
case 39: //# right
({ state } = table.pagination);
if (state.page === state.page_max) {
return;
}
SF.history.set({
[this.prefixHistoryKey("page")]: parseInt(state.page) + 1,
});
break;
default:
return; //# exit this handler for other keys
}
return e.preventDefault(); //# prevent the default action (scroll / move caret)
}
update() {
const request = $.extend({}, this.getUnprefixedHistory(), this.additional_request_data);
const that = this;
return SF.action.post(
this.tableSource,
request,
function (response) {
that.pagination.setState(response);
$(that.resultsNumSelector).text(response.count);
that.update_closure(response);
return SF.proto.build(that.element.find(that.prototypeSelector), response.results, that.build_closure);
},
function (response) {
if (response.type === "SF_exception_route_noaccess") {
return SF.html.redirect(`/login?back_location=${window.location.pathname}`);
} else {
return alert(`${response.type}: ${response.message}`);
}
}
);
}
prefixHistoryKey(key) {
return `${this.historyKeyPrefix}${key}`;
}
getPrefixedHistory() {
const prefixed_history = {};
for (let key in this.history_keys) {
const value = this.history_keys[key];
prefixed_history[this.prefixHistoryKey(key)] = value;
}
return prefixed_history;
}
getUnprefixedHistory() {
const unprefixed_history = {};
const regexp = new RegExp(`^${this.historyKeyPrefix}`, "g");
const object = SF.history.get();
for (let key in object) {
const value = object[key];
const new_key = key.replace(regexp, "");
unprefixed_history[new_key] = value;
}
return unprefixed_history;
}
checkInit() {
if (this.inited) {
throw "Table has already been init()ed!";
}
}
};
SF.admin.liveImage = function (liveData, fallback_closure) {
const { previousId, id, x, y } = liveData;
if (!previousId && !id) {
return;
}
if (!previousId !== !id) {
fallback_closure();
return;
}
const regexp = /\/build\/image\/\d+(?:\.(jpg|gif|png))?\?[^'\)]+/gi;
const updateUrl = (url) =>
url.replace(regexp, function (match) {
match = `/build/image/${id}` + match.match(/\?.*/g)[0];
return match.replace(/fit=(crop|ratio)\-\w+\-\w+/i, `fit=$1-${x}-${y}`);
});
$(`[style*='/build/image/${previousId}']`).each(function () {
const $this = $(this);
return $this.attr("style", updateUrl($this.attr("style")));
});
$(`img[src*='/build/image/${previousId}']`).each(function () {
const $this = $(this);
return $this.attr("src", updateUrl($this.attr("src")));
});
return $(`img[srcset*='/build/image/${previousId}']`).each(function () {
const $this = $(this);
const srcsets = $this
.attr("srcset")
.split(",")
.map((url) => updateUrl(url));
return $this.attr("srcset", srcsets.join(", "));
});
};
SF.link = {};
SF.link.parse = function (url) {
const location = document.createElement("a");
location.href = url;
return location;
};
SF.link.makeRelative = function (url) {
const DOMAIN_TEST = new RegExp("^(?:https?:)?(?://)?" + window.location.hostname);
const matches = url.match(DOMAIN_TEST);
if (matches) {
url = url.substr(matches[0].length);
}
return url;
};
SF.link.makeRelativeIfInternal = function (url) {
const location = SF.link.parse(url);
const relative_url = SF.link.makeRelative(url);
const new_url = relative_url && window.location.hostname === location.hostname ? relative_url : url;
return new_url;
};
SF.link.targetForUrl = function (url) {
// Email
if (url.indexOf("@") !== -1) {
return "";
}
// Remove domain
url = SF.link.makeRelative(url);
// Home page becomes /
if (!url) {
url = "/";
}
const RELATIVE_URI = /^(?:\/(?:[^\/\.]|$)+|[^\/\.:]+(?:\/|$))/;
const is_file = url.match(/^\/file\//) !== null;
if (!is_file && RELATIVE_URI.test(url)) {
return "";
} else {
return "_blank";
}
};
SF.idle = new (function () {
let _tmp;
this.register = _tmp = (timeout) => {
delete this.register;
$.idleTimer(timeout);
this.state = () => !$(document).idleTimer("isIdle");
this.register = function () {};
this.unregister = () => {
this.register = _tmp;
delete this.state;
$.idleTimer("destroy");
return null;
};
return null;
};
return this;
})();
SF.cache.unregisterHandles("su-update-users");
SF.cache.registerHandle("su-update-users", (user) =>
SF.action.post("action/admin/user/all/get", {}, (response) =>
$(".su-users-select").each(function () {
const $child = $(this);
const selected_user_ids = [];
$child.find(":selected").each(function () {
return selected_user_ids.push(parseInt($(this).val()));
});
$child.empty().append(new Option());
for (let child of Array.from(response.users)) {
const selected = $.inArray(child.Id, selected_user_ids) > -1 || user.Id === child.Id;
$child.append(new Option(child.FirstName + " " + child.LastName, child.Id, selected, selected));
}
return $child.trigger("change");
})
)
);
SF.form = {};
SF.form.throwError = function ($form, message, clear_existing_errors) {
if (clear_existing_errors == null) {
clear_existing_errors = true;
}
const block = SF.bootstrap.alert.basic(message, "danger");
if (!$form.find(".form-error-container").length) {
$form.append($(""));
}
const $container = $(".form-error-container");
if (clear_existing_errors) {
$container.empty();
}
$container.append(block);
const $modal_content = $form.closest(".modal-content");
if ($modal_content.length) {
return $modal_content.animate({ scrollTop: $modal_content[0].scrollHeight }, "slow");
}
};
function __guard__(value, transform) {
return typeof value !== "undefined" && value !== null ? transform(value) : undefined;
}
function __range__(left, right, inclusive) {
let range = [];
let ascending = left < right;
let end = !inclusive ? right : ascending ? right + 1 : right - 1;
for (let i = left; ascending ? i < end : i > end; ascending ? i++ : i--) {
range.push(i);
}
return range;
}
SF.debounce = function debounce(func, wait, immediate) {
var timeout;
return function () {
var context = this,
args = arguments;
var later = function () {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
SF.buildFormData = (formData, data, parentKey) => {
if (data && typeof data === "object" && !(data instanceof Date) && !(data instanceof File)) {
Object.keys(data).forEach((key) => {
SF.buildFormData(formData, data[key], parentKey ? `${parentKey}[${key}]` : key);
});
} else {
const value = data == null ? "" : data;
formData.append(parentKey, value);
}
};