From 9c3217df50d462d6be4399e3e654d591bf704df7 Mon Sep 17 00:00:00 2001 From: erdgeist Date: Thu, 9 Jul 2026 15:29:40 +0200 Subject: Fix malformed-HTML fallout across RSS, link rewriting, and flash messaging Editors' TinyMCE output can contain unclosed void elements like
, which is valid HTML5 but invalid XML -- three different places assumed the stricter rule and broke or silently misbehaved on the looser one. The Atom feed's block required real, well-formed XML structure but was handed a raw, unescaped body string; switched to type="html" with CGI.escapeHTML, matching how title/summary already handle the same content. rewrite_links_in_body used libxml's strict XML parser to rewrite internal links to be locale-prefixed, which raised on exactly this class of malformed markup -- silently, since the whole method was wrapped in rescue; nil, meaning the link rewrite (not the save) quietly failed with no error anywhere. Replaced with Nokogiri's lenient HTML parser, which repairs malformed void elements rather than rejecting them; also drops the bare rescue now that the actual failure mode it was guarding against shouldn't occur, and fixes two adjacent bugs found while in this method: a typo'd /sytem/uploads/ regex that could never match, and a missing https:// exclusion alongside the existing http:// one. Also addresses stale flash messaging surfaced while testing the above: update's save confirmation was being clobbered by edit's own "locked and ready" notice on the very next request, since nothing distinguished a fresh lock acquisition from a redirect back after saving. The save confirmation now names the next step (publish from Status) and flags a stale translation if one exists, using Page#outdated_translations?, already present but previously unused by any controller. --- app/controllers/nodes_controller.rb | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'app/controllers/nodes_controller.rb') diff --git a/app/controllers/nodes_controller.rb b/app/controllers/nodes_controller.rb index 72d4a3e..38d42d9 100644 --- a/app/controllers/nodes_controller.rb +++ b/app/controllers/nodes_controller.rb @@ -65,15 +65,16 @@ class NodesController < ApplicationController end def edit + freshly_locked = @node.lock_owner != current_user @node.lock_for_editing!( current_user ) @page = @node.autosave || @node.draft || @node.head - flash.now[:notice] = "Node locked and ready to edit" unless @node.autosave - if @node.autosave flash.now[:notice] = "This page has unsaved changes from a previous session, shown below. " \ "Save to keep them, or use \"Discard changes\" below to go back to the last saved version." + elsif freshly_locked + flash.now[:notice] = "Node locked and ready to edit" end rescue LockedByAnotherUser => e flash[:error] = e.message @@ -85,7 +86,18 @@ class NodesController < ApplicationController @node.autosave!( page_params.merge(:tag_list => params[:tag_list]), current_user ) @node.save_draft!(current_user) - flash[:notice] = "Draft has been saved: #{Time.now}" + flash[:notice] = "Draft saved. Publish your changes in the Status section once you're done." + flash[:status_path] = node_path(@node) + + if @node.draft.translated_locales.size > 1 + stale_locale = @node.draft.translated_locales.find do |locale| + @node.draft.outdated_translations?(locale: locale) + end + if stale_locale + flash[:stale_locale] = stale_locale + flash[:stale_locale_path] = edit_node_path(@node, locale: stale_locale) + end + end if params[:commit] == "Save + Unlock + Exit" @node.unlock! -- cgit v1.3