// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors // MIT License. See license.txt 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)s
', { 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 li.active").removeClass("active"); $(".navbar-nav li").each(function () { var href = $(this.getElementsByTagName("a")).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_apps: function (obj) { $(".logged-in .apps").attr("href", obj.route).text(obj.label); $(".logged-in .apps").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(() => { const lang = language_switcher.val(); document.cookie = `preferred_language=${lang}`; 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 = ``; } 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) { // copied regex from frappe/utils.js validate_type // eslint-disable-next-line 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 = window.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("