devtools-timeline-model
Advanced tools
Comparing version 1.0.15 to 1.0.16
129
index.js
/* global WebInspector TimelineModelTreeView */ | ||
'use strict'; | ||
// DevTools relies on a global WebInspector variable. :( | ||
// This callWithGlobals BS is a nasty hack to keep this global exclusive to our model | ||
var callWithGlobals = require('call-with-globals'); | ||
var _WebInspector = {} | ||
var _WI_global = { WebInspector: _WebInspector } | ||
var fs = require('fs'); | ||
var vm = require('vm') | ||
class TraceToTimelineModel { | ||
class ModelAPI { | ||
constructor(events) { | ||
var instance = this; | ||
callWithGlobals(_ => { | ||
// Everything happens in a sandboxed vm context, to keep globals and natives separate. | ||
var glob = { require: require, global: global, console: console, process, process, __dirname: __dirname } | ||
var script = new vm.Script(fs.readFileSync(__dirname + "/lib/timeline-model.js", 'utf8')) | ||
var ctx = vm.createContext(glob) | ||
var output = script.runInContext(ctx) | ||
// Other globals and stubs | ||
require('./lib/api-stubs') | ||
// Pull in the devtools frontend | ||
require('chrome-devtools-frontend/front_end/common/Object.js') | ||
require('chrome-devtools-frontend/front_end/common/SegmentedRange.js') | ||
require('chrome-devtools-frontend/front_end/platform/utilities.js') | ||
require('chrome-devtools-frontend/front_end/sdk/Target.js') | ||
require('chrome-devtools-frontend/front_end/bindings/TempFile.js') | ||
require('chrome-devtools-frontend/front_end/sdk/TracingModel.js') | ||
require('chrome-devtools-frontend/front_end/timeline/TimelineJSProfile.js') | ||
require('chrome-devtools-frontend/front_end/timeline/TimelineUIUtils.js') | ||
require('chrome-devtools-frontend/front_end/sdk/CPUProfileDataModel.js') | ||
require('chrome-devtools-frontend/front_end/timeline/LayerTreeModel.js') | ||
require('chrome-devtools-frontend/front_end/timeline/TimelineModel.js') | ||
require('chrome-devtools-frontend/front_end/timeline/TimelineTreeView.js') | ||
require('chrome-devtools-frontend/front_end/ui_lazy/SortableDataGrid.js') | ||
require('chrome-devtools-frontend/front_end/timeline/TimelineProfileTree.js') | ||
require('chrome-devtools-frontend/front_end/components_lazy/FilmStripModel.js') | ||
require('chrome-devtools-frontend/front_end/timeline/TimelineIRModel.js') | ||
require('chrome-devtools-frontend/front_end/timeline/TimelineFrameModel.js') | ||
// minor configurations | ||
require('./lib/devtools-init') | ||
// polyfill the bottom-up and topdown tree sorting | ||
require('./lib/timeline-model-treeview') | ||
this.sandbox = ctx.instance; | ||
this.sandbox.init(events); | ||
// (devtools) tracing model | ||
instance._tracingModel = new WebInspector.TracingModel(new WebInspector.TempFileBackingStorage('tracing')) | ||
// timeline model | ||
instance._timelineModel = new WebInspector.TimelineModel(WebInspector.TimelineUIUtils.visibleEventsFilter()) | ||
// populate with events | ||
instance._tracingModel.reset() | ||
instance._tracingModel.addEvents(typeof events === 'string' ? JSON.parse(events) : events) | ||
instance._tracingModel.tracingComplete() | ||
instance._timelineModel.setEvents(instance._tracingModel) | ||
instance._aggregator = new WebInspector.TimelineAggregator((event) => WebInspector.TimelineUIUtils.eventStyle(event).category.name) | ||
}, _WI_global); | ||
return this; | ||
@@ -61,41 +24,15 @@ } | ||
timelineModel() { | ||
return this._timelineModel; | ||
return this.sandbox.timelineModel(); | ||
} | ||
tracingModel() { | ||
return this._tracingModel; | ||
return this.sandbox.tracingModel(); | ||
} | ||
topDown() { | ||
var instance = this; | ||
var topDown; | ||
callWithGlobals(_ => { | ||
var filters = []; | ||
filters.push(WebInspector.TimelineUIUtils.visibleEventsFilter()); | ||
filters.push(new WebInspector.ExcludeTopLevelFilter()); | ||
var nonessentialEvents = [ | ||
WebInspector.TimelineModel.RecordType.EventDispatch, | ||
WebInspector.TimelineModel.RecordType.FunctionCall, | ||
WebInspector.TimelineModel.RecordType.TimerFire | ||
]; | ||
filters.push(new WebInspector.ExclusiveNameFilter(nonessentialEvents)); | ||
topDown = WebInspector.TimelineProfileTree.buildTopDown(instance._timelineModel.mainThreadEvents(), | ||
filters, /* startTime */ 0, /* endTime */ Infinity, WebInspector.TimelineAggregator.eventId) | ||
}, _WI_global); | ||
return topDown; | ||
return this.sandbox.topDown(); | ||
} | ||
bottomUp() { | ||
var instance = this; | ||
var bottomUp; | ||
callWithGlobals(_ => { | ||
var topDown = instance.topDown(); | ||
var noGrouping = WebInspector.TimelineAggregator.GroupBy.None | ||
var noGroupAggregator = instance._aggregator.groupFunction(noGrouping) | ||
bottomUp = WebInspector.TimelineProfileTree.buildBottomUp(topDown, noGroupAggregator) | ||
}, _WI_global); | ||
return bottomUp; | ||
return this.sandbox.bottomUp(); | ||
} | ||
@@ -105,45 +42,19 @@ | ||
bottomUpGroupBy(grouping) { | ||
var instance = this; | ||
var bottomUpGrouped; | ||
callWithGlobals(_ => { | ||
var topDown = instance.topDown(); | ||
var groupSetting = WebInspector.TimelineAggregator.GroupBy[grouping] // one of: None Category Subdomain Domain URL | ||
var groupURLAggregator = instance._aggregator.groupFunction(groupSetting) | ||
bottomUpGrouped = WebInspector.TimelineProfileTree.buildBottomUp(topDown, groupURLAggregator) | ||
// sort the grouped tree, in-place | ||
new TimelineModelTreeView(bottomUpGrouped).sortingChanged('self', 'desc') | ||
}, _WI_global); | ||
return bottomUpGrouped | ||
return this.sandbox.bottomUpGroupBy(grouping); | ||
} | ||
frameModel() { | ||
var instance = this; | ||
var frameModel; | ||
callWithGlobals(_ => { | ||
frameModel = new WebInspector.TracingTimelineFrameModel() | ||
frameModel.addTraceEvents({ /* target */ }, instance._timelineModel.inspectedTargetEvents(), instance._timelineModel.sessionId() || '') | ||
}, _WI_global); | ||
return frameModel | ||
return this.sandbox.frameModel(); | ||
} | ||
filmStripModel() { | ||
var instance = this; | ||
var fsModel; | ||
callWithGlobals(_ => { | ||
fsModel = new WebInspector.FilmStripModel(instance._tracingModel) | ||
}, _WI_global); | ||
return fsModel; | ||
return this.sandbox.filmStripModel(); | ||
} | ||
interactionModel() { | ||
var instance = this; | ||
var irModel; | ||
callWithGlobals(_ => { | ||
irModel = new WebInspector.TimelineIRModel() | ||
irModel.populate(instance._timelineModel) | ||
}, _WI_global); | ||
return irModel | ||
return this.sandbox.interactionModel(); | ||
} | ||
} | ||
module.exports = TraceToTimelineModel | ||
module.exports = ModelAPI |
@@ -5,11 +5,2 @@ /* global WebInspector Runtime WorkerRuntime Protocol */ | ||
// Required for a select portion DevTools frontend to work (in node) | ||
global.self = global | ||
global.window = global | ||
global.Runtime = {} | ||
global.TreeElement = {} | ||
global.WorkerRuntime = {} | ||
global.Protocol = {} | ||
WebInspector.targetManager = {} | ||
@@ -34,2 +25,1 @@ WebInspector.targetManager.observeTargets = noop | ||
// no exports as we're preparing the global scope |
{ | ||
"name": "devtools-timeline-model", | ||
"version": "1.0.15", | ||
"version": "1.0.16", | ||
"description": "Parse raw trace data into the Chrome DevTools' structured profiling data models", | ||
@@ -29,3 +29,2 @@ "license": "Apache-2.0", | ||
"dependencies": { | ||
"call-with-globals": "0.1.0", | ||
"chrome-devtools-frontend": "1.0.382117" | ||
@@ -32,0 +31,0 @@ }, |
@@ -52,8 +52,15 @@ # devtools-timeline-model [![Build Status](https://travis-ci.org/paulirish/devtools-timeline-model.svg?branch=master)](https://travis-ci.org/paulirish/devtools-timeline-model) | ||
## Dev | ||
```sh | ||
npm i | ||
brew install entr | ||
gls index.js lib/*.js | entr node example.js | ||
``` | ||
## License | ||
Apache © [Paul Irish](https://github.com/paulirish/) |
@@ -16,2 +16,21 @@ import test from 'ava' | ||
test("Array native globals dont leak", (t) => { | ||
t.is(Array.prototype.peekLast, undefined) | ||
}) | ||
test("WebInspector global doesn't leak", (t) => { | ||
t.is(typeof WebInspector, 'undefined') | ||
}) | ||
test("Multiple instances don't conflict", (t) => { | ||
var model1, model2; | ||
t.notThrows((_) => { | ||
model1 = new TraceToTimelineModel(events) | ||
model2 = new TraceToTimelineModel(events) | ||
}) | ||
var events1 = model1.timelineModel().mainThreadEvents().length; | ||
var events2 = model2.timelineModel().mainThreadEvents().length; | ||
t.is(events1, events2) | ||
}) | ||
test('metrics returned are expected', (t) => { | ||
@@ -18,0 +37,0 @@ t.is(model.timelineModel().mainThreadEvents().length, 7228) |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses eval() which is a dangerous function. This prevents the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
Debug access
Supply chain riskUses debug, reflection and dynamic code execution features.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
17746
1
348
66
7
2
- Removedcall-with-globals@0.1.0
- Removedcall-with-globals@0.1.0(transitive)