// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// MIT License. See license.txt
/* eslint-disable no-console */
import hljs from "./syntax_highlight";
frappe.provide("website");
frappe.provide("frappe.awesome_bar_path");
window.cur_frm = null;
$.extend(frappe, {
_assets_loaded: [],
require: async function (links, callback) {
if (typeof links === "string") {
links = [links];
}
links = links.map((link) => frappe.bundled_asset(link));
for (let link of links) {
await this.add_asset_to_head(link);
}
callback && callback();
},
bundled_asset(path, is_rtl = null) {
if (!path.startsWith("/assets") && path.includes(".bundle.")) {
if (path.endsWith(".css") && is_rtl) {
path = `rtl_${path}`;
}
path = frappe.boot.assets_json[path] || path;
return path;
}
return path;
},
add_asset_to_head(link) {
return new Promise((resolve) => {
if (frappe._assets_loaded.includes(link)) return resolve();
let el;
if (link.split(".").pop() === "js") {
el = document.createElement("script");
el.type = "text/javascript";
el.src = link;
} else {
el = document.createElement("link");
el.type = "text/css";
el.rel = "stylesheet";
el.href = link;
}
document.getElementsByTagName("head")[0].appendChild(el);
el.onload = () => {
frappe._assets_loaded.push(link);
resolve();
};
});
},
hide_message: function () {
$(".message-overlay").remove();
},
xcall: function (method, params) {
return new Promise((resolve, reject) => {
frappe.call({
method: method,
args: params,
callback: (r) => {
resolve(r.message);
},
error: (r) => {
reject(r.message);
},
});
});
},
call: function (opts) {
// opts = {"method": "PYTHON MODULE STRING", "args": {}, "callback": function(r) {}}
if (typeof arguments[0] === "string") {
opts = {
method: arguments[0],
args: arguments[1],
callback: arguments[2],
};
}
frappe.prepare_call(opts);
if (opts.freeze) {
frappe.freeze();
}
return $.ajax({
type: opts.type || "POST",
url: opts.url || "/",
data: opts.args,
dataType: "json",
headers: {
"X-Frappe-CSRF-Token": frappe.csrf_token,
"X-Frappe-CMD": (opts.args && opts.args.cmd) || "" || "",
},
statusCode: opts.statusCode || {
404: function () {
frappe.msgprint(__("Not found"));
},
403: function () {
frappe.msgprint(__("Not permitted"));
},
200: function (data) {
if (opts.callback) opts.callback(data);
if (opts.success) opts.success(data);
},
},
}).always(function (data) {
if (opts.freeze) {
frappe.unfreeze();
}
// executed before statusCode functions
if (data.responseText) {
try {
data = JSON.parse(data.responseText);
} catch (e) {
data = {};
}
}
frappe.process_response(opts, data);
});
},
prepare_call: function (opts) {
if (opts.btn) {
$(opts.btn).prop("disabled", true);
}
if (opts.msg) {
$(opts.msg).toggle(false);
}
if (!opts.args) opts.args = {};
// method
if (opts.method) {
opts.args.cmd = opts.method;
}
$.each(opts.args, function (key, val) {
if (typeof val != "string" && val !== null) {
opts.args[key] = JSON.stringify(val);
}
});
if (!opts.no_spinner) {
//NProgress.start();
}
},
process_response: function (opts, data) {
//if(!opts.no_spinner) NProgress.done();
if (opts.btn) {
$(opts.btn).prop("disabled", false);
}
if (data._server_messages) {
var server_messages = JSON.parse(data._server_messages || "[]");
server_messages
.map((msg) => {
// temp fix for messages sent as dict
try {
return JSON.parse(msg);
} catch (e) {
return msg;
}
})
.join("
");
if (opts.error_msg) {
$(opts.error_msg).html(server_messages).toggle(true);
} else {
frappe.msgprint(server_messages);
}
}
if (data.exc) {
// if(opts.btn) {
// $(opts.btn).addClass($(opts.btn).is('button') || $(opts.btn).hasClass('btn') ? "btn-danger" : "text-danger");
// setTimeout(function() { $(opts.btn).removeClass("btn-danger text-danger"); }, 1000);
// }
try {
var err = JSON.parse(data.exc);
if ($.isArray(err)) {
err = err.join("\n");
}
console.error ? console.error(err) : console.log(err);
} catch (e) {
console.log(data.exc);
}
} else {
// if(opts.btn) {
// $(opts.btn).addClass($(opts.btn).is('button') || $(opts.btn).hasClass('btn') ? "btn-success" : "text-success");
// setTimeout(function() { $(opts.btn).removeClass("btn-success text-success"); }, 1000);
// }
}
if (opts.msg && data.message) {
$(opts.msg).html(data.message).toggle(true);
}
if (opts.always) {
opts.always(data);
}
},
show_message: function (text, icon) {
if (!icon) icon = "fa fa-refresh fa-spin";
frappe.hide_message();
$('
')
.html(
'
' +
text +
"
"
)
.appendTo(document.body);
},
has_permission: function (doctype, docname, perm_type, callback) {
return frappe.call({
type: "GET",
method: "frappe.client.has_permission",
no_spinner: true,
args: { doctype: doctype, docname: docname, perm_type: perm_type },
callback: function (r) {
if (!r.exc && r.message.has_permission) {
if (callback) {
return callback(r);
}
}
},
});
},
render_user: function () {
if (frappe.is_user_logged_in()) {
$(".btn-login-area").toggle(false);
$(".logged-in").toggle(true);
$(".user-image").attr("src", frappe.get_cookie("user_image"));
$(".user-image-wrapper").html(
frappe.avatar(null, "avatar-medium", null, null, null, true)
);
$(".user-image-sidebar").html(
frappe.avatar(null, "avatar-medium", null, null, null, true)
);
$(".user-image-myaccount").html(
frappe.avatar(null, "avatar-large", null, null, null, true)
);
}
},
freeze_count: 0,
freeze: function (msg) {
// blur
if (!$("#freeze").length) {
var freeze = $('').appendTo("body");
freeze.html(
repl(
'',
{ msg: msg || "" }
)
);
setTimeout(function () {
freeze.addClass("in");
}, 1);
} else {
$("#freeze").addClass("in");
}
frappe.freeze_count++;
},
unfreeze: function () {
if (!frappe.freeze_count) return; // anything open?
frappe.freeze_count--;
if (!frappe.freeze_count) {
var freeze = $("#freeze").removeClass("in");
setTimeout(function () {
if (!frappe.freeze_count) {
freeze.remove();
}
}, 150);
}
},
trigger_ready: function () {
frappe.ready_events.forEach(function (fn) {
fn();
});
},
highlight_code_blocks: function () {
hljs.initHighlighting();
},
bind_filters: function () {
// set in select
$(".filter").each(function () {
var key = $(this).attr("data-key");
var val = frappe.utils.get_url_arg(key).replace(/\+/g, " ");
if (val) $(this).val(val);
});
// search url
var search = function () {
var args = {};
$(".filter").each(function () {
var val = $(this).val();
if (val) args[$(this).attr("data-key")] = val;
});
window.location.href = location.pathname + "?" + $.param(args);
};
$(".filter").on("change", function () {
search();
});
},
bind_navbar_search: function () {
frappe.get_navbar_search().on("keypress", function (e) {
var val = $(this).val();
if (e.which === 13 && val) {
$(this).val("").blur();
frappe.do_search(val);
return false;
}
});
},
do_search: function (val) {
var path =
(frappe.awesome_bar_path && frappe.awesome_bar_path[location.pathname]) ||
window.search_path ||
location.pathname;
window.location.href = path + "?txt=" + encodeURIComponent(val);
},
set_search_path: function (path) {
frappe.awesome_bar_path[location.pathname] = path;
},
make_navbar_active: function () {
var pathname = window.location.pathname;
$(".navbar-nav a.active").removeClass("active");
$(".navbar-nav a").each(function () {
var href = $(this).attr("href");
if (href === pathname) {
$(this).addClass("active");
return false;
}
});
},
get_navbar_search: function () {
return $(".navbar .search, .sidebar .search");
},
is_user_logged_in: function () {
return frappe.get_cookie("user_id") !== "Guest" && frappe.session.user !== "Guest";
},
add_switch_to_desk: function () {
$(".switch-to-desk").removeClass("hidden");
},
add_link_to_headings: function () {
$(".doc-content .from-markdown")
.find("h2, h3, h4, h5, h6")
.each((i, $heading) => {
let id = $heading.id;
let $a = $('')
.prop("href", "#" + id)
.attr("aria-hidden", "true").html(`
`);
$($heading).append($a);
});
},
show_language_picker() {
if (frappe.session.user === "Guest" && window.show_language_picker) {
frappe
.call("frappe.translate.get_all_languages", {
with_language_name: true,
})
.then((res) => {
let language_list = res.message;
let language = frappe.get_cookie("preferred_language");
let language_codes = [];
let language_switcher = $("#language-switcher .form-control");
language_list.forEach((language_doc) => {
language_codes.push(language_doc.language_code);
language_switcher.append(
$("")
.attr("value", language_doc.language_code)
.text(language_doc.language_name)
);
});
$("#language-switcher").removeClass("hide");
language =
language ||
(language_codes.includes(navigator.language) ? navigator.language : "en");
language_switcher.val(language);
document.documentElement.lang = language;
language_switcher.change(() => {
let lang = language_switcher.val();
frappe
.call("frappe.translate.set_preferred_language_cookie", {
preferred_language: lang,
})
.then(() => {
window.location.reload();
});
});
});
}
},
setup_videos: () => {
// converts video images into youtube embeds (via Page Builder)
$(".section-video-wrapper").on("click", (e) => {
let $video = $(e.currentTarget);
let id = $video.data("youtubeId");
console.log(id);
$video.find(".video-thumbnail").hide();
$video.append(`
`);
});
},
});
frappe.setup_search = function (target, search_scope) {
if (typeof target === "string") {
target = $(target);
}
let $search_input = $(``);
target.empty();
$search_input.appendTo(target);
// let $dropdown = $search_input.find('.dropdown');
let $dropdown_menu = $search_input.find(".dropdown-menu");
let $input = $search_input.find("input");
let dropdownItems;
let offsetIndex = 0;
$(document).on("keypress", (e) => {
if ($(e.target).is("textarea, input, select")) {
return;
}
if (e.key === "/") {
e.preventDefault();
$input.focus();
}
});
$input.on(
"input",
frappe.utils.debounce(() => {
if (!$input.val()) {
clear_dropdown();
return;
}
frappe
.call({
method: "frappe.search.web_search",
args: {
scope: search_scope || null,
query: $input.val(),
limit: 5,
},
})
.then((r) => {
let results = r.message || [];
let dropdown_html;
if (results.length == 0) {
dropdown_html = `No results found
`;
} else {
dropdown_html = results
.map((r) => {
return `
${r.title_highlights || r.title}
${r.content_highlights}
`;
})
.join("");
}
$dropdown_menu.html(dropdown_html);
$dropdown_menu.addClass("show");
dropdownItems = $dropdown_menu.find(".dropdown-item");
});
}, 500)
);
$input.on("focus", () => {
if (!$input.val()) {
clear_dropdown();
} else {
$input.trigger("input");
}
});
$input.keydown(function (e) {
// up: 38, down: 40
if (e.which == 40) {
navigate(0);
}
});
$dropdown_menu.keydown(function (e) {
// up: 38, down: 40
if (e.which == 38) {
navigate(-1);
} else if (e.which == 40) {
navigate(1);
} else if (e.which == 27) {
setTimeout(() => {
clear_dropdown();
}, 300);
}
});
// Clear dropdown when clicked
$(window).click(function () {
clear_dropdown();
});
$search_input.click(function (event) {
event.stopPropagation();
});
// Navigate the list
var navigate = function (diff) {
offsetIndex += diff;
if (offsetIndex >= dropdownItems.length) offsetIndex = 0;
if (offsetIndex < 0) offsetIndex = dropdownItems.length - 1;
$input.off("blur");
dropdownItems.eq(offsetIndex).focus();
};
function clear_dropdown() {
offsetIndex = 0;
$dropdown_menu.html("");
$dropdown_menu.removeClass("show");
dropdownItems = undefined;
}
// Remove focus state on hover
$dropdown_menu.mouseover(function () {
dropdownItems.blur();
});
};
// Utility functions
window.valid_email = function (id) {
// eslint-disable-next-line
// copied regex from frappe/utils.js validate_type
return /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/.test(
id.toLowerCase()
);
};
window.validate_email = valid_email;
window.cstr = function (s) {
return s == null ? "" : s + "";
};
window.is_null = function is_null(v) {
if (v === null || v === undefined || cstr(v).trim() === "") return true;
};
window.is_html = function is_html(txt) {
if (
txt.indexOf("
") == -1 &&
txt.indexOf("