PageRenderTime 176ms CodeModel.GetById 32ms app.highlight 40ms RepoModel.GetById 94ms app.codeStats 0ms

/demos/nav-nav-div.html

http://github.com/yinwang0/ydiff
HTML | 501 lines | 402 code | 99 blank | 0 comment | 0 complexity | 258547f51f2db28171e238413a7d2fc2 MD5 | raw file
  1<html>
  2<head>
  3<META http-equiv="Content-Type" content="text/html; charset=utf-8">
  4<LINK href="diff-s.css" rel="stylesheet" type="text/css">
  5<script type="text/javascript" src="nav-div.js"></script>
  6</head>
  7<body>
  8<div id="left" class="src">
  9<pre>
 10<a id='leftstart' tid='rightstart'></a>
 11/////////////////////// debug flag ////////////////////////
 12<span class='d'>var debug = false;</span>
 13
 14
 15/////////////////////// adjustable parameters //////////////////
 16<span class='d'>var minStep = 10;</span>
 17<span class='d'>var nSteps = 30;</span>
 18<span class='d'>var stepInterval = 10;</span>
 19<span class='d'>var blockRange = 15;</span>                    // how far consider one page blocked
 20<span class='d'>var nodeHLColor = &#39;lightgrey&#39;;</span>
 21<span class='d'>var lineHLColor = &#39;#FFFF66&#39;;</span>
 22<span class='d'>var lineBlockedColor = &#39;#E9AB17&#39;;</span>
 23<span class='d'>var bgColor = &#39;&#39;;</span>
 24<span class='d'>var bodyBlockedColor = &#39;#FAF0E6&#39;;</span>
 25
 26
 27///////////////////////// globals ////////////////////////
 28<span class='d'>var eventCount = 0;</span>
 29<span class='d'>var moving = false;</span>
 30<span class='d'>var matchId = -1;</span>
 31<span class='d'>var matchLineId = -1;</span>
 32<span class='d'>var cTimeout;</span>
 33
 34
 35///////////////////////// utilities ///////////////////////
 36
 37// No Math.sign() in JS?
 38<a id='167' tid='168' class='m'>function</a> <a id='169' tid='170' class='m'>sign</a>(<a id='171' tid='172' class='m'>x</a>) {
 39    <a id='173' tid='174' class='m'>if</a> (<a id='175' tid='176' class='m'>x</a> <a id='177' tid='178' class='m'>&gt;</a> <a id='179' tid='180' class='m'>0</a>) {
 40        <a id='181' tid='182' class='m'>return</a> <a id='183' tid='184' class='m'>1</a>;
 41    } <a id='185' tid='186' class='m'>else</a> <a id='187' tid='188' class='m'>if</a> (<a id='189' tid='190' class='m'>x</a> <a id='191' tid='192' class='m'>&lt;</a> <a id='193' tid='194' class='m'>0</a>) {
 42        <a id='195' tid='196' class='m'>return</a> <a id='197' tid='198' class='m'>-</a><a id='199' tid='200' class='m'>1</a>;
 43    } <a id='201' tid='202' class='m'>else</a> {
 44        <a id='203' tid='204' class='m'>return</a> <a id='205' tid='206' class='m'>0</a>;
 45    }
 46}
 47
 48
 49<span class='d'>function log(msg) {
 50    if (debug) {
 51        console.log(&quot;[ &quot; + window.name + &quot; ] &quot; + msg);
 52    }
 53}</span>
 54
 55
 56///////////////////// window scrolling stuff ////////////////////
 57
 58// accessing other window
 59<span class='d'>if (window.name == &#39;left&#39;) {
 60    otherside = parent.right;
 61} else {
 62    otherside = parent.left;
 63}</span>
 64
 65<a id='261' tid='262' class='m'>function</a> <a id='263' tid='264' class='m'>elementPosition</a>(<a id='265' tid='266' class='m'>id</a>) {
 66    <a id='267' tid='268' class='m'>obj</a> <a id='269' tid='270' class='m'>=</a> <a id='271' tid='272' class='m'>document</a>.<a id='273' tid='274' class='m'>getElementById</a>(<a id='275' tid='276' class='m'>id</a>);
 67    <a id='277' tid='278' class='m'>var</a> <a id='279' tid='280' class='m'>curleft</a> <a id='281' tid='282' class='m'>=</a> <a id='283' tid='284' class='m'>0</a>, <a id='285' tid='286' class='m'>curtop</a> <a id='287' tid='288' class='m'>=</a> <a id='289' tid='290' class='m'>0</a>;
 68
 69    <a id='291' tid='292' class='m'>if</a> (<a id='293' tid='294' class='m'>obj</a> <a id='295' tid='296' class='m'>&&</a> <a id='297' tid='298' class='m'>obj</a>.<a id='299' tid='300' class='m'>offsetParent</a>) {
 70        <a id='301' tid='302' class='m'>curleft</a> <a id='303' tid='304' class='m'>=</a> <a id='305' tid='306' class='m'>obj</a>.<a id='307' tid='308' class='m'>offsetLeft</a>;
 71        <a id='309' tid='310' class='m'>curtop</a> <a id='311' tid='312' class='m'>=</a> <a id='313' tid='314' class='m'>obj</a>.<a id='315' tid='316' class='m'>offsetTop</a>;
 72
 73        <a id='317' tid='318' class='m'>while</a> (<a id='319' tid='320' class='m'>obj</a> <a id='321' tid='322' class='m'>=</a> <a id='323' tid='324' class='m'>obj</a>.<a id='325' tid='326' class='m'>offsetParent</a>) {
 74            <a id='327' tid='328' class='m'>curleft</a> <a id='329' tid='330' class='m'>+=</a> <a id='331' tid='332' class='m'>obj</a>.<a id='333' tid='334' class='m'>offsetLeft</a>;
 75            <a id='335' tid='336' class='m'>curtop</a> <a id='337' tid='338' class='m'>+=</a> <a id='339' tid='340' class='m'>obj</a>.<a id='341' tid='342' class='m'>offsetTop</a>;
 76        }
 77    }
 78
 79    <a id='343' tid='344' class='m'>return</a> { <a id='345' tid='346' class='m'>x</a>: <a id='347' tid='348' class='m'>curleft</a>, <a id='349' tid='350' class='m'>y</a>: <a id='351' tid='352' class='m'>curtop</a> };
 80}
 81
 82
 83/*
 84 * Scroll the window to relative position, detecting blocking positions.
 85 */
 86<span class='d'>function</span> <span class='d'>scrollWithBlockCheck</span>(<span class='d'>distX, distY</span>) {
 87    <span class='d'>var oldTop = document.body.scrollTop;</span>
 88    <span class='d'>var oldLeft = document.body.scrollLeft;</span>
 89
 90    <span class='d'>eventCount++;</span>
 91    <span class='d'>window.scrollBy(distX, distY);</span>      // the ONLY place for actual scrolling
 92
 93    <span class='d'>var actualX = document.body.scrollLeft - oldLeft;</span>    
 94    <span class='d'>var actualY = document.body.scrollTop - oldTop;</span>
 95    <a id='245' tid='246' class='m'>log</a>(<a id='247' tid='248' class='m'>&quot;distY=&quot;</a> <a id='249' tid='250' class='m'>+</a> <a id='251' tid='252' class='m'>distY</a> <a id='253' tid='254' class='m'>+</a> <a id='255' tid='256' class='m'>&quot;, actualY=&quot;</a> <a id='257' tid='258' class='m'>+</a> <a id='259' tid='260' class='m'>actualY</a>);
 96
 97    // extra leewaw here because Chrome scrolling is horribly inacurate
 98    <span class='d'>if</span> ((<a id='207' tid='208' class='m'>Math</a>.<a id='209' tid='210' class='m'>abs</a>(<a id='211' tid='212' class='m'>distX</a>) <a id='213' tid='214' class='m'>&gt;</a> <a id='215' tid='216' class='m'>blockRange</a> <a id='217' tid='218' class='m'>&&</a> <a id='219' tid='220' class='m'>actualX</a> <a id='221' tid='222' class='m'>==</a> <a id='223' tid='224' class='m'>0</a>)
 99        <a id='225' tid='226' class='m'>||</a> <a id='227' tid='228' class='m'>Math</a>.<a id='229' tid='230' class='m'>abs</a>(<a id='231' tid='232' class='m'>distY</a>) <a id='233' tid='234' class='m'>&gt;</a> <a id='235' tid='236' class='m'>blockRange</a> <a id='237' tid='238' class='m'>&&</a> <a id='239' tid='240' class='m'>actualY</a> <a id='241' tid='242' class='m'>==</a> <a id='243' tid='244' class='m'>0</a>) <span class='d'>{
100        log(&quot;blocked&quot;);
101        eventCount--;
102        document.body.style.backgroundColor = bodyBlockedColor;
103        putHighlight(matchLineId, lineBlockedColor);
104        with (otherside) {
105            putHighlight(matchLineId, lineBlockedColor);
106        }
107        return true;
108    }</span> <span class='d'>else {
109        document.body.style.backgroundColor = bgColor;
110        otherside.document.body.style.backgroundColor = bgColor;
111        putHighlight(matchLineId, lineHLColor);
112        with (otherside) {
113            putHighlight(matchLineId, lineHLColor);
114        }
115        return false;
116    }</span>
117}
118
119
120/*
121 * timed animation function for scrolling the current window
122 */
123<span class='d'>function</span> <span class='d'>matchWindow</span>(<span class='d'>n</span>)
124{
125    <span class='d'>moving = true;</span>
126
127    <span class='d'>var linkPos = otherside.elementPosition(otherside.matchId).y;</span>
128    <span class='d'>var linkOffset = linkPos - otherside.document.body.scrollTop;</span>
129    <span class='d'>var targetPos = document.body.scrollTop + linkOffset</span>
130    <span class='d'>var curPos = elementPosition(matchId).y;</span>
131    <span class='d'>var distY = curPos - targetPos;</span>
132    <span class='d'>var distX = otherside.document.body.scrollLeft
133        - document.body.scrollLeft;</span>
134
135    <a id='151' tid='152' class='m'>log</a>(<a id='153' tid='154' class='m'>&quot;matching window... &quot;</a> <a id='155' tid='156' class='m'>+</a> <a id='157' tid='158' class='m'>n</a> <a id='159' tid='160' class='m'>+</a> <a id='161' tid='162' class='m'>&quot; distY=&quot;</a> <a id='163' tid='164' class='m'>+</a> <a id='165' tid='166' class='m'>distY</a>);
136
137    <span class='d'>if</span> (<a id='137' tid='138' class='m'>distY</a> <a id='139' tid='140' class='m'>==</a> <a id='141' tid='142' class='m'>0</a> <a id='143' tid='144' class='m'>&&</a> <a id='145' tid='146' class='m'>distX</a> <a id='147' tid='148' class='m'>==</a> <a id='149' tid='150' class='m'>0</a>) <span class='d'>{
138        moving = false;
139    }</span> <a id='95' tid='96' class='m'>else</a> <span class='d'>if</span> <span class='d'>(n &lt;= 1)</span> <span class='d'>{
140        scrollWithBlockCheck(distX, distY);
141        moving = false;        
142    }</span> <span class='d'>else</span>{
143        <a id='97' tid='98' class='m'>var</a> <a id='99' tid='100' class='m'>stepSize</a> <a id='101' tid='102' class='m'>=</a> <a id='103' tid='104' class='m'>Math</a>.<a id='105' tid='106' class='m'>floor</a>(<a id='107' tid='108' class='m'>Math</a>.<a id='109' tid='110' class='m'>abs</a>(<a id='111' tid='112' class='m'>distY</a>) <a id='113' tid='114' class='m'>/</a> <a id='115' tid='116' class='m'>n</a>);
144        <a id='79' tid='80' class='m'>actualMinStep</a> <a id='81' tid='82' class='m'>=</a> <a id='83' tid='84' class='m'>Math</a>.<a id='85' tid='86' class='m'>min</a>(<a id='87' tid='88' class='m'>minStep</a>, <a id='89' tid='90' class='m'>Math</a>.<a id='91' tid='92' class='m'>abs</a>(<a id='93' tid='94' class='m'>distY</a>));
145        <a id='37' tid='38' class='m'>if</a> (<a id='39' tid='40' class='m'>Math</a>.<a id='41' tid='42' class='m'>abs</a>(<a id='43' tid='44' class='m'>stepSize</a>) <a id='45' tid='46' class='m'>&lt;</a> <a id='47' tid='48' class='m'>minStep</a>) {
146            <a id='49' tid='50' class='m'>var</a> <a id='51' tid='52' class='m'>step</a> <a id='53' tid='54' class='m'>=</a> <a id='55' tid='56' class='m'>actualMinStep</a> <a id='57' tid='58' class='m'>*</a> <a id='59' tid='60' class='m'>sign</a>(<a id='61' tid='62' class='m'>distY</a>);
147        } <a id='63' tid='64' class='m'>else</a> {
148            <a id='65' tid='66' class='m'>var</a> <a id='67' tid='68' class='m'>step</a> <a id='69' tid='70' class='m'>=</a> <a id='71' tid='72' class='m'>stepSize</a> <a id='73' tid='74' class='m'>*</a> <a id='75' tid='76' class='m'>sign</a>(<a id='77' tid='78' class='m'>distY</a>);
149        }
150        <span class='d'>var blocked = scrollWithBlockCheck(distX, step);</span>
151        <a id='17' tid='18' class='m'>var</a> <a id='19' tid='20' class='m'>rest</a> <a id='21' tid='22' class='m'>=</a> <a id='23' tid='24' class='m'>Math</a>.<a id='25' tid='26' class='m'>floor</a>(<a id='27' tid='28' class='m'>distY</a> <a id='29' tid='30' class='m'>/</a> <a id='31' tid='32' class='m'>step</a>) <a id='33' tid='34' class='m'>-</a> <a id='35' tid='36' class='m'>1</a>;
152        <a id='1' tid='2' class='m'>log</a>(<a id='3' tid='4' class='m'>&quot;blocked?&quot;</a> <a id='5' tid='6' class='m'>+</a> <a id='7' tid='8' class='m'>blocked</a> <a id='9' tid='10' class='m'>+</a> <a id='11' tid='12' class='m'>&quot;, rest steps=&quot;</a> <a id='13' tid='14' class='m'>+</a> <a id='15' tid='16' class='m'>rest</a>);
153        <span class='d'>if (!blocked) {
154            cTimeout = setTimeout(&quot;matchWindow(&quot; + rest + &quot;)&quot;, stepInterval);
155        } else {
156            moving = false;
157        }</span>
158    }
159}
160
161
162////////////////////////// highlighting /////////////////////////////
163
164<a id='117' tid='118' class='m'>function</a> <a id='119' tid='120' class='m'>putHighlight</a>(<a id='121' tid='122' class='m'>id</a>, <a id='123' tid='124' class='m'>color</a>) {
165    <a id='125' tid='126' class='m'>var</a> <a id='127' tid='128' class='m'>elm</a> <a id='129' tid='130' class='m'>=</a> <a id='131' tid='132' class='m'>document</a>.<a id='133' tid='134' class='m'>getElementById</a>(<a id='135' tid='136' class='m'>id</a>);
166    <span class='d'>if (elm != null) {
167        elm.style.backgroundColor = color;
168    }</span>
169}
170
171
172/*
173 * Highlight the link, target nodes and their lines,
174 * then start animation to move the other window to match.
175 */
176<span class='d'>function highlight(linkId, targetId, linkLineId, targetLineId)
177{
178    putHighlight(matchId, bgColor);
179    putHighlight(matchLineId, bgColor);
180    putHighlight(linkId, nodeHLColor);
181    putHighlight(linkLineId, lineHLColor);
182
183    matchId = linkId;
184    matchLineId = linkLineId;
185
186    with (otherside) {
187        putHighlight(matchId, bgColor);
188        putHighlight(matchLineId, bgColor);
189        putHighlight(targetId, nodeHLColor);
190        putHighlight(targetLineId, lineHLColor);
191
192        matchId = targetId;
193        matchLineId = targetLineId;
194
195        cTimeout = setTimeout(&quot;matchWindow(&quot; + nSteps + &quot;)&quot; , stepInterval);
196    }
197}</span>
198
199
200//////////////////////////// event handling ////////////////////////////
201/*
202 * Making other side move instantly. Move other side only if:
203 * - I am not in an animation initiated by the other side (moving)
204 * - I do not have pending program-generated scroll events.
205 *
206 * Theoretically eventCount alone should work, but this is not the
207 * case with Safari, so the &#39;moving&#39; flag is necessary!
208 */
209<span class='d'>function instantMoveOtherWindow (e) {
210    log(&quot;moving=&quot; + moving + &quot;, eventCount=&quot; + eventCount);
211    if (!moving && eventCount == 0) {
212        otherside.matchWindow(1);    
213    }
214    if (eventCount &gt; 0) {
215        eventCount--;
216    }
217    log(&quot;eventCount change=&quot; + eventCount);
218}</span>
219
220// Scroll and Resize event handlers
221<span class='d'>window.onscroll = instantMoveOtherWindow</span>
222<span class='d'>window.onresize = instantMoveOtherWindow</span>
223
224</pre>
225</div>
226<div id="right" class="src">
227<pre>
228<a id='rightstart' tid='leftstart'></a>
229// yDiff - a language-aware tool for comparing programs
230// Copyright (C) 2011 Yin Wang (yinwang0@gmail.com)
231
232
233// This program is free software: you can redistribute it and/or modify
234// it under the terms of the GNU General Public License as published by
235// the Free Software Foundation, either version 3 of the License, or
236// (at your option) any later version.
237
238// This program is distributed in the hope that it will be useful,
239// but WITHOUT ANY WARRANTY; without even the implied warranty of
240// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
241// GNU General Public License for more details.
242
243// You should have received a copy of the GNU General Public License
244// along with this program.  If not, see &lt;http://www.gnu.org/licenses/&gt;.
245
246
247
248/////////////////////// debug flag ////////////////////////
249<span class='i'>var debug = false;</span>
250
251
252/////////////////////// adjustable parameters //////////////////
253<span class='i'>var minStep = 10;</span>
254<span class='i'>var nSteps = 30;</span>
255<span class='i'>var stepInterval = 10;</span>
256<span class='i'>var blockRange = 5;</span>                    // how far consider one page blocked
257<span class='i'>var nodeHLColor = &#39;yellow&#39;;</span>
258<span class='i'>var lineHLColor = &#39;#FFFF66&#39;;</span>
259<span class='i'>var lineBlockedColor = &#39;#E9AB17&#39;;</span>
260<span class='i'>var bgColor = &#39;&#39;;</span>
261<span class='i'>var bodyBlockedColor = &#39;#FAF0E6&#39;;</span>
262
263
264///////////////////////// globals ////////////////////////
265<span class='i'>var eventCount = { &#39;left&#39; : 0, &#39;right&#39; : 0};</span>
266<span class='i'>var moving = false;</span>
267<span class='i'>var matchId1 = &#39;leftstart&#39;;</span>
268<span class='i'>var matchId2 = &#39;rightstart&#39;;</span>
269<span class='i'>var matchLineId1 = -1;</span>
270<span class='i'>var matchLineId2 = -1;</span>
271<span class='i'>var cTimeout;</span>
272
273
274///////////////////////// utilities ///////////////////////
275
276
277<span class='i'>function log(msg) {
278    if (debug) {
279        console.log(msg);
280    }
281}</span>
282
283
284
285<a id='262' tid='261' class='m'>function</a> <a id='264' tid='263' class='m'>elementPosition</a>(<a id='266' tid='265' class='m'>id</a>) {
286    <a id='268' tid='267' class='m'>obj</a> <a id='270' tid='269' class='m'>=</a> <a id='272' tid='271' class='m'>document</a>.<a id='274' tid='273' class='m'>getElementById</a>(<a id='276' tid='275' class='m'>id</a>);
287    <a id='278' tid='277' class='m'>var</a> <a id='280' tid='279' class='m'>curleft</a> <a id='282' tid='281' class='m'>=</a> <a id='284' tid='283' class='m'>0</a>, <a id='286' tid='285' class='m'>curtop</a> <a id='288' tid='287' class='m'>=</a> <a id='290' tid='289' class='m'>0</a>;
288
289    <a id='292' tid='291' class='m'>if</a> (<a id='294' tid='293' class='m'>obj</a> <a id='296' tid='295' class='m'>&&</a> <a id='298' tid='297' class='m'>obj</a>.<a id='300' tid='299' class='m'>offsetParent</a>) {
290        <a id='302' tid='301' class='m'>curleft</a> <a id='304' tid='303' class='m'>=</a> <a id='306' tid='305' class='m'>obj</a>.<a id='308' tid='307' class='m'>offsetLeft</a>;
291        <a id='310' tid='309' class='m'>curtop</a> <a id='312' tid='311' class='m'>=</a> <a id='314' tid='313' class='m'>obj</a>.<a id='316' tid='315' class='m'>offsetTop</a>;
292
293        <a id='318' tid='317' class='m'>while</a> (<a id='320' tid='319' class='m'>obj</a> <a id='322' tid='321' class='m'>=</a> <a id='324' tid='323' class='m'>obj</a>.<a id='326' tid='325' class='m'>offsetParent</a>) {
294            <a id='328' tid='327' class='m'>curleft</a> <a id='330' tid='329' class='m'>+=</a> <a id='332' tid='331' class='m'>obj</a>.<a id='334' tid='333' class='m'>offsetLeft</a>;
295            <a id='336' tid='335' class='m'>curtop</a> <a id='338' tid='337' class='m'>+=</a> <a id='340' tid='339' class='m'>obj</a>.<a id='342' tid='341' class='m'>offsetTop</a>;
296        }
297    }
298
299    <a id='344' tid='343' class='m'>return</a> { <a id='346' tid='345' class='m'>x</a>: <a id='348' tid='347' class='m'>curleft</a>, <a id='350' tid='349' class='m'>y</a>: <a id='352' tid='351' class='m'>curtop</a> };
300}
301
302
303/*
304 * Scroll the window to relative position, detecting blocking positions.
305 */
306<span class='i'>function</span> <span class='i'>scrollWithBlockCheck</span>(<span class='i'>container, distX, distY</span>) {
307    <span class='i'>var oldTop = container.scrollTop;</span>
308    <span class='i'>var oldLeft = container.scrollLeft;</span>
309
310    <span class='i'>container.scrollTop += distY;</span>      // the ONLY place for actual scrolling
311    <span class='i'>container.scrollLeft += distX;</span>
312
313    <span class='i'>var actualX = container.scrollLeft - oldLeft;</span>
314    <span class='i'>var actualY = container.scrollTop - oldTop;</span>
315    <a id='246' tid='245' class='m'>log</a>(<a id='248' tid='247' class='m'>&quot;distY=&quot;</a> <a id='250' tid='249' class='m'>+</a> <a id='252' tid='251' class='m'>distY</a> <a id='254' tid='253' class='m'>+</a> <a id='256' tid='255' class='m'>&quot;, actualY=&quot;</a> <a id='258' tid='257' class='m'>+</a> <a id='260' tid='259' class='m'>actualY</a>);
316    <span class='i'>log(&quot;distX=&quot; + distX + &quot;, actualX=&quot; + actualX);</span>
317
318    // extra leewaw here because Chrome scrolling is horribly inacurate
319    <span class='i'>if</span> ((<a id='208' tid='207' class='m'>Math</a>.<a id='210' tid='209' class='m'>abs</a>(<a id='212' tid='211' class='m'>distX</a>) <a id='214' tid='213' class='m'>&gt;</a> <a id='216' tid='215' class='m'>blockRange</a> <a id='218' tid='217' class='m'>&&</a> <a id='220' tid='219' class='m'>actualX</a> <a id='222' tid='221' class='m'>==</a> <a id='224' tid='223' class='m'>0</a>)
320        <a id='226' tid='225' class='m'>||</a> <a id='228' tid='227' class='m'>Math</a>.<a id='230' tid='229' class='m'>abs</a>(<a id='232' tid='231' class='m'>distY</a>) <a id='234' tid='233' class='m'>&gt;</a> <a id='236' tid='235' class='m'>blockRange</a> <a id='238' tid='237' class='m'>&&</a> <a id='240' tid='239' class='m'>actualY</a> <a id='242' tid='241' class='m'>==</a> <a id='244' tid='243' class='m'>0</a>) <span class='i'>{
321        log(&quot;blocked&quot;);
322        container.style.backgroundColor = bodyBlockedColor;
323        return true;
324    }</span> <span class='i'>else {
325        eventCount[container.id]++;
326        container.style.backgroundColor = bgColor;
327        return false;
328    }</span>
329}
330
331// No Math.sign() in JS?
332<a id='168' tid='167' class='m'>function</a> <a id='170' tid='169' class='m'>sign</a>(<a id='172' tid='171' class='m'>x</a>) {
333    <a id='174' tid='173' class='m'>if</a> (<a id='176' tid='175' class='m'>x</a> <a id='178' tid='177' class='m'>&gt;</a> <a id='180' tid='179' class='m'>0</a>) {
334        <a id='182' tid='181' class='m'>return</a> <a id='184' tid='183' class='m'>1</a>;
335    } <a id='186' tid='185' class='m'>else</a> <a id='188' tid='187' class='m'>if</a> (<a id='190' tid='189' class='m'>x</a> <a id='192' tid='191' class='m'>&lt;</a> <a id='194' tid='193' class='m'>0</a>) {
336        <a id='196' tid='195' class='m'>return</a> <a id='198' tid='197' class='m'>-</a><a id='200' tid='199' class='m'>1</a>;
337    } <a id='202' tid='201' class='m'>else</a> {
338        <a id='204' tid='203' class='m'>return</a> <a id='206' tid='205' class='m'>0</a>;
339    }
340}
341
342
343
344<span class='i'>function getContainer(elm) {
345    while (elm && elm.tagName != &#39;DIV&#39;) {
346        elm = elm.parentElement || elm.parentNode;
347    }
348    return elm;
349}</span>
350
351
352/*
353 * timed animation function for scrolling the current window
354 */
355<span class='i'>function</span> <span class='i'>matchWindow</span>(<span class='i'>linkId, targetId, n</span>)
356{
357    <span class='i'>moving = true;</span>
358
359    <span class='i'>var link = document.getElementById(linkId);</span>
360    <span class='i'>var target = document.getElementById(targetId);</span>
361    <span class='i'>var linkContainer = getContainer(link);</span>
362    <span class='i'>var targetContainer = getContainer(target);</span>
363
364    <span class='i'>var linkPos = elementPosition(linkId).y - linkContainer.scrollTop;</span>
365    <span class='i'>var targetPos = elementPosition(targetId).y - targetContainer.scrollTop;</span>
366    <span class='i'>var distY = targetPos - linkPos;</span>
367    <span class='i'>var distX = linkContainer.scrollLeft - targetContainer.scrollLeft;</span>
368
369
370    <a id='152' tid='151' class='m'>log</a>(<a id='154' tid='153' class='m'>&quot;matching window... &quot;</a> <a id='156' tid='155' class='m'>+</a> <a id='158' tid='157' class='m'>n</a> <a id='160' tid='159' class='m'>+</a> <a id='162' tid='161' class='m'>&quot; distY=&quot;</a> <a id='164' tid='163' class='m'>+</a> <a id='166' tid='165' class='m'>distY</a> <span class='i'>+</span> <span class='i'>&quot; distX=&quot;</span> <span class='i'>+</span> <span class='i'>distX</span>);
371
372    <span class='i'>if</span> (<a id='138' tid='137' class='m'>distY</a> <a id='140' tid='139' class='m'>==</a> <a id='142' tid='141' class='m'>0</a> <a id='144' tid='143' class='m'>&&</a> <a id='146' tid='145' class='m'>distX</a> <a id='148' tid='147' class='m'>==</a> <a id='150' tid='149' class='m'>0</a>) <span class='i'>{
373        clearTimeout(cTimeout);
374        moving = false;
375    }</span> <span class='i'>else</span> <span class='i'>if</span> <span class='i'>(n &lt;= 1)</span> <span class='i'>{
376        scrollWithBlockCheck(targetContainer, distX, distY);
377        moving = false;
378    }</span> <a id='96' tid='95' class='m'>else</a> {
379        <a id='98' tid='97' class='m'>var</a> <a id='100' tid='99' class='m'>stepSize</a> <a id='102' tid='101' class='m'>=</a> <a id='104' tid='103' class='m'>Math</a>.<a id='106' tid='105' class='m'>floor</a>(<a id='108' tid='107' class='m'>Math</a>.<a id='110' tid='109' class='m'>abs</a>(<a id='112' tid='111' class='m'>distY</a>) <a id='114' tid='113' class='m'>/</a> <a id='116' tid='115' class='m'>n</a>);
380        <a id='80' tid='79' class='m'>actualMinStep</a> <a id='82' tid='81' class='m'>=</a> <a id='84' tid='83' class='m'>Math</a>.<a id='86' tid='85' class='m'>min</a>(<a id='88' tid='87' class='m'>minStep</a>, <a id='90' tid='89' class='m'>Math</a>.<a id='92' tid='91' class='m'>abs</a>(<a id='94' tid='93' class='m'>distY</a>));
381        <a id='38' tid='37' class='m'>if</a> (<a id='40' tid='39' class='m'>Math</a>.<a id='42' tid='41' class='m'>abs</a>(<a id='44' tid='43' class='m'>stepSize</a>) <a id='46' tid='45' class='m'>&lt;</a> <a id='48' tid='47' class='m'>minStep</a>) {
382            <a id='50' tid='49' class='m'>var</a> <a id='52' tid='51' class='m'>step</a> <a id='54' tid='53' class='m'>=</a> <a id='56' tid='55' class='m'>actualMinStep</a> <a id='58' tid='57' class='m'>*</a> <a id='60' tid='59' class='m'>sign</a>(<a id='62' tid='61' class='m'>distY</a>);
383        } <a id='64' tid='63' class='m'>else</a> {
384            <a id='66' tid='65' class='m'>var</a> <a id='68' tid='67' class='m'>step</a> <a id='70' tid='69' class='m'>=</a> <a id='72' tid='71' class='m'>stepSize</a> <a id='74' tid='73' class='m'>*</a> <a id='76' tid='75' class='m'>sign</a>(<a id='78' tid='77' class='m'>distY</a>);
385        }
386        <span class='i'>var blocked = scrollWithBlockCheck(targetContainer, distX, step);</span>
387        <a id='18' tid='17' class='m'>var</a> <a id='20' tid='19' class='m'>rest</a> <a id='22' tid='21' class='m'>=</a> <a id='24' tid='23' class='m'>Math</a>.<a id='26' tid='25' class='m'>floor</a>(<a id='28' tid='27' class='m'>distY</a> <a id='30' tid='29' class='m'>/</a> <a id='32' tid='31' class='m'>step</a>) <a id='34' tid='33' class='m'>-</a> <a id='36' tid='35' class='m'>1</a>;
388        <a id='2' tid='1' class='m'>log</a>(<a id='4' tid='3' class='m'>&quot;blocked?&quot;</a> <a id='6' tid='5' class='m'>+</a> <a id='8' tid='7' class='m'>blocked</a> <a id='10' tid='9' class='m'>+</a> <a id='12' tid='11' class='m'>&quot;, rest steps=&quot;</a> <a id='14' tid='13' class='m'>+</a> <a id='16' tid='15' class='m'>rest</a>);
389        <span class='i'>if (!blocked) {
390            cTimeout = setTimeout(&quot;matchWindow(&quot; + linkId + &quot;,&quot; + targetId + &quot;,&quot;
391                                  + rest + &quot;)&quot;, stepInterval);
392        } else {
393            clearTimeout(cTimeout);
394            moving = false;
395        }</span>
396    }
397}
398
399
400
401////////////////////////// highlighting /////////////////////////////
402
403<span class='i'>var highlighted = []</span>
404<a id='118' tid='117' class='m'>function</a> <a id='120' tid='119' class='m'>putHighlight</a>(<a id='122' tid='121' class='m'>id</a>, <a id='124' tid='123' class='m'>color</a>) {
405    <a id='126' tid='125' class='m'>var</a> <a id='128' tid='127' class='m'>elm</a> <a id='130' tid='129' class='m'>=</a> <a id='132' tid='131' class='m'>document</a>.<a id='134' tid='133' class='m'>getElementById</a>(<a id='136' tid='135' class='m'>id</a>);
406    <span class='i'>if (elm != null) {
407        elm.style.backgroundColor = color;
408        if (color != bgColor) {
409            highlighted.push(id);
410        }
411    }</span>
412}
413
414
415<span class='i'>function clearHighlight() {
416    for (i = 0; i &lt; highlighted.length; i++) {
417        putHighlight(highlighted[i], bgColor);
418    }
419    highlighted = [];
420}</span>
421
422
423
424/*
425 * Highlight the link, target nodes and their lines,
426 * then start animation to move the other window to match.
427 */
428<span class='i'>function highlight(me, linkId, targetId, linkLineId, targetLineId)
429{
430    if (me.id == &#39;left&#39;) {
431        matchId1 = linkId;
432        matchId2 = targetId;
433    } else {
434        matchId1 = targetId;
435        matchId2 = linkId;
436    }
437
438    clearHighlight();
439
440    putHighlight(linkId, nodeHLColor);
441    putHighlight(targetId, nodeHLColor);
442    putHighlight(linkLineId, lineHLColor);
443    putHighlight(targetLineId, lineHLColor);
444
445    matchWindow(linkId, targetId, nSteps);
446}</span>
447
448
449<span class='i'>function instantMoveOtherWindow (me) {
450    log(&quot;me=&quot; + me.id + &quot;, eventcount=&quot; + eventCount[me.id]);
451    log(&quot;matchId1=&quot; + matchId1 + &quot;, matchId2=&quot; + matchId2);
452
453    me.style.backgroundColor = bgColor;
454
455    if (!moving && eventCount[me.id] == 0) {
456        if (me.id == &#39;left&#39;) {
457            matchWindow(matchId1, matchId2, 1);
458        } else {
459            matchWindow(matchId2, matchId1, 1);
460        }
461    }
462    if (eventCount[me.id] &gt; 0) {
463        eventCount[me.id] -= 1;
464    }
465}</span>
466
467
468<span class='i'>function getTarget(x){
469    x = x || window.event;
470    return x.target || x.srcElement;
471}</span>
472
473
474<span class='i'>window.onload =
475    function (e) {
476        var tags = document.getElementsByTagName(&quot;A&quot;)
477        for (var i = 0; i &lt; tags.length; i++) {
478            tags[i].onclick =
479                function (e) {
480                    var t = getTarget(e)
481                    var lid = t.id
482                    var tid = t.getAttribute(&#39;tid&#39;)
483                    var container = getContainer(t)
484                    highlight(container, lid, tid, &#39;ignore&#39;, &#39;ignore&#39;)
485                }
486        }
487
488        tags = document.getElementsByTagName(&quot;DIV&quot;)
489        for (var i = 0; i &lt; tags.length; i++) {
490            tags[i].onscroll =
491                function (e) {
492                    instantMoveOtherWindow(getTarget(e))
493                }
494        }
495
496    }</span>
497
498</pre>
499</div>
500</body>
501</html>