Make WordPress Core

Opened 13 years ago

Closed 8 years ago

Last modified 8 years ago

#13327 closed defect (bug) (fixed)

Post editor puts content through wpautop() before displaying it to users without JS enabled

Reported by: markjaquith's profile markjaquith Owned by:
Milestone: 4.3 Priority: normal
Severity: normal Version: 3.0
Component: Editor Keywords:
Focuses: Cc:

Description (last modified by markjaquith)

Steps to reproduce:

  1. With JS on, change to the Visual Editor
  2. Disable JS
  3. Add a new post
  4. Save as draft
  5. Note that the content is wrapped in <p> tags in the textarea.

http://img19.imageshack.us/img19/6363/screenshot20100510at524.png

Expected:

No paragraph tags are added.

Change History (12)

#1 @markjaquith
13 years ago

  • Description modified (diff)
  • Summary changed from Post editor puts content through wpautop() before displaying it to Contributors without JS to Post editor puts content through wpautop() before displaying it to users without JS enabled

This happens because

#2 follow-up: @markjaquith
13 years ago

This happens because the_editor() is adding wp_richedit_pre as a filter on the_editor_content. Because the user is "stuck" in Visual mode, it formats the content the way TinyMCE wants it... with paragraph tags.

One possible fix would be to load the TinyMCE version of the content up in a hidden textarea, load the regular text in the real textarea, and then attempt to use JS to copy the TinyMCE version over to the real textarea. Without JS, this would fail, and they'd keep the real content.

For users with JS, this may cause a flicker as that swap takes place. And we may need to use JS to keep them from trying to edit the content before this operation has taken place.

#3 @markjaquith
13 years ago

  • Milestone changed from 3.0 to 3.1

Punting to 3.1 — It's not a blocker, and I don't think it is a regression.

#4 in reply to: ↑ 2 @azaozz
13 years ago

Replying to markjaquith:

For users with JS, this may cause a flicker...

... And make the visual editor load slower.

The problem is that php (the server) has to know if the browser supports JS before outputting the post content so it applies the proper filter. That is doable with a cookie.

One possible fix would be to load the TinyMCE version of the content up in a hidden textarea, load the regular text in the real textarea, and then attempt to use JS to copy the TinyMCE version over to the real textarea. Without JS, this would fail, and they'd keep the real content.

We could try doing something similar with CSS only, will run some tests.

#5 @azaozz
13 years ago

Related: #13326

#6 @azaozz
13 years ago

Been thinking more about this: currently we output HTML for both cases, js and no-js and then hide the extra elements with CSS (the .hide-if-js, .hide-if-no-js classes).

This is working well and is completely transparent for the user. The disadvantages are that we output more HTML code and that in certain cases we still need to know whether JS in the browser is disabled before we start the output like for this ticket or the horizontal folding of the admin menu.

It seems we have two options:

  • Change the no-js mechanism to use a "session" type cookie, i.e. add a <noscript> redirect in the HTML header and when that is triggered, set a cookie that will expire when the browser is closed.
    <head>
    <noscript><meta http-equiv=refresh content="0; url=..." /></noscript>
    

The main disadvantage of this method is that the <noscript> tag is invalid in the HTML head in XHTML 1.0. However this is widely used and seems to work properly in all current browsers (see Google Maps for example).

From user prospective there will be no change when JS is enabled and only a very small delay in loading the first admin screen when it's disabled. In the back-end we can see that redirect, set a global or a constant, set the temporary cookie and stop outputting the <noscript> redirect (of course we will be checking for that cookie first).

  • Continue handling this on per-case basis. In that terms we would need to output two content textareas on the write/edit screen and hide the extra one with CSS:
<textarea id="content" name="content" class="hide-if-no-js"></textarea>

<textarea id="content-nojs" name="content-nojs" class="hide-if-js"></textarea>

If JS is enabled we can empty the content of #content-nojs (or even remove it completely), then when saving the post we will look first whether $_POST['content-nojs'] is not empty and copy that over $_POST['content'].

#7 @nacin
13 years ago

  • Milestone changed from Awaiting Triage to Future Release

#8 @chriscct7
9 years ago

  • Keywords needs-patch added

#9 @azaozz
9 years ago

Looking at this again: the best way to fix it would be to scrap wp_richedit_pre() and use only wp_htmledit_pre(), then run the textarea content through the JS wpautop before initializing TinyMCE (same as switching from Text to Visual).

That would make the textarea content consistent and would fix other bugs. For example the browser restores the "last seen" textarea content on using the Back or Forward buttons. Currently on the Edit Post screen we have to set autocomplete="off" on the whole form in Chrome, as it doesn't respect it on the textarea.

However this could potentially introduce bugs in plugins that use TinyMCE and don't use wp_richedit_pre/wp_htmledit_pre to prepare the textarea content. We would need to ensure that arbitrary HTML that has <p> tags can pass through the JS wpautop() safely.

#10 @chriscct7
8 years ago

  • Priority changed from low to normal

#11 @azaozz
8 years ago

  • Keywords needs-patch removed
  • Resolution set to fixed
  • Status changed from new to closed

This was fixed with the introduction of format_for_editor() in 4.3.

#12 @swissspidy
8 years ago

  • Milestone changed from Future Release to 4.3
Note: See TracTickets for help on using tickets.