Author: jmorliaguet Date: Sat Jan 7 02:34:31 2006 New Revision: 2174 Modified: cpsskins/branches/jmo-perspectives/ui/framework/cpsskins.js cpsskins/branches/jmo-perspectives/ui/framework/tests/functional/cpsskins_model_view_test.html Log:
- added a base View class with - getData() - update() - render(data) - better decoupling between view and model: if a change occurs on the model, the model goes all the observers (views), calls view.update(), the views then get the data from the model with getData() and they are rendered with view.render(data). cf. http://msdn.microsoft.com/library/en-us/dnpatterns/html/des_MVC_Fig04.gif Modified: cpsskins/branches/jmo-perspectives/ui/framework/cpsskins.js ============================================================================== --- cpsskins/branches/jmo-perspectives/ui/framework/cpsskins.js (original) +++ cpsskins/branches/jmo-perspectives/ui/framework/cpsskins.js Sat Jan 7 02:34:31 2006 @@ -66,13 +66,13 @@ /* Controller */ - getController: function(view) { - var controller = view.getAttribute("controller"); + getController: function(tag) { + var controller = tag.getAttribute("controller"); return this.Controllers[controller]; }, - notify: function(view, object, action, param) { - var controller = this.getController(view); + notify: function(tag, object, action, param) { + var controller = this.getController(tag); if (!controller) return; var handler = controller.handlers[action]; if (handler) { @@ -284,10 +284,12 @@ } node.parentNode.insertBefore(comment, node); + // Update the views and controllers that are registered as observers + // TODO: use notify() instead var observers = CPSSkins.Observers[node]; if (observers) { - observers.each(function(v) { - v.render(data); + observers.each(function(o) { + o.update(); }); } @@ -416,34 +418,63 @@ } +// View + +CPSSkins.View = function() {}; +CPSSkins.View.prototype = { + + initialize: function(widget, tag) { + this.widget = widget; + this.tag = tag; + }, + + getData: function() { + var observed = this.tag.getAttribute("observe"); + if (observed) { + return Canvas.getNodeData(observed); + } + return null; + }, + + update: function() { + var data = this.getData(); + this.render(data); + }, + + render: function(data) { + /* to override */ + } + +} + // Renderer: instanciate a widget. if (!window.Widgets) { var Widgets = new Object(); } Object.extend(Widgets, { - contextmenu: function(view) { + contextmenu: function(tag) { var widget = Canvas.createNode({ tag: "div", classes: "contextMenu", style: {position:"absolute", display:"none"} }); - return new CPSSkins.ContextualMenu(widget, view); + return new CPSSkins.ContextualMenu(widget, tag); }, - tooltip: function(view) { + tooltip: function(tag) { var widget = Canvas.createNode({ tag: "div", classes: "tooltip", style: {position:"absolute", display:"none"} }); - return new CPSSkins.Tooltip(widget, view); + return new CPSSkins.Tooltip(widget, tag); }, - panel: function(view) { + panel: function(tag) { var widget = Canvas.createNode({ tag: "div", style: {display: "none"}, }); - return new CPSSkins.Panel(widget, view); + return new CPSSkins.Panel(widget, tag); } }); @@ -453,12 +484,12 @@ CPSSkins.Panel = Class.create(); CPSSkins.Panel.prototype = { - initialize: function(widget, view) { + initialize: function(widget, tag) { this.widget = widget; - this.view = view; + this.tag = tag; this.visible = false; - this.fadein = this.view.getAttribute("fadein") || false; - this.url = this.view.getAttribute("url"); + this.fadein = this.tag.getAttribute("fadein") || false; + this.url = this.tag.getAttribute("url"); this.css_id = null; this.script_id = null; this.render(); @@ -469,7 +500,7 @@ }, render: function() { - var script = this.view.getAttribute("script"); + var script = this.tag.getAttribute("script"); if (script) { this.script_id = this.id; Canvas.addScript(this.script_id, script); @@ -495,7 +526,7 @@ show: function() { if (this.visible) return; - var css = this.view.getAttribute("css"); + var css = this.tag.getAttribute("css"); if (css) { this.css_id = "cpsskins-panel-css" + this.id; Canvas.addStyleSheet(this.css_id, css); @@ -530,10 +561,10 @@ CPSSkins.ContextualMenu = Class.create(); CPSSkins.ContextualMenu.prototype = { - initialize: function(widget, view) { + initialize: function(widget, tag) { this.widget = widget; - this.view = view; - this.area = view.parentNode || document; + this.tag = tag; + this.area = tag.parentNode || document; this.active = false; @@ -588,7 +619,7 @@ if (!window.confirm(confirm)) return; } /* notify the controller */ - CPSSkins.notify(this.view, this.selected, action, choice); + CPSSkins.notify(this.tag, this.selected, action, choice); this.active = false; }, @@ -623,7 +654,7 @@ var selected = this.selected; if (!selected) return; var widget = this.widget; - var view = this.view; + var tag = this.tag; // Display the menu inside the screen Canvas.moveTo(widget, x, y); Canvas.fitInsideScreen(widget); @@ -633,7 +664,7 @@ v.parentNode.removeChild(v); }); - this._renderFragment(widget, view); + this._renderFragment(widget, tag); new CPSSkins.Scheduler(widget, { action: function(value) { @@ -770,12 +801,12 @@ CPSSkins.Tooltip = Class.create(); CPSSkins.Tooltip.prototype = { - initialize: function(widget, view) { + initialize: function(widget, tag) { this.widget = widget; - this.area = view.parentNode; + this.area = tag.parentNode; this.options = { - showdelay: view.getAttribute("showdelay") || 1000, - hidedelay: view.getAttribute("hidedelay") || 100 + showdelay: tag.getAttribute("showdelay") || 1000, + hidedelay: tag.getAttribute("hidedelay") || 100 } this.hint = null; this.effect = null; Modified: cpsskins/branches/jmo-perspectives/ui/framework/tests/functional/cpsskins_model_view_test.html ============================================================================== --- cpsskins/branches/jmo-perspectives/ui/framework/tests/functional/cpsskins_model_view_test.html (original) +++ cpsskins/branches/jmo-perspectives/ui/framework/tests/functional/cpsskins_model_view_test.html Sat Jan 7 02:34:31 2006 @@ -29,13 +29,18 @@ </style> <script type="text/javascript"> - Event.observe(window, "load", start); - var timer; + var timer = null; function start() { + if (timer) return; timer = setInterval("updateModel()", 100); } + function stop() { + clearInterval(timer); + timer = null; + } + function updateModel() { var data = Canvas.getNodeData("data-provider"); data.size += 1; @@ -43,47 +48,42 @@ } Object.extend(Widgets, { - counter: function(view) { + + counter: function(viewtag) { var widget = Canvas.createNode({ tag: "div", classes: "counter" }); - return new Counter(widget, view); + return new Counter(widget, viewtag); }, - progressbar: function(view) { + + progressbar: function(viewtag) { var widget = Canvas.createNode({ tag: "div", classes: "progressBar" }); - return new ProgressBar(widget, view); + return new ProgressBar(widget, viewtag); } - }); - Counter= Class.create(); - Counter.prototype = { + }); - initialize: function(widget, view) { - this.widget = widget; - }, + Counter = Class.create(); + Counter.prototype = Object.extend(new CPSSkins.View(), { render: function(data) { this.widget.innerHTML = data.size; } - } - - ProgressBar= Class.create(); - ProgressBar.prototype = { + }); - initialize: function(widget, view) { - this.widget = widget; - }, + ProgressBar = Class.create(); + ProgressBar.prototype = Object.extend(new CPSSkins.View(), { render: function(data) { this.widget.style.width = data.size % 50 * 10 +"px"; } - } + }); </script> @@ -98,12 +98,15 @@ <!-- model: {"size": 1} --> <div id="data-provider"></div> - <h2>View 1 (progress bar widget)</h2> + <h2>progress bar widget</h2> <cpsskins:view widget="progressbar" observe="data-provider"></cpsskins:view> - <h2>View 2 (counter widget)</h2> + <h2>counter widget</h2> <cpsskins:view widget="counter" observe="data-provider"></cpsskins:view> + <button onclick="start()">START</button> + <button onclick="stop()">STOP</button> + </body> </html> -- http://lists.nuxeo.com/mailman/listinfo/z3lab-checkins