<!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>[201307] trunk/Websites/perf.webkit.org</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/201307">201307</a></dd>
<dt>Author</dt> <dd>rniwa@webkit.org</dd>
<dt>Date</dt> <dd>2016-05-23 17:24:57 -0700 (Mon, 23 May 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Some applications truncates the last closing parenthesis in perf dashboard URL
https://bugs.webkit.org/show_bug.cgi?id=157976

Reviewed by Tim Horton.

Unfortunately, different applications use different heuristics to determine the end of each URL. Two trailing
parentheses, for example, is just fine in Radar as well as Apple Mail if the URL is short enough. Using other
characters such as ] and } wouldn't work either because they would be %-escaped. At that point, we might as well
as %-escape everything.

Work around the bug by parsing the URL as if it had one extra ')' if the parsing had failed. Also shorten the charts
page's URL by avoid emitting &quot;-null&quot; for each pane when the pane doesn't have a currently selected point or selection.
This improves the odds of the entire URL being recognized by various applications.

We could, in theory, implement some sort of a URL shorter but that can wait until when we support real user accounts.

* public/v3/pages/chart-pane.js:
(ChartPane.prototype.serializeState): Don't serialize the selection or the current point if nothing is selected.
* public/v3/pages/page-router.js:
(PageRouter.prototype._deserializeHashQueryValue): Try parsing the value again with one extra ] at the end if
the JSON parsing had failed.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkWebsitesperfwebkitorgChangeLog">trunk/Websites/perf.webkit.org/ChangeLog</a></li>
<li><a href="#trunkWebsitesperfwebkitorgpublicv3pageschartpanejs">trunk/Websites/perf.webkit.org/public/v3/pages/chart-pane.js</a></li>
<li><a href="#trunkWebsitesperfwebkitorgpublicv3pagespagerouterjs">trunk/Websites/perf.webkit.org/public/v3/pages/page-router.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkWebsitesperfwebkitorgChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/ChangeLog (201306 => 201307)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/ChangeLog        2016-05-24 00:22:53 UTC (rev 201306)
+++ trunk/Websites/perf.webkit.org/ChangeLog        2016-05-24 00:24:57 UTC (rev 201307)
</span><span class="lines">@@ -1,3 +1,27 @@
</span><ins>+2016-05-23  Ryosuke Niwa  &lt;rniwa@webkit.org&gt;
+
+        Some applications truncates the last closing parenthesis in perf dashboard URL
+        https://bugs.webkit.org/show_bug.cgi?id=157976
+
+        Reviewed by Tim Horton.
+
+        Unfortunately, different applications use different heuristics to determine the end of each URL. Two trailing
+        parentheses, for example, is just fine in Radar as well as Apple Mail if the URL is short enough. Using other
+        characters such as ] and } wouldn't work either because they would be %-escaped. At that point, we might as well
+        as %-escape everything.
+
+        Work around the bug by parsing the URL as if it had one extra ')' if the parsing had failed. Also shorten the charts
+        page's URL by avoid emitting &quot;-null&quot; for each pane when the pane doesn't have a currently selected point or selection.
+        This improves the odds of the entire URL being recognized by various applications.
+
+        We could, in theory, implement some sort of a URL shorter but that can wait until when we support real user accounts.
+
+        * public/v3/pages/chart-pane.js:
+        (ChartPane.prototype.serializeState): Don't serialize the selection or the current point if nothing is selected.
+        * public/v3/pages/page-router.js:
+        (PageRouter.prototype._deserializeHashQueryValue): Try parsing the value again with one extra ] at the end if
+        the JSON parsing had failed.
+
</ins><span class="cx"> 2016-05-18  Ryosuke Niwa  &lt;rniwa@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Perf dashboard &quot;Add pane&quot; should list first by test, then by machine
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgpublicv3pageschartpanejs"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/public/v3/pages/chart-pane.js (201306 => 201307)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/public/v3/pages/chart-pane.js        2016-05-24 00:22:53 UTC (rev 201306)
+++ trunk/Websites/perf.webkit.org/public/v3/pages/chart-pane.js        2016-05-24 00:24:57 UTC (rev 201307)
</span><span class="lines">@@ -15,13 +15,15 @@
</span><span class="cx"> 
</span><span class="cx">     serializeState()
</span><span class="cx">     {
</span><del>-        var selection = this._mainChart ? this._mainChart.currentSelection() : null;
-        var point = this._mainChart ? this._mainChart.currentPoint() : null;
-        return [
-            this._platformId,
-            this._metricId,
-            selection || (point &amp;&amp; this._mainChartIndicatorWasLocked ? point.id : null),
-        ];
</del><ins>+        var state = [this._platformId, this._metricId];
+        if (this._mainChart) {
+            var selection = this._mainChart.currentSelection();
+            if (selection)
+                state[2] = selection;
+            else if (this._mainChartIndicatorWasLocked)
+                state[2] = this._mainChart.currentPoint().id;
+        }
+        return state;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     updateFromSerializedState(state, isOpen)
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgpublicv3pagespagerouterjs"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/public/v3/pages/page-router.js (201306 => 201307)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/public/v3/pages/page-router.js        2016-05-24 00:22:53 UTC (rev 201306)
+++ trunk/Websites/perf.webkit.org/public/v3/pages/page-router.js        2016-05-24 00:24:57 UTC (rev 201307)
</span><span class="lines">@@ -140,9 +140,24 @@
</span><span class="cx"> 
</span><span class="cx">     _deserializeHashQueryValue(value)
</span><span class="cx">     {
</span><ins>+        var json = value.replace(/\(/g, '[').replace(/\)/g, ']').replace(/-/g, ',');
</ins><span class="cx">         try {
</span><del>-            return JSON.parse(value.replace(/\(/g, '[').replace(/\)/g, ']').replace(/-/g, ','));
</del><ins>+            return JSON.parse(json);
</ins><span class="cx">         } catch (error) {
</span><ins>+
+            // Some applications don't linkify two consecutive closing parentheses: )).
+            // Try fixing adding one extra parenthesis to see if that works.
+            function count(regex)
+            {
+                var match = json.match(regex);
+                return match ? match.length : 0;
+            }
+            var missingClosingBrackets = count(/\[/g) - count(/\]/g);
+            var fix = new Array(missingClosingBrackets).fill(']').join('');
+            try {
+                return JSON.parse(json + fix);
+            } catch (newError) { }
+
</ins><span class="cx">             return value;
</span><span class="cx">         }
</span><span class="cx">     }
</span></span></pre>
</div>
</div>

</body>
</html>