Bug 186797 - WebView reload emojis messy
Summary: WebView reload emojis messy
Status: RESOLVED INVALID
Alias: None
Product: WebKit
Classification: Unclassified
Component: Accessibility (show other bugs)
Version: WebKit Nightly Build
Hardware: iPhone / iPad Unspecified
: P2 Normal
Assignee: Nobody
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2018-06-18 21:20 PDT by 1716329344
Modified: 2018-06-21 19:57 PDT (History)
3 users (show)

See Also:


Attachments
messy emojis (120.30 KB, image/png)
2018-06-18 21:20 PDT, 1716329344
no flags Details
WKWebView test app (30.35 KB, application/zip)
2018-06-20 17:49 PDT, Myles C. Maxfield
no flags Details
Fixed test app (38.94 KB, application/zip)
2018-06-21 17:09 PDT, Myles C. Maxfield
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description 1716329344 2018-06-18 21:20:30 PDT
Created attachment 343017 [details]
messy emojis

It is normal when i use a "Div" tag to show emojis , but calling "window.reload()" ,that cause messy code.
Comment 1 Radar WebKit Bug Importer 2018-06-19 10:40:16 PDT
<rdar://problem/41254990>
Comment 2 Myles C. Maxfield 2018-06-19 22:57:13 PDT
Can you provide the specific page this is happening on? Perhaps by attaching a .html document or a URL?
Comment 3 1716329344 2018-06-20 02:04:12 PDT
// Example.html
<div id='buttons'>😊</div>
<Button onclick="window.location.reload()">click</Button>

-----------------------
Device:iPhone 8 plus

Detail Step: using UIWebView or WKWebView  to load this html, and click button
Comment 4 1716329344 2018-06-20 02:14:10 PDT
(In reply to Myles C. Maxfield from comment #2)
> Can you provide the specific page this is happening on? Perhaps by attaching
> a .html document or a URL?

// Example.html
<div id='buttons'>😊</div>
<Button onclick="window.location.reload()">click</Button>

-----------------------
Device:iPhone 8 plus

Detail Step: using UIWebView or WKWebView  to load this html, and click button
Comment 5 1716329344 2018-06-20 02:36:25 PDT
Simplely, open this Example.html file by MacDown can also display this bug.
Comment 6 Myles C. Maxfield 2018-06-20 16:48:05 PDT
Does your content have a <meta charset="utf-8"> tag in its <head> element? Or is it served from a server which uses the "Content-Type: text/html; charset=utf-8" header?

If not, the UTF-8 content will be interpreted as another encoding, and will be shown as garbage.
Comment 7 1716329344 2018-06-20 17:01:06 PDT
(In reply to Myles C. Maxfield from comment #6)
> Does your content have a <meta charset="utf-8"> tag in its <head> element?
> Or is it served from a server which uses the "Content-Type: text/html;
> charset=utf-8" header?
> 
> If not, the UTF-8 content will be interpreted as another encoding, and will
> be shown as garbage.

The Example.html is a local file,and a <meta charset="utf-8"> tag has been added,it does not work.
Comment 8 1716329344 2018-06-20 17:10:37 PDT
(In reply to Myles C. Maxfield from comment #6)
> Does your content have a <meta charset="utf-8"> tag in its <head> element?
> Or is it served from a server which uses the "Content-Type: text/html;
> charset=utf-8" header?
> 
> If not, the UTF-8 content will be interpreted as another encoding, and will
> be shown as garbage.

This issue is : It is nomal When I load Example.html at first time,but calling js "window.location.reload" or using WebKit API to reload ,emoji will be shown as garbage.
Comment 9 Myles C. Maxfield 2018-06-20 17:39:57 PDT
I can't reproduce this problem in Safari on an iPhone or in the iOS simulator. Perhaps the problem is with raw WKWebViews.
Comment 10 Myles C. Maxfield 2018-06-20 17:49:51 PDT
Created attachment 343197 [details]
WKWebView test app
Comment 11 Myles C. Maxfield 2018-06-20 17:50:04 PDT
I just made a test app with a WKWebView and the problem doesn't reproduce there either (in the Simulator).

If you try running the attached project, does it show the problem?
Comment 12 1716329344 2018-06-20 18:26:26 PDT
(In reply to Myles C. Maxfield from comment #11)
> I just made a test app with a WKWebView and the problem doesn't reproduce
> there either (in the Simulator).
> 
> If you try running the attached project, does it show the problem?


you can download resource from https://github.com/zhaojiewen/WebViewJavascriptBridge, and run Examples.
Comment 13 1716329344 2018-06-20 20:10:09 PDT
(In reply to Myles C. Maxfield from comment #11)
> I just made a test app with a WKWebView and the problem doesn't reproduce
> there either (in the Simulator).
> 
> If you try running the attached project, does it show the problem?

I have run this Test App, and the difference is "webView.loadHTMLString(htmlString, baseURL: url)" from my Example project.
Comment 14 1716329344 2018-06-21 00:17:32 PDT
(In reply to Myles C. Maxfield from comment #11)
> I just made a test app with a WKWebView and the problem doesn't reproduce
> there either (in the Simulator).
> 
> If you try running the attached project, does it show the problem?

My Code:

let path = Bundle.main.path(forResource: "ExampleApp", ofType: "html")
        let url = URL(fileURLWithPath: path!)
        do {
            let htmlString = try String(contentsOfFile: path!, encoding: .utf8)
            webView.loadHTMLString(htmlString, baseURL: myURL)
        }
        catch let error {
            print(error)
        }


Your Code :

let myURL = Bundle.main.url(forResource: "ExampleApp", withExtension: "html")
        let myRequest = URLRequest(url: myURL!)
        webView.load(myRequest)

If I use yours,It is normal. "webView.loadHTMLString(htmlString, baseURL: myURL)" method and "baseURL" parameter cause this issue. Then I pass "Bundle.main.url(forResource: "ExampleApp", withExtension: "html)" to "baseURL" parameter instead of "URL(fileURLWithPath: path!)" , everything is normal.
Comment 15 Myles C. Maxfield 2018-06-21 17:09:54 PDT
Created attachment 343293 [details]
Fixed test app
Comment 16 Myles C. Maxfield 2018-06-21 17:10:15 PDT
When you say "String(contentsOfFile: htmlPath!, encoding: .utf8)" you are telling Foundation to read the file, interpret the bytes as UTF-8, and convert the string to some well-known encoding so it can be held in memory. All strings use the same well-known encoding. Everything works so far.

Then, when you use "WKWebView.loadHTMLString(_:baseURL:)", WebKit does two things:

1) Reads the string in its (correct) internal encoding, and draws the emoji properly.
2) Remembers the baseURL

Then, if the Javascript then executes "window.location.reload()", WebKit will load from the baseURL it remembered. At this point, the string argument to "WKWebView.loadHTMLString(_:baseURL:)" is totally lost forever. From now on, WebKit only uses the baseURL.

So, when the content reloads, it reloads from the baseURL. Upon reading the file, however, WebKit doesn't know what encoding to use, so it arbitrarily picks one, and happens to pick wrong. Adding <meta charset="utf-8"> is the way to tell WebKit the correct encoding.

I've attached the fixed project. It's fixed by adding <meta charset="utf-8"> in the HTML file.
Comment 17 1716329344 2018-06-21 19:57:02 PDT
(In reply to Myles C. Maxfield from comment #16)
> When you say "String(contentsOfFile: htmlPath!, encoding: .utf8)" you are
> telling Foundation to read the file, interpret the bytes as UTF-8, and
> convert the string to some well-known encoding so it can be held in memory.
> All strings use the same well-known encoding. Everything works so far.
> 
> Then, when you use "WKWebView.loadHTMLString(_:baseURL:)", WebKit does two
> things:
> 
> 1) Reads the string in its (correct) internal encoding, and draws the emoji
> properly.
> 2) Remembers the baseURL
> 
> Then, if the Javascript then executes "window.location.reload()", WebKit
> will load from the baseURL it remembered. At this point, the string argument
> to "WKWebView.loadHTMLString(_:baseURL:)" is totally lost forever. From now
> on, WebKit only uses the baseURL.
> 
> So, when the content reloads, it reloads from the baseURL. Upon reading the
> file, however, WebKit doesn't know what encoding to use, so it arbitrarily
> picks one, and happens to pick wrong. Adding <meta charset="utf-8"> is the
> way to tell WebKit the correct encoding.
> 
> I've attached the fixed project. It's fixed by adding <meta charset="utf-8">
> in the HTML file.

Thanks for your help!