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