<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[170988] trunk/Source/WebKit2</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/170988">170988</a></dd>
<dt>Author</dt> <dd>benjamin@webkit.org</dd>
<dt>Date</dt> <dd>2014-07-10 19:29:33 -0700 (Thu, 10 Jul 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>[iOS][WK2] It should be safe to call WKContentViewInteraction's cleanupInteraction multiple times
https://bugs.webkit.org/show_bug.cgi?id=134820

Patch by Benjamin Poulain &lt;bpoulain@apple.com&gt; on 2014-07-10
Reviewed by Andreas Kling.

If a view is destroyed just after a crash, &quot;cleanupInteraction&quot; is called twice: once on crash,
once on dealloc.

The code handling _interactionViewsContainerView is using KVO to monitor transform changes. It is not safe
to remove the observer if we are not already observing on that view.

To solve the problem, this patch makes the cleanup actually remove the view so that setup and cleanup
are completely symmetrical. If cleanup is called twice, the second time would not enter the branch because
the view is already nil.

* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView setupInteraction]):
(-[WKContentView cleanupInteraction]):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2UIProcessiosWKContentViewInteractionmm">trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (170987 => 170988)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2014-07-11 00:49:02 UTC (rev 170987)
+++ trunk/Source/WebKit2/ChangeLog        2014-07-11 02:29:33 UTC (rev 170988)
</span><span class="lines">@@ -1,3 +1,24 @@
</span><ins>+2014-07-10  Benjamin Poulain  &lt;bpoulain@apple.com&gt;
+
+        [iOS][WK2] It should be safe to call WKContentViewInteraction's cleanupInteraction multiple times
+        https://bugs.webkit.org/show_bug.cgi?id=134820
+
+        Reviewed by Andreas Kling.
+
+        If a view is destroyed just after a crash, &quot;cleanupInteraction&quot; is called twice: once on crash,
+        once on dealloc.
+
+        The code handling _interactionViewsContainerView is using KVO to monitor transform changes. It is not safe
+        to remove the observer if we are not already observing on that view.
+
+        To solve the problem, this patch makes the cleanup actually remove the view so that setup and cleanup
+        are completely symmetrical. If cleanup is called twice, the second time would not enter the branch because
+        the view is already nil.
+
+        * UIProcess/ios/WKContentViewInteraction.mm:
+        (-[WKContentView setupInteraction]):
+        (-[WKContentView cleanupInteraction]):
+
</ins><span class="cx"> 2014-07-10  Simon Fraser  &lt;simon.fraser@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [iOS WK2] Move WKInspectorHighlightView to its own file
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessiosWKContentViewInteractionmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm (170987 => 170988)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm        2014-07-11 00:49:02 UTC (rev 170987)
+++ trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm        2014-07-11 02:29:33 UTC (rev 170988)
</span><span class="lines">@@ -220,8 +220,9 @@
</span><span class="cx">         _interactionViewsContainerView = adoptNS([[UIView alloc] init]);
</span><span class="cx">         [_interactionViewsContainerView setOpaque:NO];
</span><span class="cx">         [_interactionViewsContainerView layer].anchorPoint = CGPointZero;
</span><ins>+        [self.superview addSubview:_interactionViewsContainerView.get()];
</ins><span class="cx">     }
</span><del>-    [_interactionViewsContainerView setHidden:NO];
</del><ins>+
</ins><span class="cx">     [self.layer addObserver:self forKeyPath:@&quot;transform&quot; options:NSKeyValueObservingOptionInitial context:nil];
</span><span class="cx"> 
</span><span class="cx">     _touchEventGestureRecognizer = adoptNS([[UIWebTouchEventsGestureRecognizer alloc] initWithTarget:self action:@selector(_webTouchEventsRecognized:) touchDelegate:self]);
</span><span class="lines">@@ -276,8 +277,13 @@
</span><span class="cx">     [_formInputSession invalidate];
</span><span class="cx">     _formInputSession = nil;
</span><span class="cx">     [_highlightView removeFromSuperview];
</span><del>-    [self.layer removeObserver:self forKeyPath:@&quot;transform&quot;];
-    [_interactionViewsContainerView setHidden:YES];
</del><ins>+
+    if (_interactionViewsContainerView) {
+        [self.layer removeObserver:self forKeyPath:@&quot;transform&quot;];
+        [_interactionViewsContainerView removeFromSuperview];
+        _interactionViewsContainerView = nil;
+    }
+
</ins><span class="cx">     [_touchEventGestureRecognizer setDelegate:nil];
</span><span class="cx">     [self removeGestureRecognizer:_touchEventGestureRecognizer.get()];
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>