Add Flora license
[platform/framework/web/web-ui-fw.git] / src / js / jquery.mobile.tizen.loadprototype.js
1 //>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
2 //>>description: Loads widget's prototype
3 //>>label: Widget prototype loader
4 //>>group: Tizen:Core
5
6 define( [ ], function ( ) {
7 //>>excludeEnd("jqmBuildExclude");
8
9 (function($, undefined) {
10
11 ensureNS("jQuery.mobile.tizen");
12
13 jQuery.extend( jQuery.mobile.tizen,
14 {
15     _widgetPrototypes: {},
16
17     /*
18      * load the prototype for a widget.
19      *
20      * If @widget is a string, the function looks for @widget.prototype.html in the proto-html/ subdirectory of the
21      * framework's current theme and loads the file via AJAX into a string. Note that the file will only be loaded via
22      * AJAX once. If two widget instances based on the same @widget value are to be constructed, the second will be
23      * constructed from the cached copy of the prototype of the first instance.
24      *
25      * If @widget is not a string, it is assumed to be a hash containing at least one key, "proto", the value of which is
26      * the string to be used for the widget prototype. if another key named "key" is also provided, it will serve as the
27      * key under which to cache the prototype, so it need not be rendered again in the future.
28      *
29      * Given the string for the widget prototype, the following patterns occurring in the string are replaced:
30      *
31      *   "${FRAMEWORK_ROOT}" - replaced with the path to the root of the framework
32      *
33      * The function then creates a jQuery $("<div>") object containing the prototype from the string.
34      *
35      * If @ui is not provided, the jQuery object containing the prototype is returned.
36      *
37      * If @ui is provided, it is assumed to be a (possibly multi-level) hash containing CSS selectors. For every level of
38      * the hash and for each string-valued key at that level, the CSS selector specified as the value is sought in the
39      * prototype jQuery object and, if found, the value of the key is replaced with the jQuery object resulting from the
40      * search. Additionally, if the CSS selector is of the form "#widgetid", the "id" attribute will be removed from the
41      * elements contained within the resulting jQuery object. The resulting hash is returned.
42      *
43      * Examples:
44      *
45      * 1.
46      * $.mobile.tizen.loadPrototype("mywidget") => Returns a <div> containing the structure from the file
47      * mywidget.prototype.html located in the current theme folder of the current framework.
48      *
49      * 2. $.mobile.tizen.loadPrototype("mywidget", ui):
50      * where ui is a hash that looks like this:
51      * ui = {
52      *   element1: "<css selector 1>",
53      *   element2: "<css selector 2>",
54      *   group1: {
55      *     group1element1: "<css selector 3>",
56      *     group1element1: "<css selector 4>"
57      *   }
58      *  ...
59      * }
60      *
61      * In this case, after loading the prototype as in Example 1, loadPrototype will traverse @ui and replace the CSS
62      * selector strings with the result of the search for the selector string upon the prototype. If any of the CSS
63      * selectors are of the form "#elementid" then the "id" attribute will be stripped from the elements selected. This
64      * means that they will no longer be accessible via the selector used initially. @ui is then returned thus modified.
65      */
66
67     loadPrototype: function(widget, ui) {
68         var ret = undefined,
69             theScriptTag = $("script[data-framework-version][data-framework-root][data-framework-theme]"),
70             frameworkRootPath = theScriptTag.attr("data-framework-root")    + "/" +
71                                 theScriptTag.attr("data-framework-version") + "/";
72
73         function replaceVariables(s) {
74             return s.replace(/\$\{FRAMEWORK_ROOT\}/g, frameworkRootPath);
75         }
76
77         function fillObj(obj, uiProto) {
78             var selector;
79
80             for (var key in obj) {
81                 if (typeof obj[key] === "string") {
82                     selector = obj[key];
83                     obj[key] = uiProto.find(obj[key]);
84                     if (selector.substring(0, 1) === "#")
85                         obj[key].removeAttr("id");
86                 }
87                 else
88                 if (typeof obj[key] === "object")
89                     obj[key] = fillObj(obj[key], uiProto);
90             }
91             return obj;
92         }
93
94         /* If @widget is a string ... */
95         if (typeof widget === "string") {
96             /* ... try to use it as a key into the cached prototype hash ... */
97             ret = $.mobile.tizen._widgetPrototypes[widget];
98             if (ret === undefined) {
99                 /* ... and if the proto was not found, try to load its definition ... */
100                 var protoPath = frameworkRootPath + "proto-html" + "/" +
101                                 theScriptTag.attr("data-framework-theme");
102                 $.ajax({
103                     url: protoPath + "/" + widget + ".prototype.html",
104                     async: false,
105                     dataType: "html"
106                 })
107                  .success(function(data, textStatus, jqXHR) {
108                     /* ... and if loading succeeds, cache it and use a copy of it ... */
109                     $.mobile.tizen._widgetPrototypes[widget] = $("<div>").html(replaceVariables(data));
110                     ret = $.mobile.tizen._widgetPrototypes[widget].clone();
111                 });
112             }
113         }
114         /* Otherwise ... */
115         else {
116             /* ... if a key was provided ... */
117             if (widget.key !== undefined)
118                 /* ... try to use it as a key into the cached prototype hash ... */
119                 ret = $.mobile.tizen._widgetPrototypes[widget.key];
120
121             /* ... and if the proto was not found in the cache ... */
122             if (ret === undefined) {
123                 /* ... and a proto definition string was provided ... */
124                 if (widget.proto !== undefined) {
125                     /* ... create a new proto from the definition ... */
126                     ret = $("<div>").html(replaceVariables(widget.proto));
127                     /* ... and if a key was provided ... */
128                     if (widget.key !== undefined)
129                         /* ... cache a copy of the proto under that key */
130                         $.mobile.tizen._widgetPrototypes[widget.key] = ret.clone();
131                 }
132             }
133             else
134                 /* otherwise, if the proto /was/ found in the cache, return a copy of it */
135                 ret = ret.clone();
136         }
137
138         /* If the prototype was found/created successfully ... */
139         if (ret != undefined)
140             /* ... and @ui was provided */
141             if (ui != undefined)
142                 /* ... return @ui, but replace the CSS selectors it contains with the elements they select */
143                 ret = fillObj(ui, ret);
144
145         return ret;
146     }
147 });
148 })(jQuery);
149
150 //>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
151 } );
152 //>>excludeEnd("jqmBuildExclude");