/** * webtrees: online genealogy * Copyright (C) 2019 webtrees development team * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ 'use strict'; let webtrees = function () { const lang = document.documentElement.lang; /** * Tidy the whitespace in a string. */ function trim(str) { return str.replace(/\s+/g, " ").trim(); } /** * Look for non-latin characters in a string. */ function detectScript(str) { if (str.match(/[\u3400-\u9FCC]/)) { return "cjk"; } else if (str.match(/[\u0370-\u03FF]/)) { return "greek"; } else if (str.match(/[\u0400-\u04FF]/)) { return "cyrillic"; } else if (str.match(/[\u0590-\u05FF]/)) { return "hebrew"; } else if (str.match(/[\u0600-\u06FF]/)) { return "arabic"; } return "latin"; } /** * In some languages, the SURN uses a male/default form, but NAME uses a gender-inflected form. */ function inflectSurname(surname, sex) { if (lang === "pl" && sex === "F") { return surname .replace(/ski$/, "ska") .replace(/cki$/, "cka") .replace(/dzki$/, "dzka") .replace(/żki$/, "żka"); } return surname; } /** * Build a NAME from a NPFX, GIVN, SPFX, SURN and NSFX parts. * * Assumes the language of the document is the same as the language of the name. */ function buildNameFromParts(npfx, givn, spfx, surn, nsfx, sex) { const usesCJK = detectScript(npfx + givn + spfx + givn + surn + nsfx) === "cjk"; const separator = usesCJK ? "" : " "; const surnameFirst = usesCJK || ['hu', 'jp', 'ko', 'vi', 'zh-Hans', 'zh-Hant'].indexOf(lang) !== -1; const patronym = ['is'].indexOf(lang) !== -1; const slash = patronym ? "" : "/"; // GIVN and SURN may be a comma-separated lists. npfx = trim(npfx); givn = trim(givn.replace(",", separator)); spfx = trim(spfx); surn = inflectSurname(trim(surn.replace(",", separator)), sex); nsfx = trim(nsfx); const surname = trim(spfx + separator + surn); const name = surnameFirst ? slash + surname + slash + separator + givn : givn + separator + slash + surname + slash; return trim(npfx + separator + name + separator + nsfx); } // Public methods return { buildNameFromParts: buildNameFromParts, detectScript: detectScript, }; }(); function expand_layer(sid) { $('#' + sid + '_img').toggleClass('icon-plus icon-minus'); $('#' + sid).slideToggle('fast'); $('#' + sid + '-alt').toggle(); // hide something when we show the layer - and vice-versa return false; } // Accept the changes to a record - and reload the page function accept_changes(xref, ged) { $.post( 'index.php', { route: 'accept-changes', xref: xref, ged: ged, }, function () { document.location.reload(); } ); return false; } // Reject the changes to a record - and reload the page function reject_changes(xref, ged) { $.post( 'index.php', { route: 'reject-changes', xref: xref, ged: ged, }, function () { document.location.reload(); } ); return false; } // Delete a record - and reload the page function delete_record(xref, gedcom) { $.post( 'index.php', { route: 'delete-record', xref: xref, ged: gedcom, }, function () { document.location.reload(); } ); return false; } // Delete a fact - and reload the page function delete_fact(message, ged, xref, fact_id) { if (confirm(message)) { $.post( 'index.php', { route: 'delete-fact', xref: xref, fact_id: fact_id, ged: ged }, function () { document.location.reload(); } ); } return false; } // Copy a fact to the clipboard function copy_fact(ged, xref, fact_id) { $.post( 'index.php', { route: 'copy-fact', xref: xref, fact_id: fact_id, ged: ged, }, function () { document.location.reload(); } ); return false; } // Paste a fact from the clipboard function paste_fact(ged, xref, element) { $.post( 'index.php', { route: 'paste-fact', xref: xref, fact_id: $(element).val(), // element is the '; for (i = 1; i < 32; i++) { content += '"); }); // Datatables - locale aware sorting $.fn.dataTableExt.oSort['text-asc'] = function (x, y) { return x.localeCompare(y, document.documentElement.lang, {'sensitivity': 'base'}); }; $.fn.dataTableExt.oSort['text-desc'] = function (x, y) { return y.localeCompare(x, document.documentElement.lang, {'sensitivity': 'base'}); }; // DataTables - start hidden to prevent FOUC. $('table.datatables').each(function () { $(this).DataTable(); $(this).removeClass('d-none'); }); // Create a new record while editing an existing one. // Paste the XREF and description into the Select2 element. $('.wt-modal-create-record').on('show.bs.modal', function (event) { // Find the element ID that needs to be updated with the new value. $('form', $(this)).data('element-id', $(event.relatedTarget).data('element-id')); $('form .form-group input:first', $(this)).focus(); }); // Submit the modal form using AJAX, and paste the returned record ID/NAME into the parent form. $('.wt-modal-create-record form').on('submit', function (event) { event.preventDefault(); var elementId = $(this).data('element-id'); $.ajax({ url: 'index.php', type: 'POST', data: new FormData(this), async: false, cache: false, contentType: false, processData: false, success: function (data) { $('#' + elementId).select2().empty().append(new Option(data.text, data.id)).val(data.id).trigger('change'); }, failure: function (data) { alert(data.error_message); } }); // Clear the form this.reset(); // Close the modal $(this).closest('.wt-modal-create-record').modal('hide'); }); // Activate the langauge selection menu. $('.menu-language').on('click', '[data-language]', function () { $.post('index.php', { route: 'language', language: $(this).data('language') }, function () { document.location.reload(); }); return false; }); // Activate the theme selection menu. $('.menu-theme').on('click', '[data-theme]', function () { $.post('index.php', { route: 'theme', theme: $(this).data('theme') }, function () { document.location.reload(); }); return false; }); // Activate the on-screen keyboard var osk_focus_element; $('.wt-osk-trigger').click(function () { // When a user clicks the icon, set focus to the corresponding input osk_focus_element = document.getElementById($(this).data('id')); osk_focus_element.focus(); $('.wt-osk').show(); }); $('.wt-osk-script-button').change(function () { $('.wt-osk-script').prop('hidden', true); $('.wt-osk-script-' + $(this).data('script')).prop('hidden', false); }); $('.wt-osk-shift-button').click(function () { document.querySelector('.wt-osk-keys').classList.toggle('shifted'); }); $('.wt-osk-keys').on('click', '.wt-osk-key', function () { var key = $(this).contents().get(0).nodeValue; var shift_state = $('.wt-osk-shift-button').hasClass('active'); var shift_key = $('sup', this)[0]; if (shift_state && shift_key !== undefined) { key = shift_key.innerText; } if (osk_focus_element !== null) { var cursorPos = osk_focus_element.selectionStart; var v = osk_focus_element.value; var textBefore = v.substring(0, cursorPos); var textAfter = v.substring(cursorPos, v.length); osk_focus_element.value = textBefore + key + textAfter; if ($('.wt-osk-pin-button').hasClass('active') === false) { $('.wt-osk').hide(); } } }); $('.wt-osk-close').on('click', function () { $('.wt-osk').hide(); }); });