moksha/api/widgets/containers/dashboardcontainer.py | 7 moksha/api/widgets/containers/templates/layout_applist.mak | 19 - moksha/api/widgets/grid.py | 11 moksha/api/widgets/moksha.py | 21 + moksha/lib/base.py | 12 - moksha/lib/helpers.py | 27 +- moksha/public/javascript/moksha.js | 85 +++++++ moksha/public/javascript/ui/moksha.ui.grid.js | 148 ++++++------- moksha/public/javascript/ui/moksha.ui.tabs.js | 10 setup.py | 11 10 files changed, 221 insertions(+), 130 deletions(-)
New commits: commit fd6e566f9a8362ec4e7a61ac954ee1daab1841b3 Author: John (J5) Palmieri johnp@redhat.com Date: Wed Feb 18 18:09:11 2009 -0500
fix up script filtering and use uuid's for the grid
diff --git a/moksha/api/widgets/containers/dashboardcontainer.py b/moksha/api/widgets/containers/dashboardcontainer.py index bb1335b..6b34e2a 100644 --- a/moksha/api/widgets/containers/dashboardcontainer.py +++ b/moksha/api/widgets/containers/dashboardcontainer.py @@ -1,3 +1,8 @@ +from moksha.api.widgets.layout.layout import layout_js, layout_css, ui_core_js, ui_draggable_js, ui_droppable_js, ui_sortable_js + +from tw.api import Widget +from twfrom.jquery import jquery_js +from moksha.lib.helpers import eval_app_config, ConfigWrapper from tg import config from tw.api import Widget
@@ -22,6 +27,8 @@ applist_widget = AppListWidget('applist');
class DashboardContainer(Widget): template = 'mako:moksha.api.widgets.containers.templates.dashboardcontainer' + css = [] + javascript = [jquery_js] config_key = None layout = []
diff --git a/moksha/api/widgets/containers/templates/layout_applist.mak b/moksha/api/widgets/containers/templates/layout_applist.mak index d9d8a24..bf267c4 100644 --- a/moksha/api/widgets/containers/templates/layout_applist.mak +++ b/moksha/api/widgets/containers/templates/layout_applist.mak @@ -5,21 +5,6 @@ <dt>${app['label']}</dt> % endif
- <script type="text/javascript"> - function moksha_strip_and_display(r, panel) { - var $temp = $(r); - var $scripts = $temp.find("script[src]"); - $scripts.remove(); - - var $stripped = []; - $.each($temp, function(i, s) { - if (!$(s).is('script[src]')){ - $stripped.push(s); - } - }); - panel.html($stripped); - } - </script> <dd id="${app['id']}"> % if app.has_key('widget'): ${app['widget'](**app['params'])} @@ -33,7 +18,9 @@ url: "${app['url']}", success: function(r, s) { var $panel = $("#${app['id']}"); - moksha_strip_and_display(r, $panel); + var $stripped = moksha.filter_resources(r); + $panel.html($stripped); + }, data: ${app['params']} }; diff --git a/moksha/api/widgets/grid.py b/moksha/api/widgets/grid.py index 7469c3a..cec51aa 100644 --- a/moksha/api/widgets/grid.py +++ b/moksha/api/widgets/grid.py @@ -3,6 +3,8 @@ from tw.forms import FormField from tw.jquery.ui_core import jquery_ui_core_js from tw.jquery import jQuery, jquery_js import simplejson as json +import uuid +
jquery_json_js = JSLink(filename='public/javascript/jquery.json.js', modname='moksha', javascript=[jquery_js]) @@ -19,7 +21,7 @@ class Grid(FormField): params= ['rows_per_page', 'page_num', 'total_rows', 'filters', 'unique_key', 'sort_key', 'sort_order', 'row_template', 'resource', 'resource_path', - 'loading_throbber'] + 'loading_throbber', 'uid']
rows_per_page = 10 page_num = 1 @@ -47,7 +49,6 @@ class Grid(FormField):
grid_d[p] = v
- id = d['id'] - if d.get('uid'): - id += d.uid - self.add_call(jQuery("#%s" % id).mokshagrid(grid_d)) + d['id'] += "-uuid" + str(uuid.uuid4()) + + self.add_call(jQuery("#%s" % d['id']).mokshagrid(grid_d)) diff --git a/moksha/api/widgets/moksha.py b/moksha/api/widgets/moksha.py new file mode 100644 index 0000000..baff13e --- /dev/null +++ b/moksha/api/widgets/moksha.py @@ -0,0 +1,21 @@ +# This file is part of Moksha. +# +# Moksha is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Moksha is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Moksha. If not, see http://www.gnu.org/licenses/. +# +# Copyright 2008, Red Hat, Inc. +# Authors: John (J5) Palmieri johnp@redhat.com +from tw.jquery import jquery_js +from tw.api import JSLink +moksha_js = JSLink(modname="moksha", filename='public/javascript/moksha.js', + javascript=[jquery_js]) diff --git a/moksha/lib/base.py b/moksha/lib/base.py index 7d77a1b..16cd23e 100644 --- a/moksha/lib/base.py +++ b/moksha/lib/base.py @@ -43,19 +43,13 @@ class BaseController(TGController): # url is already taken tmpl_context.get_url = url
- ## Inject our global resources - if request.path.startswith('/appz') or \ - request.path.startswith('/widgets') or \ - request.path.startswith('/docs'): - # Don't inject global resources for apps or widgets. - tmpl_context.moksha_global_resources = lambda: '' - else: + # Add our global widget to the template context, and register it's resources - tmpl_context.moksha_global_resources = global_resources + tmpl_context.moksha_global_resources = global_resources
# This is normally done when the widget is rendered, but we cannot assume that # moksha apps are going to be using our master index template, which renders # this widget for us. - global_resources.register_resources() + global_resources.register_resources()
return TGController.__call__(self, environ, start_response) diff --git a/moksha/lib/helpers.py b/moksha/lib/helpers.py index 6fa9426..96093c0 100644 --- a/moksha/lib/helpers.py +++ b/moksha/lib/helpers.py @@ -1,5 +1,15 @@ -import moksha -import pylons +from webhelpers import date, feedgenerator, html, number, misc, text + +from repoze.what.predicates import (Not, Predicate, All, Any, has_all_permissions, + has_any_permission, has_permission, + in_all_groups, in_any_group, in_group, + is_user, not_anonymous) + +from repoze.what.authorize import check_authorization, NotAuthorizedError + +from webob import Request + +import urllib import uuid import simplejson as json import re @@ -8,14 +18,7 @@ import logging
from webob import Request from decorator import decorator -from webhelpers import date, feedgenerator, html, number, misc, text -from repoze.what.authorize import check_authorization, NotAuthorizedError -from repoze.what.predicates import (Not, Predicate, All, Any, - has_all_permissions, has_any_permission, - has_permission, in_all_groups, in_any_group, - in_group, is_user, not_anonymous) - -from moksha.exc import MokshaConfigNotFound +import moksha
log = logging.getLogger(__name__) scrub_filter = re.compile('[^_a-zA-Z0-9-]') @@ -408,12 +411,14 @@ def check_predicates(predicates): :return: False is any one is False :return: True if they are all True """ + from pylons import request + if(not(isinstance(predicates, list) or isinstance(predicates, tuple))): predicates = (predicates,)
for p in predicates: try: - check_authorization(p, pylons.request.environ) + check_authorization(p, request.environ) except NotAuthorizedError, e: return False
diff --git a/moksha/public/javascript/moksha.js b/moksha/public/javascript/moksha.js index 9c5641f..d4a977b 100644 --- a/moksha/public/javascript/moksha.js +++ b/moksha/public/javascript/moksha.js @@ -1,7 +1,7 @@ /* * Moksha javascript library * - * Copyright (c) 2008 Red Hat, Inc. + * Copyright (c) 2008 Red Hat, Inc. * * GPLv2+ license. * @@ -9,4 +9,85 @@ * jquery.js */
-/* nothing for now */ +(function(){ + +// prevent double loading +if (!(typeof(moksha) === 'undefined')) + return; + +var _moksha_page_scripts_cache = {}; + +var _moksha_init = false; +// preload cache + +$(document).ready(function(){ + _moksha_init = true; + var $s = $('script[src]'); + + $.each($s, function(i, a) { + var $a = $(a); + var src = $a.attr('src'); + // for right now just compare exact source values + // later we will want to be a bit smarter + if(!_moksha_page_scripts_cache[src]) { + _moksha_page_scripts_cache[src] = true; + } + } + ); + +}); + +moksha = { + /****************************************************************** + * Filter the script tags in a fragment of HTML or jQuery DOM + * so that they aren't double loaded. You should send in HTML + * if possible because placing script tags in a jQuery DOM can + * cause them to load if not done correctly + ******************************************************************/ + filter_scripts: function(fragment) { + // don't append to a tag, doing so will cause scripts to load + if (!fragment.jquery) + fragment = $(fragment); + + var $stripped = []; + $.each(fragment, function(i, s) { + var $s = $(s) + if ($s.is('script[src]')){ + var src = $s.attr('src'); + //strip query string + src = src.split('?')[0]; + + if(!_moksha_page_scripts_cache[src]) { + // we can add more attributes later + // right now just set to true + _moksha_page_scripts_cache[src] = true; + $stripped.push(s); + } + } else { + $stripped.push(s); + } + }); + + return $stripped; + }, + + /****************************************************************** + * Filter resources in a fragment of HTML or jQuery DOM + * so that they aren't double loaded. Right now this is only + * scripts but could be expanded to css and other loaded + * resource types. You should send in HTML + * if possible since loading into a jQuery DOM can cause them + * to load if not done correctly + ******************************************************************/ + filter_resources: function(fragment) { + if (!fragment.jquery) + fragment = $(fragment); + + var $div = $('<div />'); + var $f = moksha.filter_scripts(fragment); + + return $f; + } +} + +})(); \ No newline at end of file diff --git a/moksha/public/javascript/ui/moksha.ui.grid.js b/moksha/public/javascript/ui/moksha.ui.grid.js index 4f64b74..f6b60eb 100644 --- a/moksha/public/javascript/ui/moksha.ui.grid.js +++ b/moksha/public/javascript/ui/moksha.ui.grid.js @@ -1,107 +1,107 @@ (function($) { - $.widget("ui.mokshagrid",{ + $.widget("ui.mokshagrid",{ /* methods */ - + init: function() { var self = this; var o = self.options; - + self.$visible_rows = [];
// add placeholder for row appends self.$rowplaceholder = jQuery('<span />').addClass('moksha_rowplaceholder'); self.$rowplaceholder.hide(); - - - if (!self.element.is('table')) { + + + if (!self.element.is('table')) { var t = self._generate_table(); - + self.element.append(t); } else { self._setup_template(); - } + } }, - + destroy: function() { this.$headers.unbind('.mokshagrid'); this.element.unbind('.mokshagrid'); }, - + clear: function() { var self = this; var rows = self.$visible_rows; for (i in rows) rows[i].replaceWith(''); - + self.$visible_rows = []; }, - + insert_row: function(i, row_data) { var self = this; var o = self.options var rows = self.$visible_rows; var row_count = self.visible_row_count(); - + // store the widget for this element jQuery.data(self.element, 'mokshagrid', self); - + // do nothing if we are asked to insert passed // the number of rows being displayed if (i >= o.rows_per_page || (i == -1 && row_count >= o.rows_per_page)) return; - + var new_row = jQuery(o.row_template.apply(row_data)); - + if (i == -1 || row_count == i) { // append to the end of the tracking array and the table dom rows.push(new_row); self.$rowplaceholder.before(new_row); } else { - + // insert before i element in the tracking array and table dom rows[i].before(new_row); rows.splice(i, 0, new_row); - + // if there is one too many rows remove the last one if (row_count == o.rows_per_page) self.remove_row(o.rows_per_page); } - + new_row.show(); }, - + append_row: function(row_data) { var self = this; self.insert_row(-1, row_data); }, - + remove_row: function(i) { var self = this; var rows = self.$visible_rows; rows[i].replaceWith(''); rows.splice(i,1); }, - + get_json: function(path, args, callback) { - //TODO: implement a json loading method + //TODO: implement a json loading method // which starts and stops a loading // throbber var self = this; - + self.element.find('tbody').fadeOut('slow'); var xmlrequest = jQuery.getJSON(path, args, function (json) { callback(json); self.element.find('tbody').fadeIn('slow'); - + }); - + }, - + connector_query_model: function(connector, path, callback) { path = '/moksha_connector/' + connector + '/query_model/' + path; this.get_json(path, {}, callback); }, - + connector_query: function(connector, path, dispatch_data, callback) { path = '/moksha_connector/' + connector + '/query/' + path; if (dispatch_data) @@ -109,16 +109,16 @@
this.get_json(path, {}, callback); }, - + request_data_refresh: function(event) { // TODO: allow an optional rows_requested parameter var self = this; var o = self.options; - + // figure out which row to start with var rpp = o.rows_per_page; var start_row = (o.page_num - 1) * rpp; - + // setup the search criteria var search_criteria = { filters: o.filters, @@ -127,61 +127,61 @@ sort_key: o.sort_key, sort_order: o.sort_order, } - + // TODO: Only trigger refresh signal if we have a cache miss self.refresh_data(event, search_criteria); }, - + refresh_data: function(event, search_criteria) { var self = this; var o = self.options; - + if (!o.resource || !o.resource_path) return; - + var results = function(json) { self.clear(); for (var i in json.rows) { - self.append_row(json.rows[i]); + self.append_row(json.rows[i]); } } - + var filters = search_criteria.filters - + var dispatch_data = {offset: search_criteria.start_row, num_rows: search_criteria.rows_requested, filters: filters } - - if (search_criteria.sort_key) { + + if (search_criteria.sort_key) { dispatch_data["sort_col"] = search_criteria.sort_key; dispatch_data["sort_order"] = search_criteria.sort_order; }
- self.connector_query( - o.resource, - o.resource_path, - dispatch_data, + self.connector_query( + o.resource, + o.resource_path, + dispatch_data, results); }, - + /* Signals */ ready: function(event, user_data) { - + }, - + /* Getter/Setters */ - + visible_row_count: function() { var self = this; return self.$visible_rows.length; }, - + /* Private */ _setup_template: function() { var self = this; var o = self.options; - + var rowtemplate = jQuery('.rowtemplate', self.element); rowtemplate.removeClass('rowtemplate') if (rowtemplate.length) @@ -191,16 +191,16 @@ // this also removes the template from the document var container_div = jQuery('<div />'); var html = unescape(container_div.append(rowtemplate).html()); - + o.row_template = jQuery.template(html, {regx:'moksha'}).compile(); - + self.$headers = $('th:has(a[href])', this.element); //self.$headers = this.$ths.map(function() { return $('a', this)[0]; }); self.$headers.unbind(o.event + '.mokshagrid').bind(o.event + '.mokshagrid', function(event) { var ckey = o.sort_key; var corder = o.sort_order; var key = event.originalTarget.hash.substr(1); - + if (key == ckey) { if (corder == -1) { corder = 1; @@ -210,18 +210,18 @@ } else { corder = 'decending'; } - + self.options['sort_key'] = key; self.options['sort_order'] = corder; - + self.request_data_refresh();
return false; }) - + self.request_data_refresh(); }, - + _generate_table: function() { var self = this; var t = $('<table />'); @@ -229,7 +229,7 @@ // get the model if there is a resource and path if (!o.resource || !o.resource_path) return t; - + var results = function(json) { o.sort_key = json.default_sort_col; o.sort_order = json.default_sort_order; @@ -238,17 +238,17 @@ var header_tr = $('<tr />'); headers.append(header_tr); t.append(headers); - + var template = $('<tbody />').addClass("rowtemplate"); var template_tr = $('<tr />'); template.append(template_tr); t.append(template); - + for (var c in json.columns) { var c_data = json.columns[c]; if (!c_data.default_visible) continue; - + if (c_data.can_sort) { var a = $('<a />').attr('href', '#' + c).text(c); var th = $('<th />').append(a); @@ -257,22 +257,22 @@ var td = $('<th />').text(c); header_tr.append(td); } - + template_tr.append('<td>@{' + c + '}</td>'); } - + self._setup_template(); }
- self.connector_query_model( - o.resource, - o.resource_path, + self.connector_query_model( + o.resource, + o.resource_path, results); - + return t; } }) - + $.extend($.ui.mokshagrid, { version: '@VERSION', getters: 'visible_row_count', @@ -289,16 +289,16 @@ resource: null, resource_path: null, loading_throbber: ["Loading", // list of img urls or text - "Loading.", - "Loading..", - "Loading..."] + "Loading.", + "Loading..", + "Loading..."] } }); - + $.extend( $.template.regx , { moksha:/@{([\w-]+)(?::([\w.]*)(?:((.*?)?))?)?}/g } ); - - + + })(jQuery); \ No newline at end of file diff --git a/moksha/public/javascript/ui/moksha.ui.tabs.js b/moksha/public/javascript/ui/moksha.ui.tabs.js index 406a2ac..b216610 100644 --- a/moksha/public/javascript/ui/moksha.ui.tabs.js +++ b/moksha/public/javascript/ui/moksha.ui.tabs.js @@ -532,17 +532,11 @@ $.widget("ui.mokshatabs", { url: url, success: function(r, s) { var $panel = $(a.hash + ':first', self.element); - var $temp = $(r); - var $stripped = []; - $.each($temp, function(i, s) { - if (!$(s).is('script[src]')){ - $stripped.push(s); - } - }); + var $stripped = moksha.filter_resources(r); + $panel.html($stripped); cleanup();
- if (o.cache) $.data(a, 'cache.tabs', true); // if loaded once do not load them again
diff --git a/setup.py b/setup.py index 5d870e5..d930a38 100644 --- a/setup.py +++ b/setup.py @@ -79,16 +79,17 @@ setup( orbited = moksha.api.widgets.orbited:orbited_js
jquery = tw.jquery:jquery_js - jquery_ui_core = tw.jquery.ui_core:jquery_ui_core_js - - #jquery_ui_draggable = tw.jquery.ui:ui_draggable_min_js - #jquery_ui_resizable = tw.jquery.ui:ui_resizable_min_js + moksha = moksha.api.widgets.moksha:moksha_js + jquery_ui_core = tw.jquery.ui:ui_core_js + jquery_ui_draggable = tw.jquery.ui:ui_draggable_min_js + jquery_ui_resizable = tw.jquery.ui:ui_resizable_min_js #jquery_ui_dialog = tw.jquery.ui:ui_dialog_min_js #jquery_ui_tabs = tw.jquery.ui_tabs:jquery_ui_tabs_js #jquery_json_js = fedoracommunity.widgets:jquery_json_js #jquery_template_js = fedoracommunity.widgets:jquery_template_js #jquery_ui_css = moksha.widgets.jquery_ui_theme:JQueryUITheme
+ # Enable support for the Blueprint CSS framework blueprint_ie_css = moksha.widgets.blueprint:blueprint_ie_css blueprint_screen_css = moksha.widgets.blueprint:blueprint_screen_css @@ -98,7 +99,7 @@ setup( #blueprint_fancytype_css = moksha.widgets.blueprint:blueprint_plugin_fancytype_css
# up up down down left right left right b a - #konami_js = moksha.widgets.misc.ptd:konami + konami_js = moksha.widgets.misc.ptd:konami
[moksha.menu] default_menu = moksha.api.menus:MokshaDefaultMenu
moksha-commits@lists.fedorahosted.org