michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: "use strict"; michael@0: michael@0: var gInstanceUID; michael@0: var gParsedQS; michael@0: var gHideSourceLinks; michael@0: michael@0: function getParam(key) { michael@0: if (gParsedQS) michael@0: return gParsedQS[key]; michael@0: michael@0: var query = window.location.search.substring(1); michael@0: gParsedQS = {}; michael@0: michael@0: query.split("&").forEach(function (pair) { michael@0: pair = pair.split("="); michael@0: gParsedQS[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]); michael@0: }); michael@0: michael@0: return gParsedQS[key]; michael@0: } michael@0: michael@0: /** michael@0: * Sends a message to the parent window with a status michael@0: * update. michael@0: * michael@0: * @param string status michael@0: * Status to send to the parent page: michael@0: * - loaded, when page is loaded. michael@0: * - displaysource, when user wants to display source michael@0: * @param object data (optional) michael@0: * Additional data to send to the parent page. michael@0: */ michael@0: function notifyParent(status, data={}) { michael@0: if (!gInstanceUID) { michael@0: gInstanceUID = getParam("uid"); michael@0: } michael@0: michael@0: window.parent.postMessage({ michael@0: uid: gInstanceUID, michael@0: status: status, michael@0: data: data michael@0: }, "*"); michael@0: } michael@0: michael@0: /** michael@0: * A listener for incoming messages from the parent michael@0: * page. All incoming messages must be stringified michael@0: * JSON objects to be compatible with Cleopatra's michael@0: * format: michael@0: * michael@0: * { michael@0: * task: string, michael@0: * ... michael@0: * } michael@0: * michael@0: * This listener recognizes two tasks: onStarted and michael@0: * onStopped. michael@0: * michael@0: * @param object event michael@0: * PostMessage event object. michael@0: */ michael@0: function onParentMessage(event) { michael@0: var start = document.getElementById("startWrapper"); michael@0: var stop = document.getElementById("stopWrapper"); michael@0: var profilerMessage = document.getElementById("profilerMessage"); michael@0: var msg = JSON.parse(event.data); michael@0: michael@0: if (msg.task !== "receiveProfileData" && !msg.isCurrent) { michael@0: return; michael@0: } michael@0: michael@0: switch (msg.task) { michael@0: case "onStarted": michael@0: start.style.display = "none"; michael@0: start.querySelector("button").removeAttribute("disabled"); michael@0: stop.style.display = "inline"; michael@0: break; michael@0: case "onStopped": michael@0: stop.style.display = "none"; michael@0: stop.querySelector("button").removeAttribute("disabled"); michael@0: start.style.display = "inline"; michael@0: break; michael@0: case "receiveProfileData": michael@0: loadProfile(JSON.stringify(msg.rawProfile)); michael@0: } michael@0: } michael@0: michael@0: window.addEventListener("message", onParentMessage); michael@0: michael@0: /** michael@0: * Main entry point. This function initializes Cleopatra michael@0: * in the light mode and creates all the UI we need. michael@0: */ michael@0: function initUI() { michael@0: gHideSourceLinks = getParam("ext") === "true"; michael@0: gFileList = { profileParsingFinished: function () {} }; michael@0: gInfoBar = { display: function () {} }; michael@0: michael@0: var container = document.createElement("div"); michael@0: container.id = "ui"; michael@0: michael@0: gMainArea = document.createElement("div"); michael@0: gMainArea.id = "mainarea"; michael@0: michael@0: container.appendChild(gMainArea); michael@0: document.body.appendChild(container); michael@0: } michael@0: michael@0: /** michael@0: * Modified copy of Cleopatra's enterFinishedProfileUI. michael@0: * By overriding the function we don't need to modify ui.js which helps michael@0: * with updating from upstream. michael@0: */ michael@0: function enterFinishedProfileUI() { michael@0: var cover = document.createElement("div"); michael@0: cover.className = "finishedProfilePaneBackgroundCover"; michael@0: michael@0: var pane = document.createElement("table"); michael@0: var rowIndex = 0; michael@0: var currRow; michael@0: michael@0: pane.style.width = "100%"; michael@0: pane.style.height = "100%"; michael@0: pane.border = "0"; michael@0: pane.cellPadding = "0"; michael@0: pane.cellSpacing = "0"; michael@0: pane.borderCollapse = "collapse"; michael@0: pane.className = "finishedProfilePane"; michael@0: michael@0: gBreadcrumbTrail = new BreadcrumbTrail(); michael@0: currRow = pane.insertRow(rowIndex++); michael@0: currRow.insertCell(0).appendChild(gBreadcrumbTrail.getContainer()); michael@0: michael@0: gHistogramView = new HistogramView(); michael@0: currRow = pane.insertRow(rowIndex++); michael@0: currRow.insertCell(0).appendChild(gHistogramView.getContainer()); michael@0: michael@0: if (gMeta && gMeta.videoCapture) { michael@0: gVideoPane = new VideoPane(gMeta.videoCapture); michael@0: gVideoPane.onTimeChange(videoPaneTimeChange); michael@0: currRow = pane.insertRow(rowIndex++); michael@0: currRow.insertCell(0).appendChild(gVideoPane.getContainer()); michael@0: } michael@0: michael@0: var tree = document.createElement("div"); michael@0: tree.className = "treeContainer"; michael@0: tree.style.width = "100%"; michael@0: tree.style.height = "100%"; michael@0: michael@0: gTreeManager = new ProfileTreeManager(); michael@0: gTreeManager.treeView.setColumns([ michael@0: { name: "sampleCount", title: gStrings["Running Time"] }, michael@0: { name: "selfSampleCount", title: gStrings["Self"] }, michael@0: { name: "resource", title: "" } michael@0: ]); michael@0: michael@0: currRow = pane.insertRow(rowIndex++); michael@0: currRow.style.height = "100%"; michael@0: michael@0: var cell = currRow.insertCell(0); michael@0: cell.appendChild(tree); michael@0: tree.appendChild(gTreeManager.getContainer()); michael@0: michael@0: gPluginView = new PluginView(); michael@0: tree.appendChild(gPluginView.getContainer()); michael@0: michael@0: gMainArea.appendChild(cover); michael@0: gMainArea.appendChild(pane); michael@0: michael@0: var currentBreadcrumb = gSampleFilters; michael@0: gBreadcrumbTrail.add({ michael@0: title: gStrings["Complete Profile"], michael@0: enterCallback: function () { michael@0: gSampleFilters = []; michael@0: filtersChanged(); michael@0: } michael@0: }); michael@0: michael@0: if (currentBreadcrumb == null || currentBreadcrumb.length == 0) { michael@0: gTreeManager.restoreSerializedSelectionSnapshot(gRestoreSelection); michael@0: viewOptionsChanged(); michael@0: } michael@0: michael@0: for (var i = 0; i < currentBreadcrumb.length; i++) { michael@0: var filter = currentBreadcrumb[i]; michael@0: var forceSelection = null; michael@0: if (gRestoreSelection != null && i == currentBreadcrumb.length - 1) { michael@0: forceSelection = gRestoreSelection; michael@0: } michael@0: switch (filter.type) { michael@0: case "FocusedFrameSampleFilter": michael@0: focusOnSymbol(filter.name, filter.symbolName); michael@0: gBreadcrumbTrail.enterLastItem(forceSelection); michael@0: case "FocusedCallstackPrefixSampleFilter": michael@0: focusOnCallstack(filter.focusedCallstack, filter.name, false); michael@0: gBreadcrumbTrail.enterLastItem(forceSelection); michael@0: case "FocusedCallstackPostfixSampleFilter": michael@0: focusOnCallstack(filter.focusedCallstack, filter.name, true); michael@0: gBreadcrumbTrail.enterLastItem(forceSelection); michael@0: case "RangeSampleFilter": michael@0: gHistogramView.selectRange(filter.start, filter.end); michael@0: gBreadcrumbTrail.enterLastItem(forceSelection); michael@0: } michael@0: } michael@0: michael@0: // Show platform data? michael@0: if (getParam("spd") !== "true") michael@0: toggleJavascriptOnly(); michael@0: } michael@0: michael@0: function enterProgressUI() { michael@0: var pane = document.createElement("div"); michael@0: var label = document.createElement("a"); michael@0: var bar = document.createElement("progress"); michael@0: var string = gStrings.getStr("profiler.loading"); michael@0: michael@0: pane.className = "profileProgressPane"; michael@0: pane.appendChild(label); michael@0: pane.appendChild(bar); michael@0: michael@0: var reporter = new ProgressReporter(); michael@0: reporter.addListener(function (rep) { michael@0: var progress = rep.getProgress(); michael@0: michael@0: if (label.textContent !== string) { michael@0: label.textContent = string; michael@0: } michael@0: michael@0: if (isNaN(progress)) { michael@0: bar.removeAttribute("value"); michael@0: } else { michael@0: bar.value = progress; michael@0: } michael@0: }); michael@0: michael@0: gMainArea.appendChild(pane); michael@0: Parser.updateLogSetting(); michael@0: michael@0: return reporter; michael@0: }