Fix turbo nav for settings and stats pages.

Extract settings.js, preserve inline scripts from raw HTML (DOMParser strips them), and load trade config via JSON script tag.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-06-26 21:26:15 +08:00
parent 6d55a54946
commit 9613fb0737
7 changed files with 229 additions and 163 deletions
+2 -110
View File
@@ -212,7 +212,7 @@
{% endif %}
</p>
<form action="{{ url_for('settings') }}" method="post" id="ctp-settings-form">
<form action="{{ url_for('settings') }}" method="post" id="ctp-settings-form" data-simnow-pwd-set="{{ '1' if ctp_cfg.simnow_password_set else '0' }}">
<input type="hidden" name="action" value="ctp">
<div class="settings-ctp-auto card" style="margin-bottom:.85rem;padding:.75rem 1rem">
@@ -478,113 +478,5 @@
</div>
{% endblock %}
{% block extra_js %}
<script>
(function () {
var sel = document.getElementById('position-sizing-mode');
var lotsField = document.getElementById('field-fixed-lots');
var amountField = document.getElementById('field-fixed-amount');
function syncSizingFields() {
if (!sel) return;
var isAmount = sel.value === 'amount';
if (lotsField) lotsField.hidden = isAmount;
if (amountField) amountField.hidden = !isAmount;
}
if (sel) sel.addEventListener('change', syncSizingFields);
syncSizingFields();
var SETTINGS_FOLD_KEY = 'qihuo_settings_fold';
function setSettingsFold(el, collapsed) {
if (!el) return;
el.classList.toggle('is-collapsed', collapsed);
var head = el.querySelector('.settings-fold-head');
if (head) head.setAttribute('aria-expanded', collapsed ? 'false' : 'true');
}
function saveSettingsFoldState() {
var state = {};
document.querySelectorAll('[data-settings-fold]').forEach(function (el) {
state[el.getAttribute('data-settings-fold')] = el.classList.contains('is-collapsed');
});
try { localStorage.setItem(SETTINGS_FOLD_KEY, JSON.stringify(state)); } catch (e) { /* ignore */ }
}
function loadSettingsFoldState() {
try {
var raw = localStorage.getItem(SETTINGS_FOLD_KEY);
if (!raw) return;
var state = JSON.parse(raw);
document.querySelectorAll('[data-settings-fold]').forEach(function (el) {
var key = el.getAttribute('data-settings-fold');
if (Object.prototype.hasOwnProperty.call(state, key)) {
setSettingsFold(el, !!state[key]);
}
});
} catch (e) { /* ignore */ }
}
document.querySelectorAll('.settings-fold-head').forEach(function (btn) {
btn.addEventListener('click', function () {
var panel = btn.closest('[data-settings-fold]');
if (!panel) return;
setSettingsFold(panel, !panel.classList.contains('is-collapsed'));
saveSettingsFoldState();
});
});
loadSettingsFoldState();
var CTP_FOLD_KEY = 'qihuo_ctp_fold';
function setCtpFold(el, collapsed) {
if (!el) return;
el.classList.toggle('is-collapsed', collapsed);
var head = el.querySelector('.settings-ctp-fold-head');
if (head) head.setAttribute('aria-expanded', collapsed ? 'false' : 'true');
}
function saveCtpFoldState() {
var state = {};
document.querySelectorAll('[data-ctp-fold]').forEach(function (el) {
state[el.getAttribute('data-ctp-fold')] = el.classList.contains('is-collapsed');
});
try { localStorage.setItem(CTP_FOLD_KEY, JSON.stringify(state)); } catch (e) { /* ignore */ }
}
function loadCtpFoldState() {
try {
var raw = localStorage.getItem(CTP_FOLD_KEY);
if (!raw) return;
var state = JSON.parse(raw);
document.querySelectorAll('[data-ctp-fold]').forEach(function (el) {
var key = el.getAttribute('data-ctp-fold');
if (Object.prototype.hasOwnProperty.call(state, key)) {
setCtpFold(el, !!state[key]);
}
});
} catch (e) { /* ignore */ }
}
document.querySelectorAll('.settings-ctp-fold-head').forEach(function (btn) {
btn.addEventListener('click', function () {
var panel = btn.closest('[data-ctp-fold]');
if (!panel) return;
setCtpFold(panel, !panel.classList.contains('is-collapsed'));
saveCtpFoldState();
});
});
loadCtpFoldState();
var ctpForm = document.getElementById('ctp-settings-form');
if (ctpForm) {
ctpForm.addEventListener('submit', function (ev) {
var ctpCard = document.querySelector('[data-settings-fold="ctp"]');
if (ctpCard) setSettingsFold(ctpCard, false);
var simnowFold = document.querySelector('[data-ctp-fold="simnow"]');
if (simnowFold) setCtpFold(simnowFold, false);
var pwd = document.getElementById('simnow_password');
var pwdVal = pwd && pwd.value ? pwd.value.trim() : '';
var pwdWasSet = {{ 'true' if ctp_cfg.simnow_password_set else 'false' }};
if (pwdWasSet && !pwdVal) {
var ok = window.confirm(
'SimNow 交易密码为空,保存后不会更新密码(仍用旧密码)。\n\n'
+ '若快期已改密,请取消后在「交易密码」框手打新密码再保存。\n\n仍要保存其他项?'
);
if (!ok) ev.preventDefault();
}
});
}
})();
</script>
<script src="{{ url_for('static', filename='js/settings.js') }}"></script>
{% endblock %}
+9 -9
View File
@@ -227,14 +227,14 @@
</div>
{% endblock %}
{% block extra_js %}
<script>
window.TRADE_SIZING_MODE = {{ sizing_mode|tojson }};
window.MARKET_NAV_ENABLED = {{ nav_items.market|tojson }};
window.TRADE_FIXED_LOTS = {{ fixed_lots|tojson }};
window.TRADE_FIXED_AMOUNT = {{ fixed_amount|tojson }};
window.PRODUCT_CATEGORIES = {{ product_categories | default([]) | tojson }};
window.__RECOMMEND_ROWS__ = {{ recommend_rows | default([]) | tojson }};
window.CTP_AUTO_CONNECT = {{ ctp_auto_connect | tojson }};
</script>
<script type="application/json" id="trade-page-data">{{ {
'sizing_mode': sizing_mode,
'market_nav_enabled': nav_items.market,
'fixed_lots': fixed_lots,
'fixed_amount': fixed_amount,
'product_categories': product_categories | default([]),
'recommend_rows': recommend_rows | default([]),
'ctp_auto_connect': ctp_auto_connect
} | tojson }}</script>
<script src="{{ url_for('static', filename='js/trade.js') }}?v={{ asset_v }}"></script>
{% endblock %}