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(a)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(a)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