1<!DOCTYPE html> 2<!-- 3Copyright (c) 2015 The Chromium Authors. All rights reserved. 4Use of this source code is governed by a BSD-style license that can be 5found in the LICENSE file. 6--> 7 8<link rel="import" href="/tracing/base/base.html"> 9 10<script> 11'use strict'; 12 13tr.exportTo('tr.model', function() { 14 /** 15 * YComponent is a class that handles storing the stableId and the percentage 16 * offset in the y direction of all tracks within a specific viewX and viewY 17 * coordinate. 18 * @constructor 19 */ 20 function YComponent(stableId, yPercentOffset) { 21 this.stableId = stableId; 22 this.yPercentOffset = yPercentOffset; 23 } 24 25 YComponent.prototype = { 26 toDict: function() { 27 return { 28 stableId: this.stableId, 29 yPercentOffset: this.yPercentOffset 30 }; 31 } 32 }; 33 34 /** 35 * Location is a class that represents a spatial location on the timeline 36 * that is specified by percent offsets within tracks rather than specific 37 * points. 38 * 39 * @constructor 40 */ 41 function Location(xWorld, yComponents) { 42 this.xWorld_ = xWorld; 43 this.yComponents_ = yComponents; 44 }; 45 46 /** 47 * Returns a new Location given by x and y coordinates with respect to 48 * the timeline's drawing canvas. 49 */ 50 Location.fromViewCoordinates = function(viewport, viewX, viewY) { 51 var dt = viewport.currentDisplayTransform; 52 var xWorld = dt.xViewToWorld(viewX); 53 var yComponents = []; 54 55 // Since we're given coordinates within the timeline canvas, we need to 56 // convert them to document coordinates to get the element. 57 var elem = document.elementFromPoint( 58 viewX + viewport.modelTrackContainer.canvas.offsetLeft, 59 viewY + viewport.modelTrackContainer.canvas.offsetTop); 60 // Build yComponents by calculating percentage offset with respect to 61 // each parent track. 62 while (elem instanceof tr.ui.tracks.Track) { 63 if (elem.eventContainer) { 64 var boundRect = elem.getBoundingClientRect(); 65 var yPercentOffset = (viewY - boundRect.top) / boundRect.height; 66 yComponents.push( 67 new YComponent(elem.eventContainer.stableId, yPercentOffset)); 68 } 69 elem = elem.parentElement; 70 } 71 72 if (yComponents.length == 0) 73 return; 74 return new Location(xWorld, yComponents); 75 } 76 77 Location.fromStableIdAndTimestamp = function(viewport, stableId, ts) { 78 var xWorld = ts; 79 var yComponents = []; 80 81 // The y components' percentage offsets will be calculated with respect to 82 // the boundingRect's top of containing track. 83 var containerToTrack = viewport.containerToTrackMap; 84 var elem = containerToTrack.getTrackByStableId(stableId); 85 if (!elem) 86 return; 87 88 var firstY = elem.getBoundingClientRect().top; 89 while (elem instanceof tr.ui.tracks.Track) { 90 if (elem.eventContainer) { 91 var boundRect = elem.getBoundingClientRect(); 92 var yPercentOffset = (firstY - boundRect.top) / boundRect.height; 93 yComponents.push( 94 new YComponent(elem.eventContainer.stableId, yPercentOffset)); 95 } 96 elem = elem.parentElement; 97 } 98 99 if (yComponents.length == 0) 100 return; 101 return new Location(xWorld, yComponents); 102 } 103 104 Location.prototype = { 105 106 get xWorld() { 107 return this.xWorld_; 108 }, 109 110 /** 111 * Returns the first valid containing track based on the 112 * internal yComponents. 113 */ 114 getContainingTrack: function(viewport) { 115 var containerToTrack = viewport.containerToTrackMap; 116 for (var i in this.yComponents_) { 117 var yComponent = this.yComponents_[i]; 118 var track = containerToTrack.getTrackByStableId(yComponent.stableId); 119 if (track !== undefined) 120 return track; 121 } 122 }, 123 124 /** 125 * Calculates and returns x and y coordinates of the current location with 126 * respect to the timeline's canvas. 127 */ 128 toViewCoordinates: function(viewport) { 129 var dt = viewport.currentDisplayTransform; 130 var containerToTrack = viewport.containerToTrackMap; 131 var viewX = dt.xWorldToView(this.xWorld_); 132 133 var viewY = -1; 134 for (var index in this.yComponents_) { 135 var yComponent = this.yComponents_[index]; 136 var track = containerToTrack.getTrackByStableId(yComponent.stableId); 137 if (track !== undefined) { 138 var boundRect = track.getBoundingClientRect(); 139 viewY = yComponent.yPercentOffset * boundRect.height + boundRect.top; 140 break; 141 } 142 } 143 144 return { 145 viewX: viewX, 146 viewY: viewY 147 }; 148 }, 149 150 toDict: function() { 151 return { 152 xWorld: this.xWorld_, 153 yComponents: this.yComponents_ 154 }; 155 } 156 }; 157 158 return { 159 Location: Location 160 }; 161}); 162</script> 163