mirror of
https://github.com/ONLYOFFICE/onlyoffice.github.io.git
synced 2026-04-07 14:04:30 +08:00
enhance settings management
This commit is contained in:
@ -58,7 +58,8 @@
|
||||
<script defer src="scripts/zotero/zotero-api-checker.js"></script>
|
||||
<script defer src="scripts/zotero/zotero.js"></script>
|
||||
|
||||
<script defer src="scripts/connection.js"></script>
|
||||
<script defer src="scripts/login.js"></script>
|
||||
<script defer src="scripts/settings.js"></script>
|
||||
<script defer src="scripts/router.js"></script>
|
||||
<script defer src="scripts/code.js"></script>
|
||||
</head>
|
||||
@ -134,12 +135,12 @@
|
||||
</div>
|
||||
<div id="selectedInfo" class="hidden">
|
||||
<span id="selectedCount">0 selected</span>
|
||||
<span id="cancelBtn" class="i18n link">Cancel selection</span>
|
||||
<span id="cancelSelectBtn" class="i18n link">Cancel selection</span>
|
||||
</div>
|
||||
<div id="controlsHolder" class="flexCol">
|
||||
<div id="buttonsWrapper" class="flex" style="justify-content: space-between;">
|
||||
<button id="insertLinkBtn" class="i18n" disabled>Insert Citation</button>
|
||||
<button id="settingsBtn">
|
||||
<button id="settingsBtn" class="i18n" title="Configure how citations will be formatted in your document.">
|
||||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.07031 10C8.72717 10 10.0703 8.65685 10.0703 7C10.0703 5.34315 8.72717 4 7.07031 4C5.41346 4 4.07031 5.34315 4.07031 7C4.07031 8.65685 5.41346 10 7.07031 10ZM9.07031 7C9.07031 8.10457 8.17488 9 7.07031 9C5.96574 9 5.07031 8.10457 5.07031 7C5.07031 5.89543 5.96574 5 7.07031 5C8.17488 5 9.07031 5.89543 9.07031 7Z" fill="currentcolor" fill-opacity="0.8"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.4834 11.7324L13.9299 9.30047C14.0421 9.10329 14.0196 8.94992 13.8626 8.84038L12.3488 7.69014C12.3712 7.53678 12.3825 7.30673 12.3825 7C12.3825 6.69327 12.3712 6.46322 12.3488 6.30986L13.8626 5.15962C14.0196 5.05008 14.0421 4.89671 13.9299 4.69953L12.4834 2.26761C12.3937 2.11424 12.2479 2.07042 12.0461 2.13615L10.2631 2.82629C9.88186 2.54147 9.47817 2.31142 9.05206 2.13615L8.78294 0.295775C8.73809 0.0985915 8.62595 0 8.44654 0H5.55346C5.37405 0 5.26191 0.0985915 5.21706 0.295775L4.94794 2.13615C4.61153 2.26761 4.20785 2.49765 3.73688 2.82629L1.95394 2.13615C1.7521 2.07042 1.60633 2.11424 1.51662 2.26761L0.0700841 4.69953C-0.0420505 4.89671 -0.0196235 5.05008 0.137365 5.15962L1.65118 6.30986C1.62875 6.46322 1.61754 6.69327 1.61754 7C1.61754 7.30673 1.62875 7.53678 1.65118 7.69014L0.137365 8.84038C-0.0196235 8.94992 -0.0420505 9.10329 0.0700841 9.30047L1.51662 11.7324C1.60633 11.8858 1.7521 11.9296 1.95394 11.8638L3.73688 11.1737C4.11814 11.4585 4.52183 11.6886 4.94794 11.8638L5.21706 13.7042C5.26191 13.9014 5.37405 14 5.55346 14H8.44654C8.62595 14 8.73809 13.9014 8.78294 13.7042L9.05206 11.8638C9.38847 11.7324 9.79215 11.5023 10.2631 11.1737L12.0461 11.8638C12.2479 11.9296 12.3937 11.8858 12.4834 11.7324ZM11.3593 7.54545L11.274 8.12935L12.7816 9.2749L11.9107 10.7391L10.1275 10.0489L9.69087 10.3536C9.25147 10.6602 8.92091 10.8415 8.6881 10.9324L8.14669 11.144L7.87529 13H6.12472L5.85501 11.1557L5.32835 10.939C4.98235 10.7967 4.65163 10.6088 4.33537 10.3726L3.89201 10.0414L2.08935 10.7391L1.2184 9.2749L2.72604 8.12935L2.64066 7.54545C2.6291 7.46641 2.61754 7.2955 2.61754 7C2.61754 6.7045 2.6291 6.53359 2.64066 6.45455L2.72604 5.87065L1.2184 4.7251L2.08935 3.26086L3.87247 3.95107L4.30913 3.64637C4.74853 3.33976 5.07909 3.15854 5.3119 3.06756L5.85331 2.856L6.12472 1H7.87529L8.14499 2.84433L8.67165 3.06097C9.01765 3.20329 9.34837 3.39116 9.66463 3.62742L10.108 3.95864L11.9107 3.26086L12.7816 4.7251L11.274 5.87065L11.3593 6.45455C11.3709 6.53359 11.3825 6.7045 11.3825 7C11.3825 7.2955 11.3709 7.46641 11.3593 7.54545Z" fill="currentcolor" fill-opacity="0.8"/>
|
||||
@ -155,7 +156,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="configState" class="hidden">
|
||||
<div id="settingsState" class="hidden">
|
||||
<p>
|
||||
<span class="i18n">Configure how citations will be formatted in your document.</span>
|
||||
</p>
|
||||
@ -170,69 +171,10 @@
|
||||
<div id="styleSelectedListOther" class="selectList hidden form-control"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="label styleWrapperSecond">
|
||||
<label for="styleLang" class="i18n">Language</label>
|
||||
<div class="selectHolder">
|
||||
<input id="styleLang" readonly class="form-control control select" type="text">
|
||||
<div id="styleLangList" class="selectList hidden">
|
||||
<span data-value="af-ZA">Afrikaans</span>
|
||||
<span data-value="ar">Arabic</span>
|
||||
<span data-value="bg-BG">Bulgarian</span>
|
||||
<span data-value="ca-AD">Catalan</span>
|
||||
<span data-value="cs-CZ">Czech</span>
|
||||
<span data-value="cy-GB">Welsh</span>
|
||||
<span data-value="da-DK">Danish</span>
|
||||
<span data-value="de-AT">German (Austria)</span>
|
||||
<span data-value="de-CH">German (Switzerland)</span>
|
||||
<span data-value="de-DE">German (Germany)</span>
|
||||
<span data-value="el-GR">Greek</span>
|
||||
<span data-value="en-GB">English (UK)</span>
|
||||
<span data-value="en-US">English (US)</span>
|
||||
<span data-value="es-CL">Spanish (Chile)</span>
|
||||
<span data-value="es-ES">Spanish (Spain)</span>
|
||||
<span data-value="es-MX">Spanish (Mexico)</span>
|
||||
<span data-value="et-EE">Estonian</span>
|
||||
<span data-value="eu">Basque</span>
|
||||
<span data-value="fa-IR">Persian</span>
|
||||
<span data-value="fi-FI">Finnish</span>
|
||||
<span data-value="fr-CA">French (Canada)</span>
|
||||
<span data-value="fr-FR">French (France)</span>
|
||||
<span data-value="he-IL">Hebrew</span>
|
||||
<span data-value="hr-HR">Croatian</span>
|
||||
<span data-value="hu-HU">Hungarian</span>
|
||||
<span data-value="id-ID">Indonesian</span>
|
||||
<span data-value="is-IS">Icelandic</span>
|
||||
<span data-value="it-IT">Italian</span>
|
||||
<span data-value="ja-JP">Japanese</span>
|
||||
<span data-value="km-KH">Khmer</span>
|
||||
<span data-value="ko-KR">Korean</span>
|
||||
<span data-value="la">Latin</span>
|
||||
<span data-value="lt-LT">Lithuanian</span>
|
||||
<span data-value="lv-LV">Latvian</span>
|
||||
<span data-value="mn-MN">Mongolian</span>
|
||||
<span data-value="nb-NO">Norwegian (Bokmål)</span>
|
||||
<span data-value="nl-NL">Dutch</span>
|
||||
<span data-value="nn-NO">Norwegian (Nynorsk)</span>
|
||||
<span data-value="pl-PL">Polish</span>
|
||||
<span data-value="pt-BR">Portuguese (Brazil)</span>
|
||||
<span data-value="pt-PT">Portuguese (Portugal)</span>
|
||||
<span data-value="ro-RO">Romanian</span>
|
||||
<span data-value="ru-RU">Russian</span>
|
||||
<span data-value="sk-SK">Slovak</span>
|
||||
<span data-value="sl-SI">Slovenian</span>
|
||||
<span data-value="sr-RS">Serbian</span>
|
||||
<span data-value="sv-SE">Swedish</span>
|
||||
<span data-value="th-TH">Thai</span>
|
||||
<span data-value="tr-TR">Turkish</span>
|
||||
<span data-value="uk-UA">Ukrainian</span>
|
||||
<span data-value="vi-VN">Vietnamese</span>
|
||||
<span data-value="zh-CN">Chinese (PRC)</span>
|
||||
<span data-value="zh-TW">Chinese (Taiwan)</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="styleLangList"></div>
|
||||
|
||||
<div id="notesStyle" class="notesStyle hidden">
|
||||
<span class="i18n">Display citations as:</span>
|
||||
<div class="radioHolder">
|
||||
@ -243,6 +185,8 @@
|
||||
<label for="endNotes" class="i18n">Endnotes</label>
|
||||
</div>
|
||||
</div>
|
||||
<button id="saveSettingsBtn" class="i18n">Done</button>
|
||||
<button id="cancelBtn" class="i18n">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@ -59,6 +59,7 @@ html {
|
||||
.custom-button {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
@ -419,6 +420,7 @@ body.theme-dark .custom-button-container {
|
||||
font-size: 22px;
|
||||
line-height: 0;
|
||||
transition: all 0.2s ease;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
/* Counter */
|
||||
|
||||
@ -136,22 +136,17 @@ input[type="text"] {
|
||||
|
||||
#searchWrapper {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
justify-content: space-between;
|
||||
position: relative;
|
||||
margin-top: 13px;
|
||||
}
|
||||
#searchWrapper .input-field-container-searchField {
|
||||
width: 207px;
|
||||
}
|
||||
#searchWrapper .selectbox-container {
|
||||
position: absolute;
|
||||
}
|
||||
#searchWrapper .selectbox-container .selectbox-header {
|
||||
opacity: 0;
|
||||
}
|
||||
#searchField {
|
||||
width: 207px;
|
||||
}
|
||||
|
||||
#controlsHolder {
|
||||
padding-top: 4px;
|
||||
@ -160,8 +155,8 @@ input[type="text"] {
|
||||
#controlsHolder button {
|
||||
margin-top: 8px;
|
||||
}
|
||||
#controlsHolder .custom-button-primary {
|
||||
width: 207px;
|
||||
#controlsHolder .custom-button-container:first-child {
|
||||
width: calc(100% - 28px);
|
||||
}
|
||||
#controlsHolder .custom-button-secondary {
|
||||
width: 100%;
|
||||
@ -256,11 +251,6 @@ input[type="text"] {
|
||||
transform: rotateZ(-45deg);
|
||||
}
|
||||
|
||||
|
||||
#styleLangList {
|
||||
right: 0px;
|
||||
}
|
||||
|
||||
.selectList {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@ -342,7 +332,7 @@ input[type="text"] {
|
||||
box-sizing: border-box;
|
||||
margin-top: 6px;
|
||||
padding: 4px 6px 6px 6px;
|
||||
height: 51px;
|
||||
max-height: 51px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.page0 > .doc:first-child {
|
||||
@ -390,8 +380,7 @@ input[type="text"] {
|
||||
}
|
||||
|
||||
.doc.doc-open {
|
||||
height: auto;
|
||||
overflow: visible;
|
||||
max-height: none;
|
||||
}
|
||||
.doc-open .selectbox-arrow {
|
||||
transform: rotate(180deg);
|
||||
|
||||
@ -23,26 +23,19 @@
|
||||
/// <reference path="./zotero/zotero.js" />
|
||||
/// <reference path="./csl/citation/citation.js" />
|
||||
/// <reference path="./csl/citation/storage.js" />
|
||||
/// <reference path="./csl/styles/styles-manager.js" />
|
||||
/// <reference path="./csl/locales/locales-manager.js" />
|
||||
/// <reference path="./services/translate-service.js" />
|
||||
/// <reference path="./services/citation-service.js" />
|
||||
/// <reference path="./shared/components/search-filter.js" />
|
||||
/// <reference path="./shared/components/select-citation.js" />
|
||||
/// <reference path="./shared/ui/input.js" />
|
||||
/// <reference path="./shared/ui/selectbox.js" />
|
||||
/// <reference path="./shared/ui/button.js" />
|
||||
/// <reference path="./connection.js" />
|
||||
/// <reference path="./login.js" />
|
||||
/// <reference path="./settings.js" />
|
||||
|
||||
(function () {
|
||||
var counter = 0; // счетчик отправленных запросов (используется чтобы знать показывать "not found" или нет)
|
||||
var displayNoneClass = "hidden";
|
||||
var blurClass = "blur";
|
||||
|
||||
//var loadingStyle = false;
|
||||
//var loadingLocale = false;
|
||||
var bNumFormat = false;
|
||||
|
||||
// TODO добавить ещё обработку событий (удаление линков) их не нужно удалять
|
||||
// из библиографии автоматически (это делать только при обновлении библиографии
|
||||
// или refresh), но их точно нужно удалить из formatter!
|
||||
@ -52,7 +45,7 @@
|
||||
// TODO сейчас всегда делаем полный refresh при каждом действии
|
||||
// (обновлении, вставке линков, вставке библиографии), потому что мы не знаем
|
||||
// что поменялось без событий (потом добавить ещё сравнение контента)
|
||||
// TODO ms меняет линки (если стиль с нумерацией bNumFormat) делает их по порядку
|
||||
// TODO ms меняет линки (если стиль с нумерацией settings._bNumFormat) делает их по порядку
|
||||
// как документе (для этого нужно знать где именно в документе мы вставляем цитату,
|
||||
// какая цитата сверху и снизу от текущего курсора)
|
||||
|
||||
@ -60,12 +53,10 @@
|
||||
var router;
|
||||
/** @type {ZoteroSdk} */
|
||||
var sdk;
|
||||
/** @type {ConnectingToApi} */
|
||||
var connectingToApi;
|
||||
/** @type {CslStylesManager} */
|
||||
var cslStylesManager;
|
||||
/** @type {LocalesManager} */
|
||||
var localesManager;
|
||||
|
||||
/** @type {SettingsPage} */
|
||||
var settings;
|
||||
|
||||
/** @type {CitationService} */
|
||||
var citationService;
|
||||
|
||||
@ -86,8 +77,6 @@
|
||||
/** @type {Button} */
|
||||
var insertLinkBtn;
|
||||
/** @type {Button} */
|
||||
var settingsBtn;
|
||||
/** @type {Button} */
|
||||
var insertBibBtn;
|
||||
/** @type {Button} */
|
||||
var refreshBtn;
|
||||
@ -111,62 +100,16 @@
|
||||
throw new Error("contentHolder not found");
|
||||
}
|
||||
|
||||
const loginState = document.getElementById("loginState");
|
||||
if (!loginState) {
|
||||
throw new Error("loginState not found");
|
||||
}
|
||||
const mainState = document.getElementById("mainState");
|
||||
if (!mainState) {
|
||||
throw new Error("mainState not found");
|
||||
}
|
||||
|
||||
const styleWrapper = document.getElementById("styleWrapper");
|
||||
if (!styleWrapper) {
|
||||
throw new Error("styleWrapper not found");
|
||||
}
|
||||
const styleSelectList = document.getElementById("styleSelectList");
|
||||
if (!styleSelectList) {
|
||||
throw new Error("styleSelectList not found");
|
||||
}
|
||||
const styleSelectListOther = document.getElementById(
|
||||
"styleSelectedListOther"
|
||||
);
|
||||
if (!styleSelectListOther) {
|
||||
throw new Error("styleSelectListOther not found");
|
||||
}
|
||||
const styleSelect = document.getElementById("styleSelect");
|
||||
if (!styleSelect) {
|
||||
throw new Error("styleSelect not found");
|
||||
}
|
||||
const styleLang = document.getElementById("styleLang");
|
||||
if (!styleLang) {
|
||||
throw new Error("styleLang not found");
|
||||
}
|
||||
const styleLangList = document.getElementById("styleLangList");
|
||||
if (!styleLangList) {
|
||||
throw new Error("styleLangList not found");
|
||||
}
|
||||
const notesStyleWrapper = document.getElementById("notesStyle");
|
||||
if (!notesStyleWrapper) {
|
||||
throw new Error("notesStyleWrapper not found");
|
||||
}
|
||||
const footNotes = document.getElementById("footNotes");
|
||||
if (!footNotes) {
|
||||
throw new Error("footNotes not found");
|
||||
}
|
||||
const endNotes = document.getElementById("endNotes");
|
||||
if (!endNotes) {
|
||||
throw new Error("endNotes not found");
|
||||
}
|
||||
const checkOmitAuthor = document.getElementById("omitAuthor");
|
||||
if (!checkOmitAuthor) {
|
||||
throw new Error("checkOmitAuthor not found");
|
||||
}
|
||||
|
||||
const cslFileInput = document.getElementById("cslFileInput");
|
||||
if (!cslFileInput) {
|
||||
throw new Error("cslFileInput not found");
|
||||
}
|
||||
searchFilter = new SearchFilterComponents();
|
||||
selectCitation = new SelectCitationsComponent(
|
||||
displayNoneClass,
|
||||
@ -179,10 +122,6 @@
|
||||
insertLinkBtn = new Button("insertLinkBtn", {
|
||||
disabled: true,
|
||||
});
|
||||
settingsBtn = new Button("settingsBtn", {
|
||||
variant: "icon-only",
|
||||
size: "small",
|
||||
});
|
||||
insertBibBtn = new Button("insertBibBtn", {
|
||||
variant: "secondary",
|
||||
});
|
||||
@ -195,22 +134,10 @@
|
||||
error: error,
|
||||
|
||||
contentHolder: contentHolder,
|
||||
loginState: loginState,
|
||||
|
||||
mainState: mainState,
|
||||
|
||||
styleWrapper: styleWrapper,
|
||||
styleSelectList: styleSelectList,
|
||||
styleSelectListOther: styleSelectListOther,
|
||||
styleSelect: styleSelect,
|
||||
styleLang: styleLang,
|
||||
styleLangList: styleLangList,
|
||||
notesStyleWrapper: notesStyleWrapper,
|
||||
footNotes: footNotes,
|
||||
endNotes: endNotes,
|
||||
|
||||
checkOmitAuthor: checkOmitAuthor,
|
||||
cslFileInput: cslFileInput,
|
||||
};
|
||||
}
|
||||
|
||||
@ -220,116 +147,36 @@
|
||||
|
||||
router = new Router();
|
||||
sdk = new ZoteroSdk();
|
||||
connectingToApi = new ConnectingToApi(router, sdk);
|
||||
cslStylesManager = new CslStylesManager();
|
||||
localesManager = new LocalesManager();
|
||||
const loginPage = new LoginPage(router, sdk);
|
||||
settings = new SettingsPage(router, displayNoneClass);
|
||||
citationService = new CitationService(
|
||||
localesManager,
|
||||
cslStylesManager,
|
||||
settings.getLocalesManager(),
|
||||
settings.getStyleManager(),
|
||||
sdk
|
||||
);
|
||||
|
||||
addEventListeners();
|
||||
initSelectBoxes();
|
||||
|
||||
const connector = connectingToApi.init();
|
||||
connector.onOpen(function () {
|
||||
showLoader(false);
|
||||
});
|
||||
connector.onChangeState(function (apis) {
|
||||
cslStylesManager.setDesktopApiAvailable(apis.desktop);
|
||||
cslStylesManager.setRestApiAvailable(apis.online);
|
||||
localesManager.setDesktopApiAvailable(apis.desktop);
|
||||
localesManager.setRestApiAvailable(apis.online);
|
||||
});
|
||||
connector.onAuthorized(function (apis) {
|
||||
showLoader(true);
|
||||
|
||||
Promise.all([
|
||||
loadGroups(),
|
||||
loadStyles(),
|
||||
preloadLastStyle(),
|
||||
initLanguageSelect(),
|
||||
]).then(function () {
|
||||
loginPage
|
||||
.init()
|
||||
.onOpen(function () {
|
||||
showLoader(false);
|
||||
});
|
||||
})
|
||||
.onChangeState(function (apis) {
|
||||
settings.setDesktopApiAvailable(apis.desktop);
|
||||
settings.setRestApiAvailable(apis.online);
|
||||
})
|
||||
.onAuthorized(function (apis) {
|
||||
showLoader(true);
|
||||
|
||||
addStylesEventListeners();
|
||||
});
|
||||
Promise.all([loadGroups(), settings.init()]).then(function () {
|
||||
showLoader(false);
|
||||
});
|
||||
});
|
||||
|
||||
window.Asc.plugin.onTranslate = applyTranslations;
|
||||
};
|
||||
|
||||
function preloadLastStyle() {
|
||||
var lastStyle = cslStylesManager.getLastUsedStyleId() || "ieee";
|
||||
return cslStylesManager.getStyle(lastStyle);
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Promise<string|null>}
|
||||
*/
|
||||
function initLanguageSelect() {
|
||||
const savedLang = localesManager.getLastUsedLanguage();
|
||||
const option = elements.styleLangList.querySelector(
|
||||
'[data-value="' + savedLang + '"]'
|
||||
);
|
||||
if (!option || !(elements.styleLang instanceof HTMLInputElement)) {
|
||||
console.error("initLanguageSelect: no option");
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
option.setAttribute("selected", "");
|
||||
elements.styleLang.value = option.textContent;
|
||||
elements.styleLang.setAttribute("data-value", savedLang);
|
||||
return localesManager.loadLocale(savedLang);
|
||||
}
|
||||
|
||||
/** @returns {Promise<void>} */
|
||||
function loadStyles() {
|
||||
return cslStylesManager
|
||||
.getStylesInfo()
|
||||
.then(
|
||||
/** @param {Array<StyleInfo>} stylesInfo*/ function (
|
||||
stylesInfo
|
||||
) {
|
||||
var openOtherStyleList = function (
|
||||
/** @type {HTMLElement} */ list
|
||||
) {
|
||||
return function (/** @type {MouseEvent} */ ev) {
|
||||
elements.styleSelectListOther.style.width =
|
||||
elements.styleWrapper.clientWidth - 2 + "px";
|
||||
ev.stopPropagation();
|
||||
openList(list);
|
||||
};
|
||||
};
|
||||
|
||||
addStylesToList(stylesInfo);
|
||||
|
||||
const el = document.createElement("hr");
|
||||
elements.styleSelectList.appendChild(el);
|
||||
|
||||
if (elements.styleSelectListOther.children.length > 0) {
|
||||
var other = document.createElement("span");
|
||||
other.textContent = "More Styles...";
|
||||
elements.styleSelectList.appendChild(other);
|
||||
other.onclick = openOtherStyleList(
|
||||
elements.styleSelectListOther
|
||||
);
|
||||
}
|
||||
|
||||
var custom = document.createElement("span");
|
||||
custom.setAttribute("class", "select-file");
|
||||
var label = document.createElement("label");
|
||||
label.setAttribute("for", "cslFileInput");
|
||||
label.textContent = "Add custom style...";
|
||||
custom.appendChild(label);
|
||||
elements.styleSelectList.appendChild(custom);
|
||||
}
|
||||
)
|
||||
.catch(function (err) {
|
||||
console.error(err);
|
||||
});
|
||||
}
|
||||
|
||||
/** @returns {Promise<void>} */
|
||||
function loadGroups() {
|
||||
return sdk
|
||||
@ -339,121 +186,9 @@
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Array<StyleInfo>} stylesInfo
|
||||
*/
|
||||
function addStylesToList(stylesInfo) {
|
||||
var lastStyle = cslStylesManager.getLastUsedStyleIdOrDefault();
|
||||
const styleSelect = elements.styleSelect;
|
||||
if (styleSelect instanceof HTMLInputElement === false) {
|
||||
console.error("styleSelect is not an input element");
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {HTMLElement} list - the list of styles where the element is added.
|
||||
* @param {HTMLElement} other - the list of styles where the element is removed.
|
||||
*/
|
||||
var onStyleSelectOther = function (list, other) {
|
||||
return function (/** @type {MouseEvent} */ ev) {
|
||||
let tmpEl = list.removeChild(
|
||||
list.children[list.children.length - 3]
|
||||
);
|
||||
var newEl = document.createElement("span");
|
||||
newEl.setAttribute(
|
||||
"data-value",
|
||||
String(tmpEl.getAttribute("data-value"))
|
||||
);
|
||||
newEl.textContent = tmpEl.textContent;
|
||||
other.appendChild(newEl);
|
||||
newEl.onclick = onStyleSelectOther(
|
||||
elements.styleSelectList,
|
||||
elements.styleSelectListOther
|
||||
);
|
||||
|
||||
if (ev.target instanceof HTMLElement === false) {
|
||||
console.error("ev.target is not an HTMLElement");
|
||||
return;
|
||||
}
|
||||
tmpEl = other.removeChild(ev.target);
|
||||
newEl = document.createElement("span");
|
||||
newEl.setAttribute(
|
||||
"data-value",
|
||||
String(tmpEl.getAttribute("data-value"))
|
||||
);
|
||||
newEl.textContent = tmpEl.textContent;
|
||||
list.insertBefore(newEl, list.firstElementChild);
|
||||
newEl.onclick = onClickListElement(
|
||||
elements.styleSelectList,
|
||||
styleSelect
|
||||
);
|
||||
var event = new Event("click");
|
||||
newEl.dispatchEvent(event);
|
||||
closeList();
|
||||
};
|
||||
};
|
||||
|
||||
for (var i = 0; i < stylesInfo.length; i++) {
|
||||
var el = document.createElement("span");
|
||||
el.setAttribute("data-value", stylesInfo[i].name);
|
||||
el.textContent = stylesInfo[i].title;
|
||||
if (
|
||||
cslStylesManager.isStyleDefault(stylesInfo[i].name) ||
|
||||
stylesInfo[i].name == lastStyle
|
||||
) {
|
||||
if (stylesInfo.length == 1)
|
||||
elements.styleSelectList.insertBefore(
|
||||
el,
|
||||
elements.styleSelectList.firstElementChild
|
||||
);
|
||||
else elements.styleSelectList.appendChild(el);
|
||||
el.onclick = onClickListElement(
|
||||
elements.styleSelectList,
|
||||
styleSelect
|
||||
);
|
||||
} else {
|
||||
elements.styleSelectListOther.appendChild(el);
|
||||
el.onclick = onStyleSelectOther(
|
||||
elements.styleSelectList,
|
||||
elements.styleSelectListOther
|
||||
);
|
||||
}
|
||||
if (stylesInfo[i].name == lastStyle) {
|
||||
el.setAttribute("selected", "");
|
||||
selectInput(styleSelect, el, elements.styleSelectList, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function addEventListeners() {
|
||||
selectCitation.subscribe(checkSelected);
|
||||
|
||||
elements.cslFileInput.onchange = function (e) {
|
||||
if (!(e.target instanceof HTMLInputElement)) return;
|
||||
/** @type {HTMLInputElement} */
|
||||
const target = e.target;
|
||||
if (!target.files) return;
|
||||
var file = target.files[0];
|
||||
if (!file) {
|
||||
console.error("No file selected");
|
||||
return;
|
||||
}
|
||||
//showLoader(true);
|
||||
|
||||
cslStylesManager
|
||||
.addCustomStyle(file)
|
||||
.then(function (styleValue) {
|
||||
addStylesToList([styleValue]);
|
||||
})
|
||||
.catch(function (error) {
|
||||
console.error(error);
|
||||
showError(translate("Failed to upload file"));
|
||||
})
|
||||
.finally(function () {
|
||||
showLoader(false);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} text
|
||||
* @param {Array<string|"my_library"|"group_libraries">} selectedGroups
|
||||
@ -538,11 +273,11 @@
|
||||
if (event.type !== "button:click") {
|
||||
return;
|
||||
}
|
||||
if (!cslStylesManager.getLastUsedStyleId()) {
|
||||
if (!settings.getLastUsedStyleId()) {
|
||||
showError(translate("Style is not selected"));
|
||||
return;
|
||||
}
|
||||
if (!localesManager.getLocale()) {
|
||||
if (!settings.getLocale()) {
|
||||
showError(translate("Language is not selected"));
|
||||
return;
|
||||
}
|
||||
@ -566,11 +301,11 @@
|
||||
if (event.type !== "button:click") {
|
||||
return;
|
||||
}
|
||||
if (!cslStylesManager.getLastUsedStyleId()) {
|
||||
if (!settings.getLastUsedStyleId()) {
|
||||
showError(translate("Style is not selected"));
|
||||
return;
|
||||
}
|
||||
if (!localesManager.getLocale()) {
|
||||
if (!settings.getLocale()) {
|
||||
showError(translate("Language is not selected"));
|
||||
return;
|
||||
}
|
||||
@ -596,11 +331,11 @@
|
||||
if (event.type !== "button:click") {
|
||||
return;
|
||||
}
|
||||
if (!cslStylesManager.getLastUsedStyleId()) {
|
||||
if (!settings.getLastUsedStyleId()) {
|
||||
showError(translate("Style is not selected"));
|
||||
return;
|
||||
}
|
||||
if (!localesManager.getLocale()) {
|
||||
if (!settings.getLocale()) {
|
||||
showError(translate("Language is not selected"));
|
||||
return;
|
||||
}
|
||||
@ -643,91 +378,12 @@
|
||||
showLoader(false);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function addStylesEventListeners() {
|
||||
/**
|
||||
* @param {Event|null} e - The input event.
|
||||
* @param {String} [filter] - The filter to apply on the style options.
|
||||
*/
|
||||
elements.styleSelect.oninput = function (e, filter) {
|
||||
var input = elements.styleSelect;
|
||||
if (!(input instanceof HTMLInputElement)) return;
|
||||
filter = filter !== undefined ? filter : input.value.toLowerCase();
|
||||
var list = elements.styleSelectList.classList.contains(
|
||||
displayNoneClass
|
||||
)
|
||||
? elements.styleSelectListOther
|
||||
: elements.styleSelectList;
|
||||
|
||||
for (var i = 0; i < list.children.length; i++) {
|
||||
const child = list.children[i];
|
||||
if (child instanceof HTMLElement === false) {
|
||||
continue;
|
||||
}
|
||||
var text = child.textContent || child.innerText;
|
||||
var hide = true;
|
||||
if (!filter || text.toLowerCase().indexOf(filter) > -1) {
|
||||
hide = false;
|
||||
}
|
||||
|
||||
switchClass(child, displayNoneClass, hide);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Event} inp - The input event.
|
||||
* @param {String} styleName - The name of the selected style.
|
||||
* @param {Boolean} isClick - Whether the style was selected manually or not.
|
||||
*/
|
||||
elements.styleSelect.onselectchange = function (
|
||||
inp,
|
||||
styleName,
|
||||
isClick
|
||||
) {
|
||||
isClick && showLoader(true);
|
||||
elements.styleSelect.oninput(inp, "");
|
||||
|
||||
return cslStylesManager
|
||||
.getStyle(styleName)
|
||||
.then(function (style) {
|
||||
onStyleChange();
|
||||
if (isClick) {
|
||||
return citationService.updateCslItems(
|
||||
true,
|
||||
true,
|
||||
false
|
||||
);
|
||||
}
|
||||
})
|
||||
.catch(function (err) {
|
||||
console.error(err);
|
||||
if (typeof err === "string") {
|
||||
showError(err);
|
||||
}
|
||||
})
|
||||
.finally(function () {
|
||||
isClick && showLoader(false);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Event} inp - The select change event.
|
||||
* @param {String} val - The value of the selected language.
|
||||
* @param {Boolean} isClick - Whether the language was selected manually or not.
|
||||
*/
|
||||
elements.styleLang.onselectchange = function (inp, val, isClick) {
|
||||
settings.onChangeState(function (/** @type {Promise<void>} */ promise) {
|
||||
showLoader(true);
|
||||
localesManager.saveLastUsedLanguage(val);
|
||||
localesManager
|
||||
.loadLocale(val)
|
||||
promise
|
||||
.then(function () {
|
||||
if (isClick)
|
||||
return citationService.updateCslItems(
|
||||
true,
|
||||
true,
|
||||
false
|
||||
);
|
||||
return citationService.updateCslItems(true, true, false);
|
||||
})
|
||||
.catch(function (error) {
|
||||
console.error(error);
|
||||
@ -738,27 +394,6 @@
|
||||
.finally(function () {
|
||||
showLoader(false);
|
||||
});
|
||||
};
|
||||
|
||||
elements.styleSelectList.onopen = function () {
|
||||
elements.styleSelectList.style.width =
|
||||
elements.styleWrapper.clientWidth - 2 + "px";
|
||||
};
|
||||
|
||||
[elements.footNotes, elements.endNotes].forEach(function (el) {
|
||||
el.addEventListener("change", function (event) {
|
||||
if (
|
||||
event.target instanceof HTMLInputElement &&
|
||||
event.target.checked
|
||||
) {
|
||||
const value = event.target.value;
|
||||
if (value === "endnotes" || value === "footnotes") {
|
||||
cslStylesManager.saveLastUsedNotesStyle(value);
|
||||
} else {
|
||||
console.error("Unknown notes style: " + value);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@ -827,160 +462,6 @@
|
||||
body.classList.add("theme-" + themeType);
|
||||
};
|
||||
|
||||
/** @type {HTMLElement[]} */
|
||||
var selectLists = [];
|
||||
function initSelectBoxes() {
|
||||
var select = document.getElementsByClassName("control select");
|
||||
for (var i = 0; i < select.length; i++) {
|
||||
var input = select[i];
|
||||
var holder = input.parentElement;
|
||||
if (!(input instanceof HTMLInputElement) || !holder) {
|
||||
console.error("initSelectBoxes: no input or holder");
|
||||
continue;
|
||||
}
|
||||
|
||||
var arrow = document.createElement("span");
|
||||
arrow.classList.add("selectArrow");
|
||||
arrow.appendChild(document.createElement("span"));
|
||||
arrow.appendChild(document.createElement("span"));
|
||||
holder.appendChild(arrow);
|
||||
|
||||
for (
|
||||
var k = 0;
|
||||
k < holder.getElementsByClassName("selectList").length;
|
||||
k++
|
||||
) {
|
||||
var list = holder.getElementsByClassName("selectList")[k];
|
||||
if (list.children.length > 0) {
|
||||
for (var j = 0; j < list.children.length; j++) {
|
||||
const child = list.children[j];
|
||||
if (child instanceof HTMLElement === false) {
|
||||
continue;
|
||||
}
|
||||
child.onclick = onClickListElement(list, input);
|
||||
}
|
||||
// selectInput(input, list.children[0], list, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {HTMLElement} list
|
||||
* @param {HTMLElement} input
|
||||
* @returns {function}
|
||||
*/
|
||||
var fOpen = function (list, input) {
|
||||
return function (/** @type {MouseEvent} */ ev) {
|
||||
ev.stopPropagation();
|
||||
if (
|
||||
!elements.styleSelectListOther.classList.contains(
|
||||
displayNoneClass
|
||||
)
|
||||
)
|
||||
return true;
|
||||
|
||||
if (list.onopen) {
|
||||
list.onopen();
|
||||
}
|
||||
if (!input.hasAttribute("readonly")) {
|
||||
input.select();
|
||||
}
|
||||
openList(list);
|
||||
|
||||
return true;
|
||||
};
|
||||
};
|
||||
|
||||
if (k !== 1) {
|
||||
input.onclick = fOpen(list, input);
|
||||
arrow.onclick = fOpen(list, input);
|
||||
}
|
||||
selectLists.push(list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {HTMLElement} el
|
||||
*/
|
||||
function openList(el) {
|
||||
switchClass(el, displayNoneClass, false);
|
||||
window.addEventListener("click", closeList);
|
||||
}
|
||||
|
||||
function closeList() {
|
||||
window.removeEventListener("click", closeList);
|
||||
for (var i = 0; i < selectLists.length; i++) {
|
||||
if (selectLists[i] === elements.styleSelectList)
|
||||
elements.styleSelect.oninput(null, "");
|
||||
switchClass(selectLists[i], displayNoneClass, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {HTMLInputElement} input
|
||||
* @param {HTMLElement} el
|
||||
* @param {HTMLElement} list
|
||||
* @param {boolean} isClick
|
||||
*/
|
||||
function selectInput(input, el, list, isClick) {
|
||||
input.value = el.textContent;
|
||||
var val = el.getAttribute("data-value") || "";
|
||||
input.setAttribute("data-value", val);
|
||||
input.setAttribute("title", el.textContent);
|
||||
if (input.onselectchange) {
|
||||
input.onselectchange(input, val, isClick);
|
||||
}
|
||||
switchClass(list, displayNoneClass, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Element} list
|
||||
* @param {HTMLInputElement} input
|
||||
*/
|
||||
function onClickListElement(list, input) {
|
||||
return function (/** @type {MouseEvent} */ ev) {
|
||||
if (!ev.target || !(ev.target instanceof HTMLElement)) {
|
||||
console.error("onClickListElement: no target");
|
||||
return;
|
||||
}
|
||||
var sel = ev.target.getAttribute("data-value");
|
||||
for (var i = 0; i < list.children.length; i++) {
|
||||
const temp = list.children[i];
|
||||
if (temp instanceof HTMLElement === false) continue;
|
||||
/** @type {HTMLElement} */
|
||||
const child = temp;
|
||||
if (list.children[i].getAttribute("data-value") == sel) {
|
||||
list.children[i].setAttribute("selected", "");
|
||||
|
||||
selectInput(input, child, list, true);
|
||||
} else {
|
||||
if (list.children[i].hasAttribute("selected")) {
|
||||
list.children[i].attributes.removeNamedItem("selected");
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function onStyleChange() {
|
||||
let styleFormat = cslStylesManager.getLastUsedFormat();
|
||||
citationService.setStyleFormat(styleFormat);
|
||||
bNumFormat = styleFormat == "numeric";
|
||||
if ("note" === styleFormat) {
|
||||
elements.notesStyleWrapper.classList.remove(displayNoneClass);
|
||||
} else {
|
||||
elements.notesStyleWrapper.classList.add(displayNoneClass);
|
||||
}
|
||||
|
||||
let notesStyle = cslStylesManager.getLastUsedNotesStyle();
|
||||
citationService.setNotesStyle(notesStyle);
|
||||
const notesAs = elements.notesStyleWrapper.querySelector(
|
||||
'input[name="notesAs"][value="' + notesStyle + '"]'
|
||||
);
|
||||
if (notesAs && notesAs instanceof HTMLInputElement) {
|
||||
notesAs.checked = true;
|
||||
}
|
||||
}
|
||||
|
||||
function applyTranslations() {
|
||||
var elements = document.getElementsByClassName("i18n");
|
||||
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
* @param {Router} router
|
||||
* @param {ZoteroSdk} sdk
|
||||
*/
|
||||
function ConnectingToApi(router, sdk) {
|
||||
function LoginPage(router, sdk) {
|
||||
this._router = router;
|
||||
this._sdk = sdk;
|
||||
this._apiKeyLoginField = new InputField("apiKeyField", {
|
||||
@ -48,7 +48,7 @@ function ConnectingToApi(router, sdk) {
|
||||
this._onOpen = function () {};
|
||||
}
|
||||
|
||||
ConnectingToApi.prototype.init = function () {
|
||||
LoginPage.prototype.init = function () {
|
||||
const self = this;
|
||||
this._addEventListeners();
|
||||
let hasFirstAnswer = false;
|
||||
@ -90,29 +90,34 @@ ConnectingToApi.prototype.init = function () {
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
const triggers = {
|
||||
/**
|
||||
* @param {function(AvailableApis): void} callbackFn
|
||||
* @param {function(): void} callbackFn
|
||||
*/
|
||||
onAuthorized: function (callbackFn) {
|
||||
self._onAuthorized = callbackFn;
|
||||
onOpen: function (callbackFn) {
|
||||
self._onOpen = callbackFn;
|
||||
return triggers;
|
||||
},
|
||||
/**
|
||||
* @param {function(AvailableApis): void} callbackFn
|
||||
*/
|
||||
onChangeState: function (callbackFn) {
|
||||
self._onChangeState = callbackFn;
|
||||
return triggers;
|
||||
},
|
||||
/**
|
||||
* @param {function(): void} callbackFn
|
||||
* @param {function(AvailableApis): void} callbackFn
|
||||
*/
|
||||
onOpen: function (callbackFn) {
|
||||
self._onOpen = callbackFn;
|
||||
onAuthorized: function (callbackFn) {
|
||||
self._onAuthorized = callbackFn;
|
||||
return triggers;
|
||||
},
|
||||
};
|
||||
|
||||
return triggers;
|
||||
};
|
||||
|
||||
ConnectingToApi.prototype._addEventListeners = function () {
|
||||
LoginPage.prototype._addEventListeners = function () {
|
||||
const self = this;
|
||||
this._apiKeyLoginField.subscribe(function (event) {
|
||||
if (event.type !== "inputfield:input") {
|
||||
@ -176,22 +181,19 @@ ConnectingToApi.prototype._addEventListeners = function () {
|
||||
};
|
||||
};
|
||||
|
||||
ConnectingToApi.prototype._hideAllMessages = function () {
|
||||
LoginPage.prototype._hideAllMessages = function () {
|
||||
this._apiKeyMessage.close();
|
||||
};
|
||||
|
||||
/** @param {string} apiKey */
|
||||
ConnectingToApi.prototype._onClickSave = function (apiKey) {};
|
||||
|
||||
/** @param {boolean} [bShowLogoutLink] */
|
||||
ConnectingToApi.prototype._hide = function (bShowLogoutLink) {
|
||||
LoginPage.prototype._hide = function (bShowLogoutLink) {
|
||||
this._router.openMain();
|
||||
if (bShowLogoutLink) {
|
||||
this._logoutLink.classList.remove("hidden");
|
||||
}
|
||||
};
|
||||
|
||||
ConnectingToApi.prototype._show = function () {
|
||||
LoginPage.prototype._show = function () {
|
||||
this._router.openLogin();
|
||||
this._logoutLink.classList.add("hidden");
|
||||
};
|
||||
@ -1,9 +1,9 @@
|
||||
// @ts-check
|
||||
|
||||
function Router() {
|
||||
this._states = ["mainState", "loginState"];
|
||||
this._routes = ["main", "login"];
|
||||
/** @type {"main"|"login"} */
|
||||
this._states = ["mainState", "loginState", "settingsState"];
|
||||
this._routes = ["main", "login", "settings"];
|
||||
/** @type {"main"|"login"|"settings"} */
|
||||
this._currentRoute = "login";
|
||||
this._currentRouteIndex = 1;
|
||||
this._containers = this._states.map(function (route) {
|
||||
@ -13,12 +13,12 @@ function Router() {
|
||||
});
|
||||
}
|
||||
|
||||
/** @returns {"main"|"login"} */
|
||||
/** @returns {"main"|"login"|"settings"} */
|
||||
Router.prototype.getRoute = function () {
|
||||
return this._currentRoute;
|
||||
};
|
||||
|
||||
/** @param {"main"|"login"} route */
|
||||
/** @param {"main"|"login"|"settings"} route */
|
||||
Router.prototype._setCurrentRoute = function (route) {
|
||||
this._containers[this._currentRouteIndex].classList.add("hidden");
|
||||
this._currentRoute = route;
|
||||
@ -33,3 +33,7 @@ Router.prototype.openMain = function () {
|
||||
Router.prototype.openLogin = function () {
|
||||
this._setCurrentRoute("login");
|
||||
};
|
||||
|
||||
Router.prototype.openSettings = function () {
|
||||
this._setCurrentRoute("settings");
|
||||
};
|
||||
|
||||
669
sdkjs-plugins/content/zotero/scripts/settings.js
Normal file
669
sdkjs-plugins/content/zotero/scripts/settings.js
Normal file
@ -0,0 +1,669 @@
|
||||
// @ts-check
|
||||
|
||||
/// <reference path="./router.js" />
|
||||
/// <reference path="./shared/ui/button.js" />
|
||||
/// <reference path="./shared/ui/selectbox.js" />
|
||||
/// <reference path="./shared/ui/message.js" />
|
||||
/// <reference path="./shared/ui/types.js" />
|
||||
/// <reference path="./services/translate-service.js" />
|
||||
/// <reference path="./csl/styles/styles-manager.js" />
|
||||
/// <reference path="./csl/locales/locales-manager.js" />
|
||||
|
||||
/**
|
||||
* @param {Router} router
|
||||
* @param {string} displayNoneClass
|
||||
*/
|
||||
function SettingsPage(router, displayNoneClass) {
|
||||
this._router = router;
|
||||
this._displayNoneClass = displayNoneClass;
|
||||
|
||||
this._openSettingsBtn = new Button("settingsBtn", {
|
||||
variant: "icon-only",
|
||||
size: "small",
|
||||
});
|
||||
this._saveBtn = new Button("saveSettingsBtn", {
|
||||
variant: "primary",
|
||||
});
|
||||
this._cancelBtn = new Button("cancelBtn", {
|
||||
variant: "secondary",
|
||||
});
|
||||
|
||||
this._styleWrapper = document.getElementById("styleWrapper");
|
||||
if (!this._styleWrapper) {
|
||||
throw new Error("styleWrapper not found");
|
||||
}
|
||||
this._styleSelectList = document.getElementById("styleSelectList");
|
||||
if (!this._styleSelectList) {
|
||||
throw new Error("styleSelectList not found");
|
||||
}
|
||||
this._styleSelectListOther = document.getElementById(
|
||||
"styleSelectedListOther"
|
||||
);
|
||||
if (!this._styleSelectListOther) {
|
||||
throw new Error("styleSelectListOther not found");
|
||||
}
|
||||
this._styleSelect = document.getElementById("styleSelect");
|
||||
if (!this._styleSelect) {
|
||||
throw new Error("styleSelect not found");
|
||||
}
|
||||
this._notesStyleWrapper = document.getElementById("notesStyle");
|
||||
if (!this._notesStyleWrapper) {
|
||||
throw new Error("notesStyleWrapper not found");
|
||||
}
|
||||
this._footNotes = document.getElementById("footNotes");
|
||||
if (!this._footNotes) {
|
||||
throw new Error("footNotes not found");
|
||||
}
|
||||
this._endNotes = document.getElementById("endNotes");
|
||||
if (!this._endNotes) {
|
||||
throw new Error("endNotes not found");
|
||||
}
|
||||
|
||||
this._cslFileInput = document.getElementById("cslFileInput");
|
||||
if (!this._cslFileInput) {
|
||||
throw new Error("cslFileInput not found");
|
||||
}
|
||||
|
||||
this._languageSelect = new SelectBox("styleLangList", {
|
||||
placeholder: "Select language",
|
||||
});
|
||||
|
||||
this._cslStylesManager = new CslStylesManager();
|
||||
this._localesManager = new LocalesManager();
|
||||
|
||||
/** @type {HTMLElement[]} */
|
||||
this._selectLists = [];
|
||||
/**
|
||||
* @param {Promise<void>} promise
|
||||
*/
|
||||
this._onChangeState = function (promise) {};
|
||||
this._apiKeyMessage = new Message("apiKeyMessage", { type: "error" });
|
||||
/** @type {Array<[string, string]>} */
|
||||
this._LANGUAGES = [
|
||||
["af-ZA", "Afrikaans"],
|
||||
["ar", "Arabic"],
|
||||
["bg-BG", "Bulgarian"],
|
||||
["ca-AD", "Catalan"],
|
||||
["cs-CZ", "Czech"],
|
||||
["cy-GB", "Welsh"],
|
||||
["da-DK", "Danish"],
|
||||
["de-AT", "German (Austria)"],
|
||||
["de-CH", "German (Switzerland)"],
|
||||
["de-DE", "German (Germany)"],
|
||||
["el-GR", "Greek"],
|
||||
["en-GB", "English (UK)"],
|
||||
["en-US", "English (US)"],
|
||||
["es-CL", "Spanish (Chile)"],
|
||||
["es-ES", "Spanish (Spain)"],
|
||||
["es-MX", "Spanish (Mexico)"],
|
||||
["et-EE", "Estonian"],
|
||||
["eu", "Basque"],
|
||||
["fa-IR", "Persian"],
|
||||
["fi-FI", "Finnish"],
|
||||
["fr-CA", "French (Canada)"],
|
||||
["fr-FR", "French (France)"],
|
||||
["he-IL", "Hebrew"],
|
||||
["hr-HR", "Croatian"],
|
||||
["hu-HU", "Hungarian"],
|
||||
["id-ID", "Indonesian"],
|
||||
["is-IS", "Icelandic"],
|
||||
["it-IT", "Italian"],
|
||||
["ja-JP", "Japanese"],
|
||||
["km-KH", "Khmer"],
|
||||
["ko-KR", "Korean"],
|
||||
["la", "Latin"],
|
||||
["lt-LT", "Lithuanian"],
|
||||
["lv-LV", "Latvian"],
|
||||
["mn-MN", "Mongolian"],
|
||||
["nb-NO", "Norwegian (Bokmål)"],
|
||||
["nl-NL", "Dutch"],
|
||||
["nn-NO", "Norwegian (Nynorsk)"],
|
||||
["pl-PL", "Polish"],
|
||||
["pt-BR", "Portuguese (Brazil)"],
|
||||
["pt-PT", "Portuguese (Portugal)"],
|
||||
["ro-RO", "Romanian"],
|
||||
["ru-RU", "Russian"],
|
||||
["sk-SK", "Slovak"],
|
||||
["sl-SI", "Slovenian"],
|
||||
["sr-RS", "Serbian"],
|
||||
["sv-SE", "Swedish"],
|
||||
["th-TH", "Thai"],
|
||||
["tr-TR", "Turkish"],
|
||||
["uk-UA", "Ukrainian"],
|
||||
["vi-VN", "Vietnamese"],
|
||||
["zh-CN", "Chinese (PRC)"],
|
||||
["zh-TW", "Chinese (Taiwan)"],
|
||||
];
|
||||
|
||||
this._bNumFormat = false;
|
||||
|
||||
this._initSelectBoxes();
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {LocalesManager}
|
||||
*/
|
||||
SettingsPage.prototype.getLocalesManager = function () {
|
||||
return this._localesManager;
|
||||
};
|
||||
|
||||
/**
|
||||
* @returns {CslStylesManager}
|
||||
*/
|
||||
SettingsPage.prototype.getStyleManager = function () {
|
||||
return this._cslStylesManager;
|
||||
};
|
||||
|
||||
/**
|
||||
* @returns {string|null}
|
||||
*/
|
||||
SettingsPage.prototype.getLocale = function () {
|
||||
return this._localesManager.getLocale();
|
||||
};
|
||||
|
||||
/**
|
||||
* @returns {string|null}
|
||||
*/
|
||||
SettingsPage.prototype.getLastUsedStyleId = function () {
|
||||
return this._cslStylesManager.getLastUsedStyleId();
|
||||
};
|
||||
|
||||
/**
|
||||
* @returns
|
||||
*/
|
||||
SettingsPage.prototype.init = function () {
|
||||
const self = this;
|
||||
var lastStyle = this._cslStylesManager.getLastUsedStyleId() || "ieee";
|
||||
const savedLang = this._localesManager.getLastUsedLanguage();
|
||||
this._addEventListeners();
|
||||
this._languageSelect.addItems(this._LANGUAGES, savedLang);
|
||||
|
||||
const promises = [
|
||||
this._cslStylesManager.getStyle(lastStyle),
|
||||
this._localesManager.loadLocale(savedLang),
|
||||
this._loadStyles(),
|
||||
];
|
||||
|
||||
return Promise.all(promises);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {function(Promise<void>): void} callbackFn
|
||||
*/
|
||||
SettingsPage.prototype.onChangeState = function (callbackFn) {
|
||||
this._onChangeState = callbackFn;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} isAvailable
|
||||
*/
|
||||
SettingsPage.prototype.setDesktopApiAvailable = function (isAvailable) {
|
||||
this._localesManager.setDesktopApiAvailable(isAvailable);
|
||||
this._cslStylesManager.setDesktopApiAvailable(isAvailable);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {boolean} isAvailable
|
||||
*/
|
||||
SettingsPage.prototype.setRestApiAvailable = function (isAvailable) {
|
||||
this._localesManager.setRestApiAvailable(isAvailable);
|
||||
this._cslStylesManager.setRestApiAvailable(isAvailable);
|
||||
};
|
||||
|
||||
SettingsPage.prototype._addEventListeners = function () {
|
||||
const self = this;
|
||||
|
||||
this._openSettingsBtn.subscribe(function (event) {
|
||||
if (event.type !== "button:click") {
|
||||
return;
|
||||
}
|
||||
self._show();
|
||||
});
|
||||
this._saveBtn.subscribe(function (event) {
|
||||
if (event.type !== "button:click") {
|
||||
return;
|
||||
}
|
||||
const selectedLang = self._languageSelect.getSelectedValue();
|
||||
if (selectedLang === null) {
|
||||
console.error("No language selected");
|
||||
return;
|
||||
}
|
||||
const promises = [];
|
||||
if (self._localesManager.getLastUsedLanguage() !== selectedLang) {
|
||||
self._localesManager.saveLastUsedLanguage(selectedLang);
|
||||
promises.push(self._localesManager.loadLocale(selectedLang));
|
||||
}
|
||||
|
||||
if (promises.length) {
|
||||
self._onChangeState(
|
||||
Promise.all(promises).then(function () {
|
||||
self._hide();
|
||||
})
|
||||
);
|
||||
}
|
||||
});
|
||||
this._cancelBtn.subscribe(function (event) {
|
||||
if (event.type !== "button:click") {
|
||||
return;
|
||||
}
|
||||
self._hide();
|
||||
});
|
||||
|
||||
this._cslFileInput.onchange = function (e) {
|
||||
if (!(e.target instanceof HTMLInputElement)) return;
|
||||
/** @type {HTMLInputElement} */
|
||||
const target = e.target;
|
||||
if (!target.files) return;
|
||||
var file = target.files[0];
|
||||
if (!file) {
|
||||
console.error("No file selected");
|
||||
return;
|
||||
}
|
||||
//showLoader(true);
|
||||
|
||||
self._cslStylesManager
|
||||
.addCustomStyle(file)
|
||||
.then(function (styleValue) {
|
||||
self._addStylesToList([styleValue]);
|
||||
})
|
||||
.catch(function (error) {
|
||||
console.error(error);
|
||||
showError(translate("Failed to upload file"));
|
||||
})
|
||||
.finally(function () {
|
||||
showLoader(false);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Event|null} e - The input event.
|
||||
* @param {String} [filter] - The filter to apply on the style options.
|
||||
*/
|
||||
this._styleSelect.oninput = function (e, filter) {
|
||||
var input = self._styleSelect;
|
||||
if (!(input instanceof HTMLInputElement)) return;
|
||||
filter = filter !== undefined ? filter : input.value.toLowerCase();
|
||||
var list = self._styleSelectList.classList.contains(
|
||||
self._displayNoneClass
|
||||
)
|
||||
? self._styleSelectListOther
|
||||
: self._styleSelectList;
|
||||
|
||||
for (var i = 0; i < list.children.length; i++) {
|
||||
const child = list.children[i];
|
||||
if (child instanceof HTMLElement === false) {
|
||||
continue;
|
||||
}
|
||||
var text = child.textContent || child.innerText;
|
||||
if (!filter || text.toLowerCase().indexOf(filter) > -1) {
|
||||
child.classList.remove(self._displayNoneClass);
|
||||
} else {
|
||||
child.classList.add(self._displayNoneClass);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Event} inp - The input event.
|
||||
* @param {String} styleName - The name of the selected style.
|
||||
* @param {Boolean} isClick - Whether the style was selected manually or not.
|
||||
*/
|
||||
this._styleSelect.onselectchange = function (inp, styleName, isClick) {
|
||||
isClick && self._showLoader(true);
|
||||
self._styleSelect.oninput(inp, "");
|
||||
|
||||
return self._cslStylesManager
|
||||
.getStyle(styleName)
|
||||
.then(function (style) {
|
||||
self._onStyleChange();
|
||||
if (isClick) {
|
||||
return self._citationService.updateCslItems(
|
||||
true,
|
||||
true,
|
||||
false
|
||||
);
|
||||
}
|
||||
})
|
||||
.catch(function (err) {
|
||||
console.error(err);
|
||||
if (typeof err === "string") {
|
||||
self._showError(err);
|
||||
}
|
||||
})
|
||||
.finally(function () {
|
||||
isClick && self._showLoader(false);
|
||||
});
|
||||
};
|
||||
|
||||
this._styleSelectList.onopen = function () {
|
||||
self._styleSelectList.style.width =
|
||||
self._styleWrapper.clientWidth - 2 + "px";
|
||||
};
|
||||
|
||||
[this._footNotes, this._endNotes].forEach(function (el) {
|
||||
el.addEventListener("change", function (event) {
|
||||
if (
|
||||
event.target instanceof HTMLInputElement &&
|
||||
event.target.checked
|
||||
) {
|
||||
const value = event.target.value;
|
||||
if (value === "endnotes" || value === "footnotes") {
|
||||
self._cslStylesManager.saveLastUsedNotesStyle(value);
|
||||
} else {
|
||||
console.error("Unknown notes style: " + value);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
SettingsPage.prototype._hideAllMessages = function () {
|
||||
this._apiKeyMessage.close();
|
||||
};
|
||||
|
||||
SettingsPage.prototype._hide = function () {
|
||||
this._router.openMain();
|
||||
};
|
||||
|
||||
SettingsPage.prototype._show = function () {
|
||||
this._router.openSettings();
|
||||
};
|
||||
|
||||
/** @returns {Promise<void>} */
|
||||
SettingsPage.prototype._loadStyles = function () {
|
||||
const self = this;
|
||||
return this._cslStylesManager
|
||||
.getStylesInfo()
|
||||
.then(
|
||||
/** @param {Array<StyleInfo>} stylesInfo*/ function (stylesInfo) {
|
||||
var openOtherStyleList = function (
|
||||
/** @type {HTMLElement} */ list
|
||||
) {
|
||||
return function (/** @type {MouseEvent} */ ev) {
|
||||
self._styleSelectListOther.style.width =
|
||||
self._styleWrapper.clientWidth - 2 + "px";
|
||||
ev.stopPropagation();
|
||||
self._openList(list);
|
||||
};
|
||||
};
|
||||
|
||||
self._addStylesToList(stylesInfo);
|
||||
|
||||
const el = document.createElement("hr");
|
||||
self._styleSelectList.appendChild(el);
|
||||
|
||||
if (self._styleSelectListOther.children.length > 0) {
|
||||
var other = document.createElement("span");
|
||||
other.textContent = "More Styles...";
|
||||
self._styleSelectList.appendChild(other);
|
||||
other.onclick = openOtherStyleList(
|
||||
self._styleSelectListOther
|
||||
);
|
||||
}
|
||||
|
||||
var custom = document.createElement("span");
|
||||
custom.setAttribute("class", "select-file");
|
||||
var label = document.createElement("label");
|
||||
label.setAttribute("for", "cslFileInput");
|
||||
label.textContent = "Add custom style...";
|
||||
custom.appendChild(label);
|
||||
self._styleSelectList.appendChild(custom);
|
||||
}
|
||||
)
|
||||
.catch(function (err) {
|
||||
console.error(err);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Array<StyleInfo>} stylesInfo
|
||||
*/
|
||||
SettingsPage.prototype._addStylesToList = function (stylesInfo) {
|
||||
const self = this;
|
||||
var lastStyle = this._cslStylesManager.getLastUsedStyleIdOrDefault();
|
||||
const styleSelect = this._styleSelect;
|
||||
if (styleSelect instanceof HTMLInputElement === false) {
|
||||
console.error("styleSelect is not an input element");
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {HTMLElement} list - the list of styles where the element is added.
|
||||
* @param {HTMLElement} other - the list of styles where the element is removed.
|
||||
*/
|
||||
var onStyleSelectOther = function (list, other) {
|
||||
return function (/** @type {MouseEvent} */ ev) {
|
||||
let tmpEl = list.removeChild(
|
||||
list.children[list.children.length - 3]
|
||||
);
|
||||
var newEl = document.createElement("span");
|
||||
newEl.setAttribute(
|
||||
"data-value",
|
||||
String(tmpEl.getAttribute("data-value"))
|
||||
);
|
||||
newEl.textContent = tmpEl.textContent;
|
||||
other.appendChild(newEl);
|
||||
newEl.onclick = onStyleSelectOther(
|
||||
self._styleSelectList,
|
||||
self._styleSelectListOther
|
||||
);
|
||||
|
||||
if (ev.target instanceof HTMLElement === false) {
|
||||
console.error("ev.target is not an HTMLElement");
|
||||
return;
|
||||
}
|
||||
tmpEl = other.removeChild(ev.target);
|
||||
newEl = document.createElement("span");
|
||||
newEl.setAttribute(
|
||||
"data-value",
|
||||
String(tmpEl.getAttribute("data-value"))
|
||||
);
|
||||
newEl.textContent = tmpEl.textContent;
|
||||
list.insertBefore(newEl, list.firstElementChild);
|
||||
newEl.onclick = self._onClickListElement(
|
||||
self._styleSelectList,
|
||||
styleSelect
|
||||
);
|
||||
var event = new Event("click");
|
||||
newEl.dispatchEvent(event);
|
||||
self._closeList();
|
||||
};
|
||||
};
|
||||
|
||||
for (var i = 0; i < stylesInfo.length; i++) {
|
||||
var el = document.createElement("span");
|
||||
el.setAttribute("data-value", stylesInfo[i].name);
|
||||
el.textContent = stylesInfo[i].title;
|
||||
if (
|
||||
self._cslStylesManager.isStyleDefault(stylesInfo[i].name) ||
|
||||
stylesInfo[i].name == lastStyle
|
||||
) {
|
||||
if (stylesInfo.length == 1)
|
||||
self._styleSelectList.insertBefore(
|
||||
el,
|
||||
self._styleSelectList.firstElementChild
|
||||
);
|
||||
else self._styleSelectList.appendChild(el);
|
||||
el.onclick = self._onClickListElement(
|
||||
self._styleSelectList,
|
||||
styleSelect
|
||||
);
|
||||
} else {
|
||||
self._styleSelectListOther.appendChild(el);
|
||||
el.onclick = onStyleSelectOther(
|
||||
self._styleSelectList,
|
||||
self._styleSelectListOther
|
||||
);
|
||||
}
|
||||
if (stylesInfo[i].name == lastStyle) {
|
||||
el.setAttribute("selected", "");
|
||||
self._selectInput(styleSelect, el, self._styleSelectList, false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
SettingsPage.prototype._onStyleChange = function () {
|
||||
let styleFormat = this._cslStylesManager.getLastUsedFormat();
|
||||
this._citationService.setStyleFormat(styleFormat);
|
||||
this._bNumFormat = styleFormat == "numeric";
|
||||
if ("note" === styleFormat) {
|
||||
this._notesStyleWrapper.classList.remove(this._displayNoneClass);
|
||||
} else {
|
||||
this._notesStyleWrapper.classList.add(this._displayNoneClass);
|
||||
}
|
||||
|
||||
let notesStyle = this._cslStylesManager.getLastUsedNotesStyle();
|
||||
this._citationService.setNotesStyle(notesStyle);
|
||||
const notesAs = this._notesStyleWrapper.querySelector(
|
||||
'input[name="notesAs"][value="' + notesStyle + '"]'
|
||||
);
|
||||
if (notesAs && notesAs instanceof HTMLInputElement) {
|
||||
notesAs.checked = true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {HTMLElement} el
|
||||
*/
|
||||
SettingsPage.prototype._openList = function (el) {
|
||||
const self = this;
|
||||
el.classList.remove(this._displayNoneClass);
|
||||
const f = function () {
|
||||
self._closeList();
|
||||
window.removeEventListener("click", f);
|
||||
};
|
||||
window.addEventListener("click", f);
|
||||
};
|
||||
|
||||
SettingsPage.prototype._closeList = function () {
|
||||
for (var i = 0; i < this._selectLists.length; i++) {
|
||||
if (this._selectLists[i] === this._styleSelectList)
|
||||
this._styleSelect.oninput(null, "");
|
||||
this._selectLists[i].classList.add(this._displayNoneClass);
|
||||
}
|
||||
};
|
||||
|
||||
SettingsPage.prototype._initSelectBoxes = function () {
|
||||
const self = this;
|
||||
var select = document.getElementsByClassName("control select");
|
||||
for (var i = 0; i < select.length; i++) {
|
||||
var input = select[i];
|
||||
var holder = input.parentElement;
|
||||
if (!(input instanceof HTMLInputElement) || !holder) {
|
||||
console.error("initSelectBoxes: no input or holder");
|
||||
continue;
|
||||
}
|
||||
|
||||
var arrow = document.createElement("span");
|
||||
arrow.classList.add("selectArrow");
|
||||
arrow.appendChild(document.createElement("span"));
|
||||
arrow.appendChild(document.createElement("span"));
|
||||
holder.appendChild(arrow);
|
||||
|
||||
const holderElement = holder.getElementsByClassName("selectList");
|
||||
|
||||
for (var k = 0; k < holderElement.length; k++) {
|
||||
var temp = holderElement[k];
|
||||
var list;
|
||||
if (temp instanceof HTMLElement) {
|
||||
list = temp;
|
||||
} else {
|
||||
console.error(
|
||||
"initSelectBoxes: holderElement is not HTMLElement"
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (list.children.length > 0) {
|
||||
for (var j = 0; j < list.children.length; j++) {
|
||||
const child = list.children[j];
|
||||
if (child instanceof HTMLElement === false) {
|
||||
continue;
|
||||
}
|
||||
child.onclick = self._onClickListElement(list, input);
|
||||
}
|
||||
// selectInput(input, list.children[0], list, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {HTMLElement} list
|
||||
* @param {HTMLElement} input
|
||||
* @returns {function}
|
||||
*/
|
||||
var fOpen = function (list, input) {
|
||||
return function (/** @type {MouseEvent} */ ev) {
|
||||
ev.stopPropagation();
|
||||
if (
|
||||
!self._styleSelectListOther.classList.contains(
|
||||
self._displayNoneClass
|
||||
)
|
||||
)
|
||||
return true;
|
||||
|
||||
if (list.onopen) {
|
||||
list.onopen();
|
||||
}
|
||||
if (!input.hasAttribute("readonly")) {
|
||||
input.select();
|
||||
}
|
||||
self._openList(list);
|
||||
|
||||
return true;
|
||||
};
|
||||
};
|
||||
|
||||
if (k !== 1) {
|
||||
input.onclick = fOpen(list, input);
|
||||
arrow.onclick = fOpen(list, input);
|
||||
}
|
||||
self._selectLists.push(list);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {HTMLElement} list
|
||||
* @param {HTMLInputElement} input
|
||||
*/
|
||||
SettingsPage.prototype._onClickListElement = function (list, input) {
|
||||
const self = this;
|
||||
return function (/** @type {MouseEvent} */ ev) {
|
||||
if (!ev.target || !(ev.target instanceof HTMLElement)) {
|
||||
console.error("onClickListElement: no target");
|
||||
return;
|
||||
}
|
||||
var sel = ev.target.getAttribute("data-value");
|
||||
for (var i = 0; i < list.children.length; i++) {
|
||||
const temp = list.children[i];
|
||||
if (temp instanceof HTMLElement === false) continue;
|
||||
/** @type {HTMLElement} */
|
||||
const child = temp;
|
||||
if (list.children[i].getAttribute("data-value") == sel) {
|
||||
list.children[i].setAttribute("selected", "");
|
||||
|
||||
self._selectInput(input, child, list, true);
|
||||
} else {
|
||||
if (list.children[i].hasAttribute("selected")) {
|
||||
list.children[i].attributes.removeNamedItem("selected");
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {HTMLInputElement} input
|
||||
* @param {HTMLElement} el
|
||||
* @param {HTMLElement} list
|
||||
* @param {boolean} isClick
|
||||
*/
|
||||
SettingsPage.prototype._selectInput = function (input, el, list, isClick) {
|
||||
input.value = el.textContent;
|
||||
var val = el.getAttribute("data-value") || "";
|
||||
input.setAttribute("data-value", val);
|
||||
input.setAttribute("title", el.textContent);
|
||||
if (input.onselectchange) {
|
||||
input.onselectchange(input, val, isClick);
|
||||
}
|
||||
list.classList.add(this._displayNoneClass);
|
||||
};
|
||||
@ -51,7 +51,7 @@ function SelectCitationsComponent(
|
||||
["volume", "Volume"],
|
||||
];
|
||||
|
||||
this._cancelBtn = document.getElementById("cancelBtn");
|
||||
this._cancelSelectBtn = document.getElementById("cancelSelectBtn");
|
||||
|
||||
this._docsHolder = document.getElementById("docsHolder");
|
||||
this._docsThumb = document.getElementById("docsThumb");
|
||||
@ -89,8 +89,8 @@ function SelectCitationsComponent(
|
||||
|
||||
SelectCitationsComponent.prototype._init = function () {
|
||||
const self = this;
|
||||
if (this._cancelBtn) {
|
||||
this._cancelBtn.onclick = function (e) {
|
||||
if (this._cancelSelectBtn) {
|
||||
this._cancelSelectBtn.onclick = function (e) {
|
||||
var ids = [];
|
||||
for (var id in self._items) {
|
||||
ids.push(id);
|
||||
|
||||
@ -538,6 +538,36 @@ SelectBox.prototype.addItem = function (value, text, selected) {
|
||||
this._updateSelectedText();
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Array<[string,string]>} values
|
||||
* @param {string} [selectedValue]
|
||||
*/
|
||||
SelectBox.prototype.addItems = function (values, selectedValue) {
|
||||
const self = this;
|
||||
values.forEach(function (pair, index) {
|
||||
const isSelected = selectedValue
|
||||
? pair[0] === selectedValue
|
||||
: index === 0;
|
||||
|
||||
if (isSelected) {
|
||||
if (self._options.multiple) {
|
||||
self._selectedValues.add(pair[0]);
|
||||
} else {
|
||||
self._selectedValues.clear();
|
||||
self._selectedValues.add(pair[0]);
|
||||
}
|
||||
}
|
||||
|
||||
self._items.push({
|
||||
value: pair[0],
|
||||
text: pair[1],
|
||||
selected: isSelected,
|
||||
});
|
||||
}, this);
|
||||
|
||||
this._updateSelectedText();
|
||||
};
|
||||
|
||||
SelectBox.prototype.addSeparator = function () {
|
||||
this._items.push(null);
|
||||
};
|
||||
@ -556,6 +586,21 @@ SelectBox.prototype.removeItem = function (value) {
|
||||
this._updateSelectedText();
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {null | string}
|
||||
*/
|
||||
SelectBox.prototype.getSelectedValue = function () {
|
||||
if (this._options.multiple) {
|
||||
console.error(
|
||||
"Method getSelectedValue is only available for single-select boxes."
|
||||
);
|
||||
return null;
|
||||
} else {
|
||||
var values = Array.from(this._selectedValues);
|
||||
return values.length > 0 ? values[0] : null;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {null | string | Array<string>}
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user