1<!DOCTYPE html>
2<!--
3Copyright (c) 2013 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<link rel="import" href="/tracing/base/base.html">
8<script>
9'use strict';
10
11tr.exportTo('tr.model', function() {
12  function StackFrame(parentFrame, id, title, colorId, opt_sourceInfo) {
13    if (id === undefined)
14      throw new Error('id must be given');
15    this.parentFrame_ = parentFrame;
16    this.id = id;
17    this.title_ = title;
18    this.colorId = colorId;
19    this.children = [];
20    this.sourceInfo_ = opt_sourceInfo;
21
22    if (this.parentFrame_)
23      this.parentFrame_.addChild(this);
24  }
25
26  StackFrame.prototype = {
27    get parentFrame() {
28      return this.parentFrame_;
29    },
30
31    get title() {
32      if (this.sourceInfo_) {
33        var src = this.sourceInfo_.toString();
34        return this.title_ + (src === '' ? '' : ' ' + src);
35      }
36      return this.title_;
37    },
38
39    /**
40     * Attempts to find the domain of the origin of the script either from this
41     * stack trace or from its ancestors.
42     */
43    get domain() {
44      var result = 'unknown';
45      if (this.sourceInfo_ && this.sourceInfo_.domain)
46        result = this.sourceInfo_.domain;
47      if (result === 'unknown' && this.parentFrame)
48        result = this.parentFrame.domain;
49      return result;
50    },
51
52    get sourceInfo() {
53      return this.sourceInfo_;
54    },
55
56    set parentFrame(parentFrame) {
57      if (this.parentFrame_)
58        this.parentFrame_.removeChild(this);
59      this.parentFrame_ = parentFrame;
60      if (this.parentFrame_)
61        this.parentFrame_.addChild(this);
62    },
63
64    addChild: function(child) {
65      this.children.push(child);
66    },
67
68    removeChild: function(child) {
69      var i = this.children.indexOf(child.id);
70      if (i == -1)
71        throw new Error('omg');
72      this.children.splice(i, 1);
73    },
74
75    removeAllChildren: function() {
76      for (var i = 0; i < this.children.length; i++)
77        this.children[i].parentFrame_ = undefined;
78      this.children.splice(0, this.children.length);
79    },
80
81    /**
82     * Returns stackFrames where the most specific frame is first.
83     */
84    get stackTrace() {
85      var stack = [];
86      var cur = this;
87      while (cur) {
88        stack.push(cur);
89        cur = cur.parentFrame;
90      }
91      return stack;
92    },
93
94    getUserFriendlyStackTrace: function() {
95      return this.stackTrace.map(function(x) { return x.title; });
96    }
97  };
98
99  return {
100    StackFrame: StackFrame
101  };
102});
103</script>
104