diff --git a/changedetectionio/blueprint/settings_browser_profile/__init__.py b/changedetectionio/blueprint/settings_browser_profile/__init__.py index 3f0ba2f8f..8b0b5b3c0 100644 --- a/changedetectionio/blueprint/settings_browser_profile/__init__.py +++ b/changedetectionio/blueprint/settings_browser_profile/__init__.py @@ -13,9 +13,7 @@ def construct_blueprint(datastore: ChangeDetectionStore): template_folder="templates" ) - @settings_browser_profile_blueprint.route("", methods=['GET']) - @login_optionally_required - def index(): + def _render_index(browser_profile_form=None, editing_machine_name=None): from changedetectionio import forms from changedetectionio import content_fetchers as cf from changedetectionio.model.browser_profile import ( @@ -23,10 +21,10 @@ def construct_blueprint(datastore: ChangeDetectionStore): ) fetcher_choices = [(name[len('html_'):], desc) for name, desc in cf.available_fetchers()] - browser_profile_form = forms.BrowserProfileForm() + if browser_profile_form is None: + browser_profile_form = forms.BrowserProfileForm() browser_profile_form.fetch_backend.choices = fetcher_choices - # Map clean fetcher name → supports_screenshots so the template can hide viewport options fetcher_supports_screenshots = {} for name, _desc in cf.available_fetchers(): clean_name = name[len('html_'):] @@ -51,8 +49,34 @@ def construct_blueprint(datastore: ChangeDetectionStore): fetcher_choices=fetcher_choices, fetcher_supports_screenshots=fetcher_supports_screenshots, current_default_profile=current_default, + editing_machine_name=editing_machine_name, ) + @settings_browser_profile_blueprint.route("", methods=['GET']) + @login_optionally_required + def index(): + return _render_index() + + @settings_browser_profile_blueprint.route("//edit", methods=['GET']) + @login_optionally_required + def edit(machine_name): + from changedetectionio import forms + from changedetectionio.model.browser_profile import get_builtin_profiles, BrowserProfile, RESERVED_MACHINE_NAMES + + if machine_name in RESERVED_MACHINE_NAMES: + flash(gettext("Built-in browser profiles cannot be edited."), 'error') + return redirect(url_for('settings_browsers.index')) + + store_profiles = datastore.data['settings']['application'].get('browser_profiles', {}) + raw = store_profiles.get(machine_name) + if raw is None: + flash(gettext("Browser profile not found."), 'error') + return redirect(url_for('settings_browsers.index')) + + profile = BrowserProfile(**raw) if isinstance(raw, dict) else raw + form = forms.BrowserProfileForm(data=profile.model_dump()) + return _render_index(browser_profile_form=form, editing_machine_name=machine_name) + @settings_browser_profile_blueprint.route("/save", methods=['POST']) @login_optionally_required def save(): diff --git a/changedetectionio/blueprint/settings_browser_profile/templates/browser_profiles.html b/changedetectionio/blueprint/settings_browser_profile/templates/browser_profiles.html index 7cf8d96c7..508f9a68a 100644 --- a/changedetectionio/blueprint/settings_browser_profile/templates/browser_profiles.html +++ b/changedetectionio/blueprint/settings_browser_profile/templates/browser_profiles.html @@ -49,8 +49,8 @@ {% if not profile.is_builtin %} - + {{ _('Edit') }} {{ _('Delete') }} @@ -63,13 +63,13 @@ -

{{ _('Add new browser profile') }}

+

{{ _('Edit browser profile') if editing_machine_name else _('Add new browser profile') }}

- +
{{ render_field(browser_profile_form.name) }} @@ -107,8 +107,9 @@
- + {% if editing_machine_name %} + {{ _('Cancel') }} + {% endif %} {{ _('Back to Settings') }}
@@ -140,33 +141,10 @@ document.addEventListener('DOMContentLoaded', function() { } }); -function browserProfileEdit(profile, machineName) { - document.getElementById('profile-form-heading').textContent = {{ _('Edit browser profile')|tojson }}; - document.getElementById('original_machine_name').value = machineName; - - const form = document.getElementById('browser-profile-form'); - form.querySelector('[name="name"]').value = profile.name || ''; - form.querySelector('[name="fetch_backend"]').value = profile.fetch_backend || ''; - form.querySelector('[name="browser_connection_url"]').value = profile.browser_connection_url || ''; - form.querySelector('[name="viewport_width"]').value = profile.viewport_width || 1280; - form.querySelector('[name="viewport_height"]').value = profile.viewport_height || 1000; - form.querySelector('[name="block_images"]').checked = !!profile.block_images; - form.querySelector('[name="block_fonts"]').checked = !!profile.block_fonts; - form.querySelector('[name="ignore_https_errors"]').checked = !!profile.ignore_https_errors; - form.querySelector('[name="user_agent"]').value = profile.user_agent || ''; - form.querySelector('[name="locale"]').value = profile.locale || ''; - - updateBrowserFieldVisibility(); - document.getElementById('profile-cancel-btn').style.display = ''; - form.scrollIntoView({behavior: 'smooth'}); -} - -function cancelEdit() { - document.getElementById('profile-form-heading').textContent = {{ _('Add new browser profile')|tojson }}; - document.getElementById('original_machine_name').value = ''; - document.getElementById('browser-profile-form').reset(); - updateBrowserFieldVisibility(); - document.getElementById('profile-cancel-btn').style.display = 'none'; -} +{% if editing_machine_name %} +document.addEventListener('DOMContentLoaded', function() { + document.getElementById('browser-profile-form').scrollIntoView({behavior: 'smooth'}); +}); +{% endif %} {% endblock %} diff --git a/changedetectionio/blueprint/ui/templates/edit.html b/changedetectionio/blueprint/ui/templates/edit.html index 4a46a8e8c..fdfae697b 100644 --- a/changedetectionio/blueprint/ui/templates/edit.html +++ b/changedetectionio/blueprint/ui/templates/edit.html @@ -132,7 +132,16 @@ {% if capabilities.supports_request_type %}
- {{ render_field(form.browser_profile, class="fetch-backend") }} +
+
    + {%- for subfield in form.browser_profile %} +
  • + {{ subfield() }} + {{ browser_profile_fetchers.get(subfield.data, '')|fetcher_status_icons }} + +
  • + {%- endfor %} +

{{ _('Choose how this watch fetches its target URL. \'System settings default\' inherits the global setting.') }}

{{ _('Manage browser profiles in') }} {{ _('Settings → Browsers') }}.