psdi-data-conversion 0.0.23__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- psdi_data_conversion/__init__.py +11 -0
- psdi_data_conversion/app.py +242 -0
- psdi_data_conversion/bin/linux/atomsk +0 -0
- psdi_data_conversion/bin/linux/c2x +0 -0
- psdi_data_conversion/bin/mac/atomsk +0 -0
- psdi_data_conversion/bin/mac/c2x +0 -0
- psdi_data_conversion/constants.py +185 -0
- psdi_data_conversion/converter.py +459 -0
- psdi_data_conversion/converters/__init__.py +6 -0
- psdi_data_conversion/converters/atomsk.py +32 -0
- psdi_data_conversion/converters/base.py +702 -0
- psdi_data_conversion/converters/c2x.py +32 -0
- psdi_data_conversion/converters/openbabel.py +239 -0
- psdi_data_conversion/database.py +1064 -0
- psdi_data_conversion/dist.py +87 -0
- psdi_data_conversion/file_io.py +216 -0
- psdi_data_conversion/log_utility.py +241 -0
- psdi_data_conversion/main.py +776 -0
- psdi_data_conversion/scripts/atomsk.sh +32 -0
- psdi_data_conversion/scripts/c2x.sh +26 -0
- psdi_data_conversion/security.py +38 -0
- psdi_data_conversion/static/content/accessibility.htm +254 -0
- psdi_data_conversion/static/content/convert.htm +121 -0
- psdi_data_conversion/static/content/convertato.htm +65 -0
- psdi_data_conversion/static/content/convertc2x.htm +65 -0
- psdi_data_conversion/static/content/documentation.htm +94 -0
- psdi_data_conversion/static/content/feedback.htm +53 -0
- psdi_data_conversion/static/content/header-links.html +8 -0
- psdi_data_conversion/static/content/index-versions/header-links.html +8 -0
- psdi_data_conversion/static/content/index-versions/psdi-common-footer.html +99 -0
- psdi_data_conversion/static/content/index-versions/psdi-common-header.html +28 -0
- psdi_data_conversion/static/content/psdi-common-footer.html +99 -0
- psdi_data_conversion/static/content/psdi-common-header.html +28 -0
- psdi_data_conversion/static/content/report.htm +103 -0
- psdi_data_conversion/static/data/data.json +143940 -0
- psdi_data_conversion/static/img/colormode-toggle-dm.svg +3 -0
- psdi_data_conversion/static/img/colormode-toggle-lm.svg +3 -0
- psdi_data_conversion/static/img/psdi-icon-dark.svg +136 -0
- psdi_data_conversion/static/img/psdi-icon-light.svg +208 -0
- psdi_data_conversion/static/img/psdi-logo-darktext.png +0 -0
- psdi_data_conversion/static/img/psdi-logo-lighttext.png +0 -0
- psdi_data_conversion/static/img/social-logo-bluesky-black.svg +4 -0
- psdi_data_conversion/static/img/social-logo-bluesky-white.svg +4 -0
- psdi_data_conversion/static/img/social-logo-instagram-black.svg +1 -0
- psdi_data_conversion/static/img/social-logo-instagram-white.svg +1 -0
- psdi_data_conversion/static/img/social-logo-linkedin-black.png +0 -0
- psdi_data_conversion/static/img/social-logo-linkedin-white.png +0 -0
- psdi_data_conversion/static/img/social-logo-mastodon-black.svg +4 -0
- psdi_data_conversion/static/img/social-logo-mastodon-white.svg +4 -0
- psdi_data_conversion/static/img/social-logo-x-black.svg +3 -0
- psdi_data_conversion/static/img/social-logo-x-white.svg +3 -0
- psdi_data_conversion/static/img/social-logo-youtube-black.png +0 -0
- psdi_data_conversion/static/img/social-logo-youtube-white.png +0 -0
- psdi_data_conversion/static/img/ukri-epsr-logo-darktext.png +0 -0
- psdi_data_conversion/static/img/ukri-epsr-logo-lighttext.png +0 -0
- psdi_data_conversion/static/img/ukri-logo-darktext.png +0 -0
- psdi_data_conversion/static/img/ukri-logo-lighttext.png +0 -0
- psdi_data_conversion/static/javascript/accessibility.js +196 -0
- psdi_data_conversion/static/javascript/common.js +42 -0
- psdi_data_conversion/static/javascript/convert.js +296 -0
- psdi_data_conversion/static/javascript/convert_common.js +252 -0
- psdi_data_conversion/static/javascript/convertato.js +107 -0
- psdi_data_conversion/static/javascript/convertc2x.js +107 -0
- psdi_data_conversion/static/javascript/data.js +176 -0
- psdi_data_conversion/static/javascript/format.js +611 -0
- psdi_data_conversion/static/javascript/load_accessibility.js +89 -0
- psdi_data_conversion/static/javascript/psdi-common.js +177 -0
- psdi_data_conversion/static/javascript/report.js +381 -0
- psdi_data_conversion/static/styles/format.css +147 -0
- psdi_data_conversion/static/styles/psdi-common.css +705 -0
- psdi_data_conversion/templates/index.htm +114 -0
- psdi_data_conversion/testing/__init__.py +5 -0
- psdi_data_conversion/testing/constants.py +12 -0
- psdi_data_conversion/testing/conversion_callbacks.py +394 -0
- psdi_data_conversion/testing/conversion_test_specs.py +208 -0
- psdi_data_conversion/testing/utils.py +522 -0
- psdi_data_conversion-0.0.23.dist-info/METADATA +663 -0
- psdi_data_conversion-0.0.23.dist-info/RECORD +81 -0
- psdi_data_conversion-0.0.23.dist-info/WHEEL +4 -0
- psdi_data_conversion-0.0.23.dist-info/entry_points.txt +2 -0
- psdi_data_conversion-0.0.23.dist-info/licenses/LICENSE +201 -0
@@ -0,0 +1,177 @@
|
|
1
|
+
// This file provides common functions related to the PSDI common assets. Most of these are run automatically as
|
2
|
+
// appropriate, except the first batch of functions exported below. These are exposed to the user so that they can
|
3
|
+
// customise aspects of the common HTML header
|
4
|
+
|
5
|
+
const ORIG_TITLE = "$REPLACEME_SITE_TITLE"
|
6
|
+
const ORIG_TITLE_LINK = "./"
|
7
|
+
|
8
|
+
const DEFAULT_TITLE = "";
|
9
|
+
const DEFAULT_TITLE_LINK_TARGET = "./";
|
10
|
+
const DEFAULT_HEADER_LINKS_SOURCE = "./header-links.html";
|
11
|
+
const DEFAULT_HEADER_SOURCE = "./psdi-common-header.html";
|
12
|
+
const DEFAULT_FOOTER_SOURCE = "./psdi-common-footer.html";
|
13
|
+
|
14
|
+
let title = DEFAULT_TITLE;
|
15
|
+
let useDefaultTitle = true;
|
16
|
+
let titleLinkTarget = DEFAULT_TITLE_LINK_TARGET;
|
17
|
+
let useDefaultTitleLink = true;
|
18
|
+
let headerLinksSource = DEFAULT_HEADER_LINKS_SOURCE;
|
19
|
+
let headerSource = DEFAULT_HEADER_SOURCE
|
20
|
+
let footerSource = DEFAULT_FOOTER_SOURCE
|
21
|
+
|
22
|
+
export function setTitle(s) {
|
23
|
+
// Public function for the user to set the site title that will appear in the header, to the right of the PSDI logo
|
24
|
+
title = s;
|
25
|
+
useDefaultTitle = false;
|
26
|
+
}
|
27
|
+
|
28
|
+
export function setTitleLinkTarget(s) {
|
29
|
+
// Public function for the user to set the target that clicking on the site title should link to
|
30
|
+
titleLinkTarget = s;
|
31
|
+
useDefaultTitleLink = false;
|
32
|
+
}
|
33
|
+
|
34
|
+
// Alias for previous name of `setTitleLinkTarget` to maintain backwards compatibility
|
35
|
+
export const setBrandLinkTarget = setTitleLinkTarget;
|
36
|
+
|
37
|
+
export function setHeaderLinksSource(s) {
|
38
|
+
// Public function to set the name of an HTML file containing the links to appear on the right side of the header
|
39
|
+
// for a given page
|
40
|
+
headerLinksSource = s;
|
41
|
+
}
|
42
|
+
|
43
|
+
export function setHeaderSource(s) {
|
44
|
+
// Public function to set the name of the header HTML file to be loaded
|
45
|
+
headerSource = s;
|
46
|
+
}
|
47
|
+
|
48
|
+
export function setFooterSource(s) {
|
49
|
+
// Public function to set the name of the footer HTML file to be loaded
|
50
|
+
footerSource = s;
|
51
|
+
}
|
52
|
+
|
53
|
+
const LIGHT_MODE = "light";
|
54
|
+
const DARK_MODE = "dark";
|
55
|
+
|
56
|
+
// Load color mode from session storage and apply it
|
57
|
+
let mode = sessionStorage.getItem("mode");
|
58
|
+
if (!mode) {
|
59
|
+
mode = LIGHT_MODE;
|
60
|
+
}
|
61
|
+
document.documentElement.setAttribute("data-theme", mode);
|
62
|
+
|
63
|
+
function toggleMode() {
|
64
|
+
let currentMode = document.documentElement.getAttribute("data-theme");
|
65
|
+
let new_mode;
|
66
|
+
|
67
|
+
if (currentMode == DARK_MODE) {
|
68
|
+
new_mode = LIGHT_MODE;
|
69
|
+
} else {
|
70
|
+
new_mode = DARK_MODE;
|
71
|
+
}
|
72
|
+
|
73
|
+
document.documentElement.setAttribute("data-theme", new_mode);
|
74
|
+
sessionStorage.setItem("mode", new_mode);
|
75
|
+
}
|
76
|
+
|
77
|
+
export function connectModeToggleButton() {
|
78
|
+
// Connect the mode toggle function to the button
|
79
|
+
const lModeToggleButton = document.querySelectorAll(".color-mode-toggle");
|
80
|
+
lModeToggleButton.forEach(function (modeToggleButton) {
|
81
|
+
modeToggleButton.addEventListener("click", toggleMode);
|
82
|
+
});
|
83
|
+
}
|
84
|
+
|
85
|
+
// Counter for elements that need to be loaded - each we request loading will increment this by 1
|
86
|
+
let loadSteps = 0;
|
87
|
+
|
88
|
+
function finalizeLoad() {
|
89
|
+
// Decrement the load steps and check if all steps are finished. If so, remove the cover
|
90
|
+
--loadSteps;
|
91
|
+
if (loadSteps <= 0) {
|
92
|
+
$("#cover").hide();
|
93
|
+
}
|
94
|
+
}
|
95
|
+
|
96
|
+
export function addHeaderLinks() {
|
97
|
+
// We want to load in the links, but preserve the existing mode toggle button alongside them, so this function
|
98
|
+
// handles saving it and re-adding it
|
99
|
+
|
100
|
+
let headerLinksParent = $("#psdi-header .navbar__items--right");
|
101
|
+
let modeToggle = $("#psdi-header .color-mode-toggle");
|
102
|
+
|
103
|
+
headerLinksParent.load(headerLinksSource,
|
104
|
+
function (_response, status, _xhr) {
|
105
|
+
if (status == "error") {
|
106
|
+
headerLinksParent[0].textContent = "ERROR: Could not load header links";
|
107
|
+
}
|
108
|
+
headerLinksParent[0].appendChild(modeToggle[0]);
|
109
|
+
connectModeToggleButton();
|
110
|
+
finalizeLoad();
|
111
|
+
});
|
112
|
+
}
|
113
|
+
|
114
|
+
$(document).ready(function () {
|
115
|
+
|
116
|
+
// Start fading out the cover over one second as a failsafe in case something goes wrong and it never gets removed
|
117
|
+
$("#cover").fadeOut(1000);
|
118
|
+
|
119
|
+
// Count the elements we'll need to load first, to avoid prematurely removing the cover
|
120
|
+
// We load an element only if it's a pure stub with no children; otherwise we assume it is intended to be used
|
121
|
+
// as-is and not overwritten by a load. If it's intended to be used as a fallback for if we can't load, it can be
|
122
|
+
// assigned the "fallback" class to load if possible despite something existing
|
123
|
+
|
124
|
+
const headerStub = $("#psdi-header");
|
125
|
+
let loadHeader = false;
|
126
|
+
if (headerStub.length > 0 && (headerStub[0].childNodes.length == 0 || headerStub[0].classList.contains("fallback"))) {
|
127
|
+
loadHeader = true;
|
128
|
+
++loadSteps;
|
129
|
+
}
|
130
|
+
|
131
|
+
const footerStub = $("#psdi-footer");
|
132
|
+
let loadFooter = false;
|
133
|
+
if (footerStub.length > 0 && (footerStub[0].childNodes.length == 0 || footerStub[0].classList.contains("fallback"))) {
|
134
|
+
loadFooter = true;
|
135
|
+
++loadSteps;
|
136
|
+
}
|
137
|
+
|
138
|
+
// Load only if the header stub has no children
|
139
|
+
if (loadHeader) {
|
140
|
+
$("#psdi-header").load(headerSource,
|
141
|
+
function (_response, status, _xhr) {
|
142
|
+
if (status != "error") {
|
143
|
+
// Check if we should replace the title link by if a value is set, or if the value in the header matches
|
144
|
+
// the original value in the source
|
145
|
+
let titleLinkElement = $("#psdi-header a.navbar__title")[0];
|
146
|
+
if (!useDefaultTitleLink || String(titleLinkElement.href) == ORIG_TITLE_LINK)
|
147
|
+
titleLinkElement.href = titleLinkTarget;
|
148
|
+
|
149
|
+
// Check if we should replace the title by if a value is set, or if the value in the header matches
|
150
|
+
// the original value in the source
|
151
|
+
let titleElement = $("#psdi-header .navbar__title h5")[0];
|
152
|
+
if (!useDefaultTitle || String(titleElement.textContent) == ORIG_TITLE)
|
153
|
+
titleElement.textContent = title;
|
154
|
+
addHeaderLinks();
|
155
|
+
} else {
|
156
|
+
$("#psdi-header")[0].textContent = "ERROR: Could not load page header";
|
157
|
+
connectModeToggleButton();
|
158
|
+
finalizeLoad();
|
159
|
+
}
|
160
|
+
});
|
161
|
+
}
|
162
|
+
|
163
|
+
// Load only if the footer stub has no children
|
164
|
+
if (loadFooter) {
|
165
|
+
$("#psdi-footer").load(footerSource,
|
166
|
+
function (_response, status, _xhr) {
|
167
|
+
if (status == "error") {
|
168
|
+
$("#psdi-footer")[0].textContent = "ERROR: Could not load page footer";
|
169
|
+
}
|
170
|
+
finalizeLoad();
|
171
|
+
});
|
172
|
+
}
|
173
|
+
|
174
|
+
if (loadSteps == 0)
|
175
|
+
finalizeLoad();
|
176
|
+
|
177
|
+
});
|
@@ -0,0 +1,381 @@
|
|
1
|
+
/*
|
2
|
+
report.js
|
3
|
+
Version 1.0, 26th June 2024
|
4
|
+
|
5
|
+
This is the JavaScript which makes the report.htm gui work.
|
6
|
+
*/
|
7
|
+
|
8
|
+
import { getAllFormats, getConverters } from "./data.js";
|
9
|
+
import { loadServiceMode } from "./common.js";
|
10
|
+
|
11
|
+
var token = "",
|
12
|
+
fromList = new Array(),
|
13
|
+
toList = new Array(),
|
14
|
+
formatList = new Array();
|
15
|
+
|
16
|
+
const pageURL = new URL(window.location.toLocaleString());
|
17
|
+
|
18
|
+
// If coming to this page from a local version of the app, warn if the user clicks a link in the header, which will
|
19
|
+
// take them to another page on the public app
|
20
|
+
const originUrlParam = pageURL.searchParams.get('origin');
|
21
|
+
const localOrigin = (originUrlParam != null && originUrlParam.toLowerCase() == "local") ? true : false;
|
22
|
+
let originAlertDisplayed = false;
|
23
|
+
|
24
|
+
if (localOrigin) {
|
25
|
+
$("#psdi-header").click(function (e) {
|
26
|
+
if (originAlertDisplayed) return;
|
27
|
+
alert("WARNING: This is the online, public version of the app, which you arrived at from the local " +
|
28
|
+
"app. Press the back button on your browser to return to the local version, or click \"OK\" on this " +
|
29
|
+
"alert to continue to the public app.");
|
30
|
+
originAlertDisplayed = true;
|
31
|
+
});
|
32
|
+
}
|
33
|
+
|
34
|
+
// Set the service mode variable for this page so that only appropriate elements are shown
|
35
|
+
loadServiceMode();
|
36
|
+
|
37
|
+
$(document).ready(function () {
|
38
|
+
|
39
|
+
token = sessionStorage.getItem("token");
|
40
|
+
|
41
|
+
$("#success").css({ display: "none" });
|
42
|
+
|
43
|
+
// Populates the "Convert from" and "Convert to" selection lists
|
44
|
+
getAllFormats().then((allFormats) => {
|
45
|
+
populateList(allFormats, "from");
|
46
|
+
populateList(allFormats, "to");
|
47
|
+
populateList(allFormats, "format");
|
48
|
+
});
|
49
|
+
|
50
|
+
$("#reason").change(display);
|
51
|
+
$("#fromList").click(populateConversionSuccess);
|
52
|
+
$("#toList").click(populateConversionSuccess);
|
53
|
+
$("#formatList").click(populateConversionSuccess);
|
54
|
+
$("#searchTo").keyup(filterOptions);
|
55
|
+
$("#searchFrom").keyup(filterOptions);
|
56
|
+
$("#searchFormats").keyup(filterOptions);
|
57
|
+
$("#resetButton").click(resetAll);
|
58
|
+
$("#resetButton2").click(resetAll);
|
59
|
+
$("#reportButton").click(submitUserInput);
|
60
|
+
});
|
61
|
+
|
62
|
+
// Included in this file for convenience. When the 'Report' button is clicked, a user's missing conversion report
|
63
|
+
// is only sent if the undisplayed conversion success box is empty (i.e., the conversion really is missing)
|
64
|
+
function populateConversionSuccess(event) {
|
65
|
+
const selectedText = getSelectedText(this);
|
66
|
+
|
67
|
+
if (this.id == "fromList") {
|
68
|
+
$("#searchFrom").val(selectedText);
|
69
|
+
}
|
70
|
+
else if (this.id == "toList") {
|
71
|
+
$("#searchTo").val(selectedText);
|
72
|
+
}
|
73
|
+
else {
|
74
|
+
$("#searchFormats").val(selectedText);
|
75
|
+
}
|
76
|
+
|
77
|
+
const from_text = $("#searchFrom").val();
|
78
|
+
const to_text = $("#searchTo").val();
|
79
|
+
|
80
|
+
sessionStorage.setItem("in_str", from_text);
|
81
|
+
sessionStorage.setItem("out_str", to_text);
|
82
|
+
|
83
|
+
this.selectionStart = -1;
|
84
|
+
this.selectionEnd = -1;
|
85
|
+
this.blur();
|
86
|
+
emptySuccess();
|
87
|
+
hideConverterDetails();
|
88
|
+
hideOffer();
|
89
|
+
|
90
|
+
try {
|
91
|
+
const in_str = $("#searchFrom").val(), // e.g. "ins: ShelX"
|
92
|
+
in_str_array = in_str.split(": "),
|
93
|
+
in_ext = in_str_array[0], // e.g. "ins"
|
94
|
+
in_note = in_str_array[1]; // e.g. "ShelX"
|
95
|
+
|
96
|
+
const out_str = $("#searchTo").val(),
|
97
|
+
out_str_array = out_str.split(": "),
|
98
|
+
out_ext = out_str_array[0],
|
99
|
+
out_note = out_str_array[1];
|
100
|
+
|
101
|
+
getConverters(in_ext, in_note, out_ext, out_note).then((converters) => {
|
102
|
+
populateList(converters, "success");
|
103
|
+
});
|
104
|
+
}
|
105
|
+
catch (e) {
|
106
|
+
// Can do without an error message if the 'Conversion options' box remains empty;
|
107
|
+
// however, consider a greyed-out message inside the box (using some of the commented out code below).
|
108
|
+
|
109
|
+
// const ID_a = getFormat($("#searchFrom").val()),
|
110
|
+
// ID_b = getFormat($("#searchTo").val());
|
111
|
+
|
112
|
+
// if (ID_a.toString() != ID_b.toString() && ID_a != "" && ID_b != "") {
|
113
|
+
// conversionSuccessEmpty();
|
114
|
+
//}
|
115
|
+
}
|
116
|
+
}
|
117
|
+
|
118
|
+
// Retrieve selected text from the "Conversion success" textarea
|
119
|
+
function getSelectedText(el) {
|
120
|
+
const text = el.value;
|
121
|
+
const before = text.substring(0, el.selectionStart);
|
122
|
+
const after = text.substring(el.selectionEnd, text.length);
|
123
|
+
|
124
|
+
el.selectionStart = before.lastIndexOf("\n") >= 0 ? before.lastIndexOf("\n") + 1 : 0;
|
125
|
+
el.selectionEnd = after.indexOf("\n") >= 0 ? el.selectionEnd + after.indexOf("\n") : text.length;
|
126
|
+
|
127
|
+
return el.value.substring(el.selectionStart, el.selectionEnd);
|
128
|
+
}
|
129
|
+
|
130
|
+
// Hides converter details
|
131
|
+
function hideConverterDetails() {
|
132
|
+
$("#converter").css({ display: "none" });
|
133
|
+
$("h3").css({ display: "none" });
|
134
|
+
}
|
135
|
+
|
136
|
+
// Submits user input
|
137
|
+
function submitUserInput() {
|
138
|
+
const from = $("#searchFrom").val(),
|
139
|
+
to = $("#searchTo").val();
|
140
|
+
|
141
|
+
var reason = $("#in").val(),
|
142
|
+
missing = $("#missingFormat").val()
|
143
|
+
|
144
|
+
if (reason.length > 9 && reason.length < 501) {
|
145
|
+
if ($("#reason").val() == "format") {
|
146
|
+
if (missing.length > 1 && missing.length < 101) {
|
147
|
+
submitFeedback({
|
148
|
+
type: "missingFormat",
|
149
|
+
missing: missing,
|
150
|
+
reason: reason
|
151
|
+
});
|
152
|
+
}
|
153
|
+
else {
|
154
|
+
alert("Please enter the missing format (2 to 100 characters).");
|
155
|
+
}
|
156
|
+
}
|
157
|
+
else {
|
158
|
+
if (from != "" && to != "") {
|
159
|
+
if ($("#success option").length == 0) {
|
160
|
+
submitFeedback({
|
161
|
+
type: "missingConversion",
|
162
|
+
from: from,
|
163
|
+
to: to,
|
164
|
+
reason: reason
|
165
|
+
});
|
166
|
+
}
|
167
|
+
else {
|
168
|
+
alert("At least one converter is capable of carrying out this conversion, therefore your report has not been sent. If you wish to send feedback about this conversion, please click on 'Contact' in the navigation bar.");
|
169
|
+
}
|
170
|
+
}
|
171
|
+
else if (to != "") {
|
172
|
+
alert("Please select 'from' format.");
|
173
|
+
}
|
174
|
+
else if (from != "") {
|
175
|
+
alert("Please select 'to' format.");
|
176
|
+
}
|
177
|
+
else {
|
178
|
+
alert("Please select 'to' and 'from' formats.");
|
179
|
+
}
|
180
|
+
}
|
181
|
+
}
|
182
|
+
else {
|
183
|
+
alert("Please enter a reason, etc. (10 to 500 characters).");
|
184
|
+
}
|
185
|
+
}
|
186
|
+
|
187
|
+
// Hide Open Babel conversion offer (not required to do anything on this page)
|
188
|
+
function hideOffer() { }
|
189
|
+
|
190
|
+
// Writes user input to a server-side file
|
191
|
+
// $$$$$$$$$$ Retain for now in case logging to file is required for some other purpose $$$$$$$$$$
|
192
|
+
//function writeLog(message) {
|
193
|
+
// var jqXHR = $.get(`/data/`, {
|
194
|
+
// 'token': token,
|
195
|
+
// 'data': message
|
196
|
+
//})
|
197
|
+
// .done(response => {
|
198
|
+
// alert("Report received!");
|
199
|
+
// })
|
200
|
+
// .fail(function(e) {
|
201
|
+
// alert("Reporting failed. Please provide feedback by clicking on 'Contact' in the navigation bar.");
|
202
|
+
|
203
|
+
// // For debugging
|
204
|
+
//console.log("Error writing to log");
|
205
|
+
// console.log(e.status);
|
206
|
+
// console.log(e.responseText);
|
207
|
+
// })
|
208
|
+
//}
|
209
|
+
|
210
|
+
// Submit feedback
|
211
|
+
function submitFeedback(data) {
|
212
|
+
$.post(`/feedback/`, {
|
213
|
+
'token': token,
|
214
|
+
'data': JSON.stringify(data)
|
215
|
+
})
|
216
|
+
.done(() => {
|
217
|
+
alert("Report received!");
|
218
|
+
})
|
219
|
+
.fail(function (e) {
|
220
|
+
alert("Reporting failed. Please provide feedback by clicking on 'Contact' in the navigation bar.");
|
221
|
+
|
222
|
+
// For debugging
|
223
|
+
console.error("Error submitting feedback", e.status, e.responseText);
|
224
|
+
});
|
225
|
+
}
|
226
|
+
|
227
|
+
// Only options having user filter input as a substring (case insensitive) are included in the selection list
|
228
|
+
function filterOptions(event) {
|
229
|
+
const str = this.value.toLowerCase();
|
230
|
+
var box, list,
|
231
|
+
count = 0,
|
232
|
+
text = "";
|
233
|
+
|
234
|
+
if (this.id == "searchFrom") {
|
235
|
+
box = $("#fromList");
|
236
|
+
list = fromList;
|
237
|
+
}
|
238
|
+
else if (this.id == "searchTo") {
|
239
|
+
box = $("#toList");
|
240
|
+
list = toList;
|
241
|
+
}
|
242
|
+
else {
|
243
|
+
box = $("#formatList");
|
244
|
+
list = formatList;
|
245
|
+
}
|
246
|
+
|
247
|
+
box.children().remove();
|
248
|
+
|
249
|
+
for (var i = 0; i < list.length; i++) {
|
250
|
+
if (list[i].toLowerCase().includes(str)) {
|
251
|
+
box.append($('<option>', { text: list[i] }));
|
252
|
+
count += 1;
|
253
|
+
}
|
254
|
+
}
|
255
|
+
|
256
|
+
if (this.id == "searchFrom") {
|
257
|
+
$("#fromLabel").html("Select format to convert from (" + count + "):");
|
258
|
+
}
|
259
|
+
else if (this.id == "searchTo") {
|
260
|
+
$("#toLabel").html("Select format to convert to (" + count + "):");
|
261
|
+
}
|
262
|
+
else {
|
263
|
+
$("#formatLabel").html("Check that the format is not present in the list. If it is, consider reporting a missing conversion. (" + count + ")");
|
264
|
+
}
|
265
|
+
|
266
|
+
$("#success").prop({ disabled: true });
|
267
|
+
emptySuccess();
|
268
|
+
hideConverterDetails();
|
269
|
+
hideOffer();
|
270
|
+
}
|
271
|
+
|
272
|
+
// Empties the "Conversion success" textarea
|
273
|
+
function emptySuccess() {
|
274
|
+
$("#success").html("");
|
275
|
+
}
|
276
|
+
|
277
|
+
// Populates a selection list
|
278
|
+
function populateList(entries, sel) {
|
279
|
+
|
280
|
+
let rows = [];
|
281
|
+
|
282
|
+
if ((sel === "from") || (sel === "to") || (sel === "format")) {
|
283
|
+
|
284
|
+
rows = entries.map(entry => `${entry.extension}: ${entry.note}`);
|
285
|
+
|
286
|
+
} else if (sel === "success") {
|
287
|
+
|
288
|
+
rows = entries.map(entry => `${entry.name}: ${entry.degree_of_success}`);
|
289
|
+
}
|
290
|
+
|
291
|
+
rows.sort(function (a, b) {
|
292
|
+
return a.toLowerCase().localeCompare(b.toLowerCase());
|
293
|
+
});
|
294
|
+
|
295
|
+
$("#success").prop({ disabled: true });
|
296
|
+
|
297
|
+
for (var i = 0; i < rows.length; i++) {
|
298
|
+
const support = rows[i].substring(0, 10) == "Open Babel" ? " (supported)" : " (unsupported)";
|
299
|
+
|
300
|
+
if (sel == "success") {
|
301
|
+
if (rows.length > 0) {
|
302
|
+
$("#success").prop({ disabled: false });
|
303
|
+
}
|
304
|
+
|
305
|
+
$("#success").append($('<option>', { text: "" + rows[i] + support }));
|
306
|
+
}
|
307
|
+
|
308
|
+
if (sel == "from") {
|
309
|
+
$("#fromList").append($('<option>', { text: rows[i] }));
|
310
|
+
fromList[i] = rows[i] + "\n";
|
311
|
+
}
|
312
|
+
else if (sel == "to") {
|
313
|
+
$("#toList").append($('<option>', { text: rows[i] }));
|
314
|
+
toList[i] = rows[i] + "\n";
|
315
|
+
}
|
316
|
+
else if (sel == "format") {
|
317
|
+
$("#formatList").append($('<option>', { text: rows[i] }));
|
318
|
+
formatList[i] = rows[i] + "\n";
|
319
|
+
}
|
320
|
+
}
|
321
|
+
|
322
|
+
if (sel != "success") {
|
323
|
+
$("#fromLabel").html("Select format to convert from (" + fromList.length + "):");
|
324
|
+
$("#toLabel").html("Select format to convert to (" + toList.length + "):");
|
325
|
+
$("#formatLabel").html("Check that the format is not present in the list. If it is, consider reporting a missing conversion. (" + toList.length + ")");
|
326
|
+
}
|
327
|
+
}
|
328
|
+
|
329
|
+
// Resets the filtering and format list boxes
|
330
|
+
function resetAll() {
|
331
|
+
$("#searchFrom").val("");
|
332
|
+
$("#searchFrom").keyup();
|
333
|
+
|
334
|
+
$("#searchTo").val("");
|
335
|
+
$("#searchTo").keyup();
|
336
|
+
|
337
|
+
$("#searchFormats").val("");
|
338
|
+
$("#searchFormats").keyup();
|
339
|
+
}
|
340
|
+
|
341
|
+
// Displays format or conversion related content as appropriate
|
342
|
+
function display(event) {
|
343
|
+
const selectedText = getSelectedText(this);
|
344
|
+
|
345
|
+
$("#in").val("");
|
346
|
+
$("#missingFormat").val("");
|
347
|
+
|
348
|
+
if (selectedText == "conversion") {
|
349
|
+
$("#in_out_formats").css({ display: "block" });
|
350
|
+
$("#message").css({ display: "inline" });
|
351
|
+
|
352
|
+
$("#userInput").css({ display: "block" });
|
353
|
+
|
354
|
+
$("#formats").css({ display: "none" });
|
355
|
+
$("#missing").css({ display: "none" });
|
356
|
+
|
357
|
+
$("#message").html("Explain why the conversion is required and provide a link to appropriate documentation if possible [max 500 characters].");
|
358
|
+
$("#message1").html("The displayed 'from' and 'to' formats will be automatically submitted with your message.");
|
359
|
+
}
|
360
|
+
else if (selectedText == "format") {
|
361
|
+
$("#formats").css({ display: "block" });
|
362
|
+
$("#missing").css({ display: "block" });
|
363
|
+
|
364
|
+
$("#userInput").css({ display: "block" });
|
365
|
+
|
366
|
+
$("#in_out_formats").css({ display: "none" });
|
367
|
+
$("#message").css({ display: "none" });
|
368
|
+
|
369
|
+
$("#message1").html("Enter details of the file conversions expected for this format and provide a link to appropriate documentation if possible [max 500 characters].");
|
370
|
+
}
|
371
|
+
else {
|
372
|
+
$("#in_out_formats").css({ display: "none" });
|
373
|
+
$("#message").css({ display: "none" });
|
374
|
+
|
375
|
+
$("#formats").css({ display: "none" });
|
376
|
+
$("#missing").css({ display: "none" });
|
377
|
+
|
378
|
+
$("#userInput").css({ display: "none" });
|
379
|
+
}
|
380
|
+
}
|
381
|
+
|
@@ -0,0 +1,147 @@
|
|
1
|
+
/*
|
2
|
+
format.css
|
3
|
+
Version 1.0, 11th October 2024
|
4
|
+
*/
|
5
|
+
|
6
|
+
@import url("./psdi-common.css");
|
7
|
+
|
8
|
+
/* Forms inherit style from normal content, and make sure content is well away from the edges */
|
9
|
+
form {
|
10
|
+
width : 95%;
|
11
|
+
min-width : 320px;
|
12
|
+
padding-top: 1rem;
|
13
|
+
align-self : center;
|
14
|
+
}
|
15
|
+
|
16
|
+
/* Padding for link to converter website. */
|
17
|
+
#visit {
|
18
|
+
padding-left: 0.125rem;
|
19
|
+
}
|
20
|
+
|
21
|
+
/* Width management for select boxes and forms */
|
22
|
+
|
23
|
+
.med-width {
|
24
|
+
width: 25rem;
|
25
|
+
}
|
26
|
+
|
27
|
+
@media (max-width: 25rem) {
|
28
|
+
.med-width {
|
29
|
+
width: 100%
|
30
|
+
}
|
31
|
+
}
|
32
|
+
|
33
|
+
.large-width {
|
34
|
+
width: 50rem;
|
35
|
+
}
|
36
|
+
|
37
|
+
@media (max-width: 50rem) {
|
38
|
+
.large-width {
|
39
|
+
width: 100%
|
40
|
+
}
|
41
|
+
|
42
|
+
input.large-width {
|
43
|
+
width: calc(100% - 0.5rem)
|
44
|
+
}
|
45
|
+
}
|
46
|
+
|
47
|
+
/* Converter details, user input and file conversion initially not displayed. */
|
48
|
+
.init-hidden {
|
49
|
+
display: none
|
50
|
+
}
|
51
|
+
|
52
|
+
/* Buttons that are initially disabled */
|
53
|
+
input.button.init-disabled {
|
54
|
+
background-color: var(--psdi-bg-color-secondary);
|
55
|
+
color : gray
|
56
|
+
}
|
57
|
+
|
58
|
+
/* Small vertical space. */
|
59
|
+
.smallGap {
|
60
|
+
padding: 0.125rem;
|
61
|
+
}
|
62
|
+
|
63
|
+
/* Medium vertical space. */
|
64
|
+
.medGap {
|
65
|
+
padding: 1rem;
|
66
|
+
}
|
67
|
+
|
68
|
+
/* Large vertical space. */
|
69
|
+
.largeGap {
|
70
|
+
padding: 8rem;
|
71
|
+
}
|
72
|
+
|
73
|
+
/* Grid for textarea label/elements. */
|
74
|
+
.access-options {
|
75
|
+
display : grid;
|
76
|
+
grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
|
77
|
+
column-gap : 2rem;
|
78
|
+
}
|
79
|
+
|
80
|
+
.access-option-container {
|
81
|
+
padding-left : 0 1rem 0 1rem;
|
82
|
+
display : flex;
|
83
|
+
flex-direction : column;
|
84
|
+
justify-content: flex-end;
|
85
|
+
}
|
86
|
+
|
87
|
+
[data-theme="dark"] .access-option-container.lm-only {
|
88
|
+
display: none;
|
89
|
+
}
|
90
|
+
|
91
|
+
/* Select boxes for accessibility options */
|
92
|
+
.access-option-container select {
|
93
|
+
min-width: 5rem;
|
94
|
+
width : 100%;
|
95
|
+
}
|
96
|
+
|
97
|
+
select#light-colour,
|
98
|
+
select#dark-background {
|
99
|
+
background-color: var(--ifm-color-primary);
|
100
|
+
color : var(--psdi-light-text-color-body);
|
101
|
+
}
|
102
|
+
|
103
|
+
select#size option {
|
104
|
+
font-family: var(--psdi-default-font);
|
105
|
+
}
|
106
|
+
|
107
|
+
select#font option {
|
108
|
+
font-size: var(--psdi-default-font-size);
|
109
|
+
}
|
110
|
+
|
111
|
+
select#dark-colour option {
|
112
|
+
color: var(--psdi-default-dark-text-color-body);
|
113
|
+
}
|
114
|
+
|
115
|
+
select#light-colour option {
|
116
|
+
background-color: var(--ifm-color-primary);
|
117
|
+
color : var(--psdi-default-light-text-color-body);
|
118
|
+
}
|
119
|
+
|
120
|
+
select#light-background option {
|
121
|
+
background-color: var(--psdi-default-background-color);
|
122
|
+
}
|
123
|
+
|
124
|
+
select#dark-background option {
|
125
|
+
background-color: var(--psdi-default-color-primary);
|
126
|
+
color : var(--psdi-light-text-color-body);
|
127
|
+
}
|
128
|
+
|
129
|
+
/* We use the service-mode variable to control whether elements with the "service-only" or "local-only" class are shown
|
130
|
+
*/
|
131
|
+
[service-mode=True] .local-only {
|
132
|
+
display: none;
|
133
|
+
}
|
134
|
+
|
135
|
+
[service-mode=False] .service-only {
|
136
|
+
display: none;
|
137
|
+
}
|
138
|
+
|
139
|
+
/* We use the production-mode variable to control whether elements with the "prod-only" or "dev-only" class are shown
|
140
|
+
*/
|
141
|
+
[production-mode=True] .prod-only {
|
142
|
+
display: none;
|
143
|
+
}
|
144
|
+
|
145
|
+
[production-mode=False] .dev-only {
|
146
|
+
display: none;
|
147
|
+
}
|