blob: 5cc4ded740c7e4a02925d4d56847b4bbd48c63b3 [file] [log] [blame]
<!DOCTYPE html>
<!--
Copyright 2015 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script type="text/javascript" src="https://apis.google.com/js/api.js"></script>
<link rel="import" href="/components/polymer/polymer.html">
<link rel="import" href="/core/timeline_view.html">
<link rel="import" href="/extras/full_config.html">
<link rel="import" href="/extras/drive/drive_comment_provider.html">
<style>
body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
display: -webkit-flex;
-webkit-flex-direction: column;
}
body > x-timeline-view {
-webkit-flex: 1 1 auto;
overflow: hidden;
position: absolute;
top: 0px;
bottom: 0;
left: 0;
right: 0;
}
nav {
display: flex;
flex-direction: row;
justify-content: flex-end;
}
#navbar button {
height: 24px;
padding-bottom: 3px;
vertical-align: middle;
box-shadow: none;
background-color: #4d90fe;
background-image: -webkit-linear-gradient(top,#4d90fe,#4787ed);
border: 1px solid #3079ed;
color: #fff;
border-radius: 2px;
cursor: default;
font-size: 11px;
font-weight: bold;
text-align: center;
white-space: nowrap;
line-height: 27px;
min-width: 54px;
outline: 0px;
padding: 0 8px;
font: normal 13px arial,sans-serif;
margin: 5px;
}
#collabs {
display: flex;
flex-direction: row;
}
.collaborator-div {
display: inline-block;
vertical-align: middle;
min-height: 0;
width: 100px;
font-size: 11px;
font-weight: bold;
font: normal 13px arial,sans-serif;
margin: 10px;
}
.collaborator-img {
margin: 2px;
}
.collaborator-tooltip {
z-index: 10000;
transition: visibility 0,opacity .13s ease-in;
background-color: #2a2a2a;
border: 1px solid #fff;
color: #fff;
cursor: default;
display: block;
font-family: arial, sans-serif;
font-size: 11px;
font-weight: bold;
margin-left: -1px;
opacity: 1;
padding: 7px 9px;
word-break: break-word;
position: absolute;
}
.collaborator-tooltip-content {
color: #fff;
}
.collaborator-tooltip-arrow {
position: absolute;
top: -6px;
}
.collaborator-tooltip-arrow-before {
border-color: #fff transparent !important;
left: -6px;
border: 6px solid;
border-top-width: 0;
content: '';
display: block;
height: 0;
position: absolute;
width: 0;
}
.collaborator-tooltip-arrow-after {
top: 1px;
border-color: #2a2a2a transparent !important;
left: -5px;
border: 5px solid;
border-top-width: 0;
content: '';
display: block;
height: 0;
position: absolute;
width: 0;
}
</style>
<title>Trace Viewer</title>
</head>
<body>
<nav id="navbar">
<div id="collabs"></div>
<button id="x-drive-save-to-disk">Save to disk</button>
<button id="x-drive-save-to-drive">Save to Drive</button>
<button id="x-drive-load-from-drive">Load from Drive</button>
<button id="x-drive-share">Share</button>
</nav>
<x-timeline-view>
</x-timeline-view>
<script>
'use strict';
// Needs to be global as it's passed through the Google API as a
// GET parameter.
var onAPIClientLoaded_ = null;
(function() {
tr.exportTo('tr.e.drive', function() {
var appId = '239864068844';
var constants = {
APP_ID: appId,
ANCHOR_NAME: appId + '.trace_viewer',
DEVELOPER_KEY: 'AIzaSyDR-6_wL9vHg1_oz4JHk8IQAkv2_Y0Y8-M',
CLIENT_ID: '239864068844-c7gefbfdcp0j6grltulh2r88tsvl18c1.apps.' +
'googleusercontent.com',
SCOPE: [
'https://www.googleapis.com/auth/drive',
'https://www.googleapis.com/auth/drive.install',
'https://www.googleapis.com/auth/drive.file',
'profile'
]
};
return {
getDriveFileId: function() { return driveFileId_; },
constants: constants
};
});
var pickerApiLoaded_ = false;
var oauthToken_ = null;
var timelineViewEl_ = null;
var driveDocument_ = null;
var shareClient_ = null;
var fileIdToLoad_ = null;
var driveFileId_ = null;
function parseGETParameter(val) {
var result = null;
var tmp = [];
location.search.substr(1).split('&').forEach(function(item) {
tmp = item.split('=');
if (tmp[0] === val)
result = decodeURIComponent(tmp[1]);
});
return result;
}
// Use the Google API Loader script to load the google.picker script.
onAPIClientLoaded_ = function() {
var driveState = parseGETParameter('state');
if (driveState != null) {
var driveStateJson = JSON.parse(driveState);
fileIdToLoad_ = String(driveStateJson.ids);
}
gapi.load('picker', {'callback': onPickerApiLoad});
gapi.load('auth', {'callback': function() {
onAuthApiLoad(true, onAuthResultSuccess);
setTimeout(function onRepeatAuthApiLoad() {
onAuthApiLoad(true, function() {});
setTimeout(onRepeatAuthApiLoad, 30000);
}, 30000);
}});
}
function onAuthApiLoad(tryImmediate, resultCallback) {
window.gapi.auth.authorize(
{'client_id': tr.e.drive.constants.CLIENT_ID,
'scope': tr.e.drive.constants.SCOPE, 'immediate': tryImmediate},
function(authResult) {
handleAuthResult(authResult, tryImmediate, resultCallback);
});
}
function onPickerApiLoad() {
pickerApiLoaded_ = true;
if (fileIdToLoad_ == null)
createPicker();
}
function onAuthResultSuccess() {
if (fileIdToLoad_ == null)
createPicker();
else
loadFileFromDrive(fileIdToLoad_);
}
function handleAuthResult(authResult, wasImmediate, resultCallback) {
if (authResult && !authResult.error) {
oauthToken_ = authResult.access_token;
resultCallback();
} else if (wasImmediate) {
onAuthApiLoad(false);
}
}
function createPicker() {
if (pickerApiLoaded_ && oauthToken_) {
var view = new google.picker.View(google.picker.ViewId.DOCS);
view.setMimeTypes('application/json,application/octet-stream');
var picker = new google.picker.PickerBuilder()
.enableFeature(google.picker.Feature.NAV_HIDDEN)
.enableFeature(google.picker.Feature.MULTISELECT_ENABLED)
.setAppId(tr.e.drive.constants.APP_ID)
.setOAuthToken(oauthToken_)
.addView(view)
.addView(new google.picker.DocsUploadView())
.setDeveloperKey(tr.e.drive.constants.DEVELOPER_KEY)
.setCallback(pickerCallback)
.build();
picker.setVisible(true);
}
}
function pickerCallback(data) {
if (data.action == google.picker.Action.PICKED) {
loadFileFromDrive(data.docs[0].id);
}
}
function initShareButton() {
shareClient_ = new gapi.drive.share.ShareClient(
tr.e.drive.constants.APP_ID);
shareClient_.setItemIds([driveFileId_]);
}
function loadFileFromDrive(fileId) {
gapi.client.load('drive', 'v2', function() {
var request = gapi.client.drive.files.get({'fileId': fileId});
request.execute(function(resp) { downloadFile(resp); });
driveFileId_ = fileId;
gapi.load('drive-share', initShareButton);
});
}
function downloadFile(file) {
if (file.downloadUrl) {
var downloadingOverlay = tr.b.ui.Overlay();
downloadingOverlay.title = 'Downloading...';
downloadingOverlay.userCanClose = false;
downloadingOverlay.msgEl = document.createElement('div');
downloadingOverlay.appendChild(downloadingOverlay.msgEl);
downloadingOverlay.msgEl.style.margin = '20px';
downloadingOverlay.update = function(msg) {
this.msgEl.textContent = msg;
}
downloadingOverlay.visible = true;
var accessToken = gapi.auth.getToken().access_token;
var xhr = new XMLHttpRequest();
xhr.open('GET', file.downloadUrl);
xhr.setRequestHeader('Authorization', 'Bearer ' + accessToken);
xhr.onload = function() {
downloadingOverlay.visible = false;
onDownloaded(file.title, xhr.responseText);
};
xhr.onprogress = function(evt) {
downloadingOverlay.update(
Math.floor(evt.position * 100 / file.fileSize) + '% complete');
};
xhr.onerror = function() { alert('Failed downloading!'); };
xhr.send();
} else {
alert('No URL!');
}
}
function displayAllCollaborators() {
var allCollaborators = driveDocument_.getCollaborators();
var collaboratorCount = allCollaborators.length;
var collabspan = document.getElementById('collabs');
collabspan.innerHTML = '';
var imageList = [];
for (var i = 0; i < collaboratorCount; i++) {
var user = allCollaborators[i];
var img = document.createElement('img');
img.src = user.photoUrl;
img.alt = user.displayName;
img.height = 30;
img.width = 30;
img.className = 'collaborator-img';
collabspan.appendChild(img);
imageList.push({'image': img, 'name': user.displayName});
}
for (i = 0; i < imageList.length; i++) {
var collabTooltip = tr.b.ui.createDiv({
className: 'collaborator-tooltip'
});
var collabTooltipContent = tr.b.ui.createDiv({
className: 'collaborator-tooltip-content'
});
collabTooltipContent.textContent = imageList[i].name;
collabTooltip.appendChild(collabTooltipContent);
collabspan.appendChild(collabTooltip);
var collabTooltipArrow = tr.b.ui.createDiv({
className: 'collaborator-tooltip-arrow'});
collabTooltip.appendChild(collabTooltipArrow);
var collabTooltipArrowBefore = tr.b.ui.createDiv({
className: 'collaborator-tooltip-arrow-before'});
collabTooltipArrow.appendChild(collabTooltipArrowBefore);
var collabTooltipArrowAfter = tr.b.ui.createDiv({
className: 'collaborator-tooltip-arrow-after'});
collabTooltipArrow.appendChild(collabTooltipArrowAfter);
var rect = imageList[i].image.getBoundingClientRect();
collabTooltip.style.top = (rect.bottom - 6) + 'px';
collabTooltip.style.left =
(rect.left + 16 - (collabTooltip.offsetWidth / 2)) + 'px';
collabTooltipArrow.style.left = (collabTooltip.offsetWidth / 2) + 'px';
collabTooltip.style.visibility = 'hidden';
function visibilityDelegate(element, visibility) {
return function() {
element.style.visibility = visibility;
}
}
imageList[i].image.addEventListener(
'mouseover', visibilityDelegate(collabTooltip, 'visible'));
imageList[i].image.addEventListener(
'mouseout', visibilityDelegate(collabTooltip, 'hidden'));
}
}
function onRealtimeFileLoaded(doc) {
if (driveDocument_)
driveDocument_.close();
driveDocument_ = doc;
doc.addEventListener(gapi.drive.realtime.EventType.COLLABORATOR_JOINED,
displayAllCollaborators);
doc.addEventListener(gapi.drive.realtime.EventType.COLLABORATOR_LEFT,
displayAllCollaborators);
displayAllCollaborators(doc);
}
function onRealtimeError(e) {
alert('Error loading realtime: ' + e);
}
function onDownloaded(filename, content) {
gapi.load('auth:client,drive-realtime,drive-share', function() {
gapi.drive.realtime.load(driveFileId_,
onRealtimeFileLoaded,
null,
onRealtimeError);
});
var traces = [];
var filenames = [];
filenames.push(filename);
traces.push(content);
createViewFromTraces(filenames, traces);
}
function createViewFromTraces(filenames, traces) {
var m = new tr.Model();
var p = m.importTracesWithProgressDialog(traces, true);
p.then(
function() {
timelineViewEl_.model = m;
timelineViewEl_.updateDocumentFavicon();
timelineViewEl_.tabIndex = 1;
if (timelineViewEl_.timeline)
timelineViewEl_.timeline.focusElement = timelineViewEl_;
timelineViewEl_.viewTitle = '';
},
function(err) {
var downloadingOverlay = new tr.b.ui.Overlay();
downloadingOverlay.textContent =
tr.b.normalizeException(err).message;
downloadingOverlay.title = 'Import error';
downloadingOverlay.visible = true;
});
}
function onSaveToDiskClicked() {
throw new Error('Not implemented');
}
function onSaveToDriveClicked() {
throw new Error('Not implemented');
}
function onLoadFromDriveClicked() {
createPicker();
}
function onLoad() {
timelineViewEl_ = document.querySelector('x-timeline-view');
var navbar = document.getElementById('navbar');
timelineViewEl_.style.top = navbar.offsetHeight + 'px';
tr.b.ui.decorate(timelineViewEl_, tr.c.TimelineView);
}
window.addEventListener('load', onLoad);
document.getElementById('x-drive-save-to-disk').onclick =
onSaveToDiskClicked;
document.getElementById('x-drive-save-to-drive').onclick =
onSaveToDriveClicked;
document.getElementById('x-drive-load-from-drive').onclick =
onLoadFromDriveClicked;
document.getElementById('x-drive-share').onclick = function() {
shareClient_.showSettingsDialog();
};
}());
</script>
<script type="text/javascript"
src="https://apis.google.com/js/client.js?onload=onAPIClientLoaded_">
</script>
</body>