Upstream version 11.39.266.0
[platform/framework/web/crosswalk.git] / src / third_party / trace-viewer / third_party / tvcm / src / tvcm / ui.html
1 <!DOCTYPE html>
2 <!--
3 Copyright (c) 2014 The Chromium Authors. All rights reserved.
4 Use of this source code is governed by a BSD-style license that can be
5 found in the LICENSE file.
6 -->
7 <link rel="import" href="/tvcm.html">
8 <script>
9 'use strict';
10
11 tvcm.exportTo('tvcm.ui', function() {
12
13   /**
14    * Decorates elements as an instance of a class.
15    * @param {string|!Element} source The way to find the element(s) to decorate.
16    *     If this is a string then {@code querySeletorAll} is used to find the
17    *     elements to decorate.
18    * @param {!Function} constr The constructor to decorate with. The constr
19    *     needs to have a {@code decorate} function.
20    */
21   function decorate(source, constr) {
22     var elements;
23     if (typeof source == 'string')
24       elements = tvcm.doc.querySelectorAll(source);
25     else
26       elements = [source];
27
28     for (var i = 0, el; el = elements[i]; i++) {
29       if (!(el instanceof constr))
30         constr.decorate(el);
31     }
32   }
33
34   /**
35    * Defines a tracing UI component, a function that can be called to construct
36    * the component.
37    *
38    * Tvcm class:
39    * <pre>
40    * var List = tvcm.ui.define('list');
41    * List.prototype = {
42    *   __proto__: HTMLUListElement.prototype,
43    *   decorate: function() {
44    *     ...
45    *   },
46    *   ...
47    * };
48    * </pre>
49    *
50    * Derived class:
51    * <pre>
52    * var CustomList = tvcm.ui.define('custom-list', List);
53    * CustomList.prototype = {
54    *   __proto__: List.prototype,
55    *   decorate: function() {
56    *     ...
57    *   },
58    *   ...
59    * };
60    * </pre>
61    *
62    * @param {string} className The className of the newly created subtype. If
63    *     subclassing by passing in opt_parentConstructor, this is used for
64    *     debugging. If not subclassing, then it is the tag name that will be
65    *     created by the component.
66
67    * @param {function=} opt_parentConstructor The parent class for this new
68    *     element, if subclassing is desired. If provided, the parent class must
69    *     be also a function created by tvcm.ui.define.
70    *
71    * @param {string=} opt_tagNS The namespace in which to create the base
72    *     element. Has no meaning when opt_parentConstructor is passed and must
73    *     either be undefined or the same namespace as the parent class.
74    *
75    * @return {function(Object=):Element} The newly created component
76    *     constructor.
77    */
78   function define(className, opt_parentConstructor, opt_tagNS) {
79     if (typeof className == 'function') {
80       throw new Error('Passing functions as className is deprecated. Please ' +
81                       'use (className, opt_parentConstructor) to subclass');
82     }
83
84     var className = className.toLowerCase();
85     if (opt_parentConstructor && !opt_parentConstructor.tagName)
86       throw new Error('opt_parentConstructor was not ' +
87                       'created by tvcm.ui.define');
88
89     // Walk up the parent constructors until we can find the type of tag
90     // to create.
91     var tagName = className;
92     var tagNS = undefined;
93     if (opt_parentConstructor) {
94       if (opt_tagNS)
95         throw new Error('Must not specify tagNS if parentConstructor is given');
96       var parent = opt_parentConstructor;
97       while (parent && parent.tagName) {
98         tagName = parent.tagName;
99         tagNS = parent.tagNS;
100         parent = parent.parentConstructor;
101       }
102     } else {
103       tagNS = opt_tagNS;
104     }
105
106     /**
107      * Creates a new UI element constructor.
108      * Arguments passed to the constuctor are provided to the decorate method.
109      * You will need to call the parent elements decorate method from within
110      * your decorate method and pass any required parameters.
111      * @constructor
112      */
113     function f() {
114       if (opt_parentConstructor &&
115           f.prototype.__proto__ != opt_parentConstructor.prototype) {
116         throw new Error(
117             className + ' prototye\'s __proto__ field is messed up. ' +
118             'It MUST be the prototype of ' + opt_parentConstructor.tagName);
119       }
120
121       var el;
122       if (tagNS === undefined)
123         el = tvcm.doc.createElement(tagName);
124       else
125         el = tvcm.doc.createElementNS(tagNS, tagName);
126       f.decorate.call(this, el, arguments);
127       return el;
128     }
129
130     /**
131      * Decorates an element as a UI element class.
132      * @param {!Element} el The element to decorate.
133      */
134     f.decorate = function(el) {
135       el.__proto__ = f.prototype;
136       el.decorate.apply(el, arguments[1]);
137       el.constructor = f;
138     };
139
140     f.className = className;
141     f.tagName = tagName;
142     f.tagNS = tagNS;
143     f.parentConstructor = (opt_parentConstructor ? opt_parentConstructor :
144                                                    undefined);
145     f.toString = function() {
146       if (!f.parentConstructor)
147         return f.tagName;
148       return f.parentConstructor.toString() + '::' + f.className;
149     };
150
151     return f;
152   }
153
154   function elementIsChildOf(el, potentialParent) {
155     if (el == potentialParent)
156       return false;
157
158     var cur = el;
159     while (cur.parentNode) {
160       if (cur == potentialParent)
161         return true;
162       cur = cur.parentNode;
163     }
164     return false;
165   };
166
167   return {
168     decorate: decorate,
169     define: define,
170     elementIsChildOf: elementIsChildOf
171   };
172 });
173 </script>