spiderfw 0.6.2 → 0.6.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. data/VERSION +1 -1
  2. data/apps/core/components/assets.rb +5 -1
  3. data/apps/core/components/public/js/jquery/plugins/jquery.ui.nestedSortable.js +356 -0
  4. data/apps/core/components/public/js/plugins/sortable.js +1 -0
  5. data/apps/core/components/public/js/spider.js +15 -6
  6. data/apps/core/forms/widgets/inputs/input/input.rb +4 -0
  7. data/blueprints/.DS_Store +0 -0
  8. data/blueprints/app/.dirs +5 -0
  9. data/blueprints/app/models/.gitignore +0 -0
  10. data/blueprints/app/public/.gitignore +0 -0
  11. data/blueprints/app/widgets/.gitignore +0 -0
  12. data/blueprints/home/.DS_Store +0 -0
  13. data/blueprints/home/.dirs +7 -0
  14. data/blueprints/home/.gitignore +2 -0
  15. data/blueprints/home/apps/.gitignore +0 -0
  16. data/blueprints/home/public/.gitignore +1 -0
  17. data/blueprints/home/tmp/.gitignore +3 -0
  18. data/blueprints/home/var/.gitignore +7 -0
  19. data/blueprints/home/var/cache/.gitignore +3 -0
  20. data/blueprints/home/var/log/.gitignore +3 -0
  21. data/blueprints/home/var/sessions/.gitignore +3 -0
  22. data/blueprints/install/.DS_Store +0 -0
  23. data/lib/spiderfw/cmd/cmd.rb +1 -0
  24. data/lib/spiderfw/controller/helpers/widget_helper.rb +1 -0
  25. data/lib/spiderfw/controller/spider_controller.rb +1 -1
  26. data/lib/spiderfw/http/server.rb +10 -5
  27. data/lib/spiderfw/i18n/javascript_parser.rb +1 -1
  28. data/lib/spiderfw/model/mappers/mapper.rb +1 -0
  29. data/lib/spiderfw/model/mixins/tree.rb +38 -5
  30. data/lib/spiderfw/model/mixins/versioned.rb +1 -0
  31. data/lib/spiderfw/model/storage/db/connectors/oci8.rb +4 -0
  32. data/lib/spiderfw/spider.rb +7 -1
  33. data/lib/spiderfw/templates/blocks/html.rb +1 -1
  34. data/lib/spiderfw/templates/layout.rb +6 -1
  35. data/lib/spiderfw/templates/template.rb +14 -6
  36. data/lib/spiderfw/widget/widget.rb +2 -0
  37. data/spider.gemspec +1 -1
  38. metadata +21 -4
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.6.2
1
+ 0.6.3
@@ -62,9 +62,13 @@ Spider::Template.define_named_asset 'jquery-ui-selectable', [
62
62
  ], :depends => ['jquery-ui-core']
63
63
 
64
64
  Spider::Template.define_named_asset 'jquery-ui-sortable', [
65
- [:js, 'js/jquery/jquery-ui-1.8.11/ui/jquery.ui.sortable.js', Spider::Components]
65
+ [:js, 'js/jquery/jquery-ui-1.8.11/ui/jquery.ui.sortable.js', Spider::Components],
66
66
  ], :depends => ['jquery-ui-core']
67
67
 
68
+ Spider::Template.define_named_asset 'jquery-ui-nestedSortable', [
69
+ [:js, 'js/jquery/plugins/jquery.ui.nestedSortable.js', Spider::Components],
70
+ ], :depends => ['jquery-ui-sortable']
71
+
68
72
  Spider::Template.define_named_asset 'jquery-ui-accordion', [
69
73
  [:js, 'js/jquery/jquery-ui-1.8.11/ui/jquery.ui.accordion.js', Spider::Components]
70
74
  ], :depends => ['jquery-ui-core']
@@ -0,0 +1,356 @@
1
+ /*
2
+ * jQuery UI Nested Sortable
3
+ * v 1.3.4 / 28 apr 2011
4
+ * http://mjsarfatti.com/sandbox/nestedSortable
5
+ *
6
+ * Depends:
7
+ * jquery.ui.sortable.js 1.8+
8
+ *
9
+ * License CC BY-SA 3.0
10
+ * Copyright 2010-2011, Manuele J Sarfatti
11
+ */
12
+
13
+ (function($) {
14
+
15
+ $.widget("ui.nestedSortable", $.extend({}, $.ui.sortable.prototype, {
16
+
17
+ options: {
18
+ tabSize: 20,
19
+ disableNesting: 'ui-nestedSortable-no-nesting',
20
+ errorClass: 'ui-nestedSortable-error',
21
+ listType: 'ol',
22
+ maxLevels: 0,
23
+ noJumpFix: 0
24
+ },
25
+
26
+ _create: function(){
27
+ if (this.noJumpFix == false)
28
+ this.element.height(this.element.height());
29
+ this.element.data('sortable', this.element.data('nestedSortable'));
30
+ return $.ui.sortable.prototype._create.apply(this, arguments);
31
+ },
32
+
33
+
34
+
35
+ _mouseDrag: function(event) {
36
+
37
+ //Compute the helpers position
38
+ this.position = this._generatePosition(event);
39
+ this.positionAbs = this._convertPositionTo("absolute");
40
+
41
+ if (!this.lastPositionAbs) {
42
+ this.lastPositionAbs = this.positionAbs;
43
+ }
44
+
45
+ //Do scrolling
46
+ if(this.options.scroll) {
47
+ var o = this.options, scrolled = false;
48
+ if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') {
49
+
50
+ if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
51
+ this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
52
+ else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity)
53
+ this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
54
+
55
+ if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
56
+ this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
57
+ else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity)
58
+ this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
59
+
60
+ } else {
61
+
62
+ if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
63
+ scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
64
+ else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
65
+ scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
66
+
67
+ if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
68
+ scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
69
+ else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
70
+ scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
71
+
72
+ }
73
+
74
+ if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
75
+ $.ui.ddmanager.prepareOffsets(this, event);
76
+ }
77
+
78
+ //Regenerate the absolute position used for position checks
79
+ this.positionAbs = this._convertPositionTo("absolute");
80
+
81
+ //Set the helper position
82
+ if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
83
+ if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
84
+
85
+ //Rearrange
86
+ for (var i = this.items.length - 1; i >= 0; i--) {
87
+
88
+ //Cache variables and intersection, continue if no intersection
89
+ var item = this.items[i], itemElement = item.item[0], intersection = this._intersectsWithPointer(item);
90
+ if (!intersection) continue;
91
+
92
+ if(itemElement != this.currentItem[0] //cannot intersect with itself
93
+ && this.placeholder[intersection == 1 ? "next" : "prev"]()[0] != itemElement //no useless actions that have been done before
94
+ && !$.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked
95
+ && (this.options.type == 'semi-dynamic' ? !$.contains(this.element[0], itemElement) : true)
96
+ //&& itemElement.parentNode == this.placeholder[0].parentNode // only rearrange items within the same container
97
+ ) {
98
+
99
+ this.direction = intersection == 1 ? "down" : "up";
100
+
101
+ if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) {
102
+ this._rearrange(event, item);
103
+ } else {
104
+ break;
105
+ }
106
+
107
+ // Clear emtpy ul's/ol's
108
+ this._clearEmpty(itemElement);
109
+
110
+ this._trigger("change", event, this._uiHash());
111
+ break;
112
+ }
113
+ }
114
+
115
+ var parentItem = (this.placeholder[0].parentNode.parentNode && $(this.placeholder[0].parentNode.parentNode).closest('.ui-sortable').length) ? $(this.placeholder[0].parentNode.parentNode) : null;
116
+ var level = this._getLevel(this.placeholder);
117
+ var childLevels = this._getChildLevels(this.helper);
118
+ var previousItem = this.placeholder[0].previousSibling ? $(this.placeholder[0].previousSibling) : null;
119
+ if (previousItem != null) {
120
+ while (previousItem[0].nodeName.toLowerCase() != 'li' || previousItem[0] == this.currentItem[0]) {
121
+ if (previousItem[0].previousSibling) {
122
+ previousItem = $(previousItem[0].previousSibling);
123
+ } else {
124
+ previousItem = null;
125
+ break;
126
+ }
127
+ }
128
+ }
129
+
130
+ newList = document.createElement(o.listType);
131
+
132
+ this.beyondMaxLevels = 0;
133
+
134
+ // If the item is moved to the left, send it to its parent level
135
+ if (parentItem != null && this.positionAbs.left < parentItem.offset().left) {
136
+ parentItem.after(this.placeholder[0]);
137
+ this._clearEmpty(parentItem[0]);
138
+ this._trigger("change", event, this._uiHash());
139
+ }
140
+ // If the item is below another one and is moved to the right, make it a children of it
141
+ else if (previousItem != null && this.positionAbs.left > previousItem.offset().left + o.tabSize) {
142
+ this._isAllowed(previousItem, level+childLevels+1);
143
+ if (!previousItem.children(o.listType).length) {
144
+ previousItem[0].appendChild(newList);
145
+ }
146
+ previousItem.children(o.listType)[0].appendChild(this.placeholder[0]);
147
+ this._trigger("change", event, this._uiHash());
148
+ }
149
+ else {
150
+ this._isAllowed(parentItem, level+childLevels);
151
+ }
152
+
153
+ //Post events to containers
154
+ this._contactContainers(event);
155
+
156
+ //Interconnect with droppables
157
+ if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
158
+
159
+ //Call callbacks
160
+ this._trigger('sort', event, this._uiHash());
161
+
162
+ this.lastPositionAbs = this.positionAbs;
163
+ return false;
164
+
165
+ },
166
+
167
+ _mouseStop: function(event, noPropagation) {
168
+
169
+ // If the item is in a position not allowed, send it back
170
+ if (this.beyondMaxLevels) {
171
+ var parent = this.placeholder.parent().closest(this.options.items);
172
+
173
+ for (var i = this.beyondMaxLevels - 1; i > 0; i--) {
174
+ parent = parent.parent().closest(this.options.items);
175
+ }
176
+
177
+ this.placeholder.removeClass(this.options.errorClass);
178
+ parent.after(this.placeholder);
179
+ this._trigger("change", event, this._uiHash());
180
+ }
181
+
182
+ $.ui.sortable.prototype._mouseStop.apply(this, arguments);
183
+
184
+ },
185
+
186
+ serialize: function(o) {
187
+
188
+ var items = this._getItemsAsjQuery(o && o.connected);
189
+ var str = []; o = o || {};
190
+
191
+ $(items).each(function() {
192
+ var res = ($(o.item || this).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
193
+ var pid = ($(o.item || this).parent(o.listType).parent('li').attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
194
+ if(res) str.push((o.key || res[1]+'['+(o.key && o.expression ? res[1] : res[2])+']')+'='+(pid ? (o.key && o.expression ? pid[1] : pid[2]) : 'root'));
195
+ });
196
+
197
+ if(!str.length && o.key) {
198
+ str.push(o.key + '=');
199
+ }
200
+
201
+ return str.join('&');
202
+
203
+ },
204
+
205
+ toHierarchy: function(o) {
206
+
207
+ o = o || {};
208
+ var sDepth = o.startDepthCount || 0;
209
+ var ret = [];
210
+
211
+ $(this.element).children('li').each(function() {
212
+ var level = _recursiveItems($(this));
213
+ ret.push(level);
214
+ });
215
+
216
+ return ret;
217
+
218
+ function _recursiveItems(li) {
219
+ var id = ($(li).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
220
+ if (id != null) {
221
+ var item = {"id" : id[2]};
222
+ if ($(li).children(o.listType).children('li').length > 0) {
223
+ item.children = [];
224
+ $(li).children(o.listType).children('li').each(function () {
225
+ var level = _recursiveItems($(this));
226
+ item.children.push(level);
227
+ });
228
+ }
229
+ return item;
230
+ }
231
+ }
232
+ },
233
+
234
+ toArray: function(o) {
235
+
236
+ o = o || {};
237
+ var sDepth = o.startDepthCount || 0;
238
+ var ret = [];
239
+ var left = 2;
240
+
241
+ ret.push({"item_id": 'root', "parent_id": 'none', "depth": sDepth, "left": '1', "right": ($('li', this.element).length + 1) * 2});
242
+
243
+ $(this.element).children('li').each(function () {
244
+ left = _recursiveArray(this, sDepth + 1, left);
245
+ });
246
+
247
+ function _sortByLeft(a,b) {
248
+ return a['left'] - b['left'];
249
+ }
250
+ ret = ret.sort(_sortByLeft);
251
+
252
+ return ret;
253
+
254
+ function _recursiveArray(item, depth, left) {
255
+
256
+ right = left + 1;
257
+
258
+ if ($(item).children(o.listType).children('li').length > 0) {
259
+ depth ++;
260
+ $(item).children(o.listType).children('li').each(function () {
261
+ right = _recursiveArray($(this), depth, right);
262
+ });
263
+ depth --;
264
+ }
265
+
266
+ id = ($(item).attr(o.attribute || 'id')).match(o.expression || (/(.+)[-=_](.+)/));
267
+
268
+ if (depth === sDepth + 1) pid = 'root';
269
+ else {
270
+ parentItem = ($(item).parent(o.listType).parent('li').attr('id')).match(o.expression || (/(.+)[-=_](.+)/));
271
+ pid = parentItem[2];
272
+ }
273
+
274
+ if (id != null) {
275
+ ret.push({"item_id": id[2], "parent_id": pid, "depth": depth, "left": left, "right": right});
276
+ }
277
+
278
+ return left = right + 1;
279
+ }
280
+
281
+ },
282
+
283
+ _clear: function(event, noPropagation) {
284
+
285
+ $.ui.sortable.prototype._clear.apply(this, arguments);
286
+
287
+ // Clean last empty ul/ol
288
+ for (var i = this.items.length - 1; i >= 0; i--) {
289
+ var item = this.items[i].item[0];
290
+ this._clearEmpty(item);
291
+ }
292
+ return true;
293
+
294
+ },
295
+
296
+ _clearEmpty: function(item) {
297
+
298
+ if (item.children[1] && item.children[1].children.length == 0) {
299
+ item.removeChild(item.children[1]);
300
+ }
301
+
302
+ },
303
+
304
+ _getLevel: function(item) {
305
+
306
+ var level = 1;
307
+
308
+ if (this.options.listType) {
309
+ var list = item.closest(this.options.listType);
310
+ while (!list.is('.ui-sortable')/* && level < this.options.maxLevels*/) {
311
+ level++;
312
+ list = list.parent().closest(this.options.listType);
313
+ }
314
+ }
315
+
316
+ return level;
317
+ },
318
+
319
+ _getChildLevels: function(parent, depth) {
320
+ var self = this,
321
+ o = this.options,
322
+ result = 0;
323
+ depth = depth || 0;
324
+
325
+ $(parent).children(o.listType).children(o.items).each(function (index, child) {
326
+ result = Math.max(self._getChildLevels(child, depth + 1), result);
327
+ });
328
+
329
+ return depth ? result + 1 : result;
330
+ },
331
+
332
+ _isAllowed: function(parentItem, levels) {
333
+ var o = this.options
334
+ // Are we trying to nest under a no-nest or are we nesting too deep?
335
+ if (parentItem == null || !(parentItem.hasClass(o.disableNesting))) {
336
+ if (o.maxLevels < levels && o.maxLevels != 0) {
337
+ this.placeholder.addClass(o.errorClass);
338
+ this.beyondMaxLevels = levels - o.maxLevels;
339
+ } else {
340
+ this.placeholder.removeClass(o.errorClass);
341
+ this.beyondMaxLevels = 0;
342
+ }
343
+ } else {
344
+ this.placeholder.addClass(o.errorClass);
345
+ if (o.maxLevels < levels && o.maxLevels != 0) {
346
+ this.beyondMaxLevels = levels - o.maxLevels;
347
+ } else {
348
+ this.beyondMaxLevels = 1;
349
+ }
350
+ }
351
+ }
352
+
353
+ }));
354
+
355
+ $.ui.nestedSortable.prototype.options = $.extend({}, $.ui.sortable.prototype.options, $.ui.nestedSortable.prototype.options);
356
+ })(jQuery);
@@ -100,6 +100,7 @@ Spider.Sortable = Spider.Plugin.extend({
100
100
  return;
101
101
  }
102
102
  var pos = this.findLiPosition(ui.item);
103
+ if (pos == -1) return;
103
104
  return this.acceptFromSender(ui.sender, ui.item, pos);
104
105
  },
105
106
 
@@ -460,11 +460,16 @@ Spider.defineWidget = function(name, parent, w){
460
460
  if (!curr[parts[i]]) curr[parts[i]] = function(){};
461
461
  curr = curr[parts[i]];
462
462
  }
463
- if (parent) parent = Spider.widgetClasses[parent];
464
- else parent = Spider.Widget;
465
- var widget = parent.extend(w);
466
463
  var last = parts[parts.length-1];
467
- if (curr[last]) widget = curr[last].extend(widget);
464
+ var widget;
465
+ if (curr[last]){
466
+ widget = curr[last].extend(w);
467
+ }
468
+ else{
469
+ if (parent) parent = Spider.widgetClasses[parent];
470
+ else parent = Spider.Widget;
471
+ widget = parent.extend(w);
472
+ }
468
473
  curr[last] = widget;
469
474
  Spider.widgetClasses[name] = widget;
470
475
  if (w.autoInit){
@@ -744,9 +749,13 @@ $.extend(Spider.Widget.prototype, Spider.EventTarget);
744
749
  var translations = {};
745
750
 
746
751
  function _(s){
752
+ var str = s;
747
753
  var tr = translations[s];
748
- if (tr) return tr;
749
- return s;
754
+ if (tr) str = tr;
755
+ for (var i=1; i<arguments.length; i++){
756
+ str = str.replace('%s', arguments[i]);
757
+ }
758
+ return str;
750
759
  }
751
760
 
752
761
  if(!window.console) {
@@ -4,8 +4,10 @@ module Spider; module Forms
4
4
  attr_accessor :element, :form, :errors
5
5
  i_attr_accessor :name
6
6
  is_attribute :value
7
+ is_attr_accessor :default
7
8
  is_attr_accessor :label
8
9
  is_attr_accessor :required, :type => Spider::DataTypes::Bool
10
+
9
11
 
10
12
 
11
13
  def init
@@ -43,6 +45,7 @@ module Spider; module Forms
43
45
  end
44
46
 
45
47
  def format_value
48
+ @value ||= @default
46
49
  @value.respond_to?(:format) ? @value.format : @value
47
50
  end
48
51
 
@@ -87,6 +90,7 @@ module Spider; module Forms
87
90
  end
88
91
 
89
92
  def check
93
+ #debugger
90
94
  if required? && !has_value?
91
95
  add_error( _("%s is required") % self.label )
92
96
  end
Binary file
@@ -0,0 +1,5 @@
1
+ controllers
2
+ models
3
+ public
4
+ views
5
+ widgets
File without changes
File without changes
File without changes
Binary file
@@ -0,0 +1,7 @@
1
+ apps
2
+ config
3
+ public
4
+ tmp
5
+ var/cache
6
+ var/log
7
+ var/sessions
@@ -0,0 +1,2 @@
1
+ tmp
2
+ var
File without changes
@@ -0,0 +1 @@
1
+ _c/*
@@ -0,0 +1,3 @@
1
+ # Ignore everything in here apart from the .gitignore file
2
+ *
3
+ !.gitignore
@@ -0,0 +1,7 @@
1
+ # Ignore everything in here apart from the .gitignore file
2
+ *
3
+ !.gitignore
4
+ !cache/.gitignore
5
+ !log/.gitignore
6
+ !sessions/.gitignore
7
+
@@ -0,0 +1,3 @@
1
+ # Ignore everything in here apart from the .gitignore file
2
+ *
3
+ !.gitignore
@@ -0,0 +1,3 @@
1
+ # Ignore everything in here apart from the .gitignore file
2
+ *
3
+ !.gitignore
@@ -0,0 +1,3 @@
1
+ # Ignore everything in here apart from the .gitignore file
2
+ *
3
+ !.gitignore
Binary file
@@ -71,6 +71,7 @@ module Spider; module CommandLine
71
71
  end
72
72
  cmd_name ||= 'help'
73
73
  if !@cmd.main_command.commands[cmd_name]
74
+ $SPIDER_CMD = true
74
75
  require 'spiderfw'
75
76
  if Spider.apps_by_short_name[cmd_name] && Spider.apps_by_short_name[cmd_name].const_defined?(:Cmd)
76
77
  app_cmd = Spider.apps_by_short_name[cmd_name].const_get(:Cmd).new
@@ -10,6 +10,7 @@ module Spider; module Helpers
10
10
  scene = super
11
11
  if (self.is_a?(Widget))
12
12
  scene.widget = widget_to_scene(self)
13
+ scene.widget[:shown_id] = attributes[:keep_id] ? self.local_id : self.full_id
13
14
  end
14
15
  scene.widgets = {}
15
16
  if (@widgets)
@@ -6,7 +6,7 @@ module Spider
6
6
 
7
7
 
8
8
  def self.pub_path
9
- $SPIDER_PATH+'/public'
9
+ File.join($SPIDER_PATH, 'public')
10
10
  end
11
11
 
12
12
  def self.pub_url
@@ -42,6 +42,7 @@ module Spider; module HTTP
42
42
  }
43
43
 
44
44
  start = lambda{
45
+ $SPIDER_WEB_SERVER = true
45
46
  require 'spiderfw'
46
47
  require 'spiderfw/controller/http_controller'
47
48
 
@@ -108,17 +109,21 @@ module Spider; module HTTP
108
109
  Process.detach(forked)
109
110
  else
110
111
  Spider.init_base
112
+ spawner_started = true
111
113
  if Spider.conf.get('webserver.respawn_on_change')
112
114
  Spider.start_loggers
113
115
  begin
114
- Bundler.require :default, Spider.runmode.to_sym
116
+ begin
117
+ Bundler.require :default, Spider.runmode.to_sym
118
+ rescue
119
+ end
120
+ spawner = Spawner.new({'spawn' => start})
121
+ spawner.run('spawn')
115
122
  rescue
123
+ Spider.logger.error("Install 'fssm' gem to enable respawning")
116
124
  end
117
- spawner = Spawner.new({'spawn' => start})
118
- spawner.run('spawn')
119
- else
120
- start.call
121
125
  end
126
+ start.call unless spawner_started
122
127
  end
123
128
  end
124
129
 
@@ -6,7 +6,7 @@ module Spider; module I18n
6
6
  module JavascriptParser
7
7
  module_function
8
8
 
9
- GettextRegexp = /\W_\(['"]([^\)'"]+)['"](,\s*[^\)]\s*)*\)/
9
+ GettextRegexp = /\W_\(['"]([^\)'"]+)['"](,\s*[^\)]+\s*)*\)/
10
10
 
11
11
 
12
12
 
@@ -762,6 +762,7 @@ module Spider; module Model
762
762
  res = path.empty? ? obj : obj.all_children(path)
763
763
  raise RuntimeError, "Broken object path" if (obj && !path.empty? && res.length < 1)
764
764
  res = QuerySet.new(@model, res) unless res.is_a?(QuerySet)
765
+ res = res.select{ |obj| obj.primary_keys_set? }
765
766
  return res
766
767
  end
767
768
 
@@ -44,11 +44,13 @@ module Spider; module Model
44
44
  attributes[:tree_left] ||= :"#{name}_left"
45
45
  attributes[:tree_right] ||= :"#{name}_right"
46
46
  attributes[:tree_depth] ||= :"#{name}_depth"
47
+ attributes[:tree_position] ||= :"#{name}_position"
47
48
  choice(attributes[:reverse], self, attributes[:reverse_attributes])
48
49
  element(name, self, attributes)
49
- element(attributes[:tree_left], Fixnum, :hidden => true, :tree_element => name)
50
+ element(attributes[:tree_left], Fixnum, :hidden => true, :tree_element => name, :order => true)
50
51
  element(attributes[:tree_right], Fixnum, :hidden => true, :tree_element => name)
51
52
  element(attributes[:tree_depth], Fixnum, :unmapped => true, :hidden => true, :tree_element => name)
53
+ element(attributes[:tree_position], Fixnum, :unmapped => true, :hidden => true, :tree_element => name)
52
54
  # sequence(name)
53
55
  qs_module ||= Module.new
54
56
 
@@ -92,7 +94,8 @@ module Spider; module Model
92
94
  define_method("#{name}_all") do
93
95
  qs = QuerySet.static(self)
94
96
  self.send("#{name}_roots").each do |root|
95
- qs += root.tree_all(name)
97
+ ta = root.tree_all(name)
98
+ qs += ta if ta
96
99
  end
97
100
  return qs
98
101
  end
@@ -146,6 +149,23 @@ module Spider; module Model
146
149
 
147
150
  end
148
151
  end
152
+
153
+ define_method(attributes[:tree_position]) do
154
+ i = instance_variable_get("@#{attributes[:tree_position]}")
155
+ return i if i
156
+ element = self.class.elements[name]
157
+ left_el = element.attributes[:tree_left]
158
+ right_el = element.attributes[:tree_right]
159
+ parent_el = element.attributes[:reverse]
160
+ parent = self.get(parent_el)
161
+ return nil unless parent
162
+ cnt = 0
163
+ parent.get(name).each do |sub|
164
+ cnt += 1
165
+ return cnt if sub == self
166
+ end
167
+ return nil
168
+ end
149
169
 
150
170
  end
151
171
 
@@ -167,12 +187,25 @@ module Spider; module Model
167
187
 
168
188
  def before_save(obj, mode)
169
189
  @model.elements_array.select{ |el| el.attributes[:association] == :tree }.each do |el|
170
- if (mode == :update)
190
+ unless obj.element_modified?(el.attributes[:reverse]) || obj.element_modified?(el.attributes[:tree_position])
191
+ next
192
+ end
193
+ if mode == :update
171
194
  tree_remove(el, obj)
172
195
  end
173
196
  parent = obj.get(el.attributes[:reverse])
174
- if (parent)
175
- tree_insert_node_under(el, obj, parent)
197
+ if parent
198
+ sub = parent.get(el.name)
199
+ if obj.element_modified?(el.attributes[:tree_position]) && sub.length > 0
200
+ pos = obj.get(el.attributes[:tree_position])
201
+ if pos == 1
202
+ tree_insert_node_first(el, obj, parent)
203
+ else
204
+ tree_insert_node_right(el, obj, sub[pos-2])
205
+ end
206
+ else
207
+ tree_insert_node_under(el, obj, parent)
208
+ end
176
209
  else
177
210
  tree_insert_node(el, obj)
178
211
  end
@@ -124,6 +124,7 @@ module Spider; module Model
124
124
  vmod.remove_element(elh[:attributes][:tree_left])
125
125
  vmod.remove_element(elh[:attributes][:tree_right])
126
126
  vmod.remove_element(elh[:attributes][:tree_depth])
127
+ vmod.remove_element(elh[:attributes][:tree_position])
127
128
  vmod.tree(el.name, elh[:attributes])
128
129
  else
129
130
  vmod.send(elh[:method], el.name, el.type.version_model, elh[:attributes])
@@ -1,5 +1,9 @@
1
1
  require 'oci8'
2
2
 
3
+ # The default mapping to BigDecimal doesn't seem to work (as of ruby-oci8 2.0.4), reverting to Float until it's fixed
4
+ OCI8::BindType::Mapping[:number_unknown_prec] = OCI8::BindType::Float
5
+ OCI8::BindType::Mapping[:number_no_prec_setting] = OCI8::BindType::Float
6
+
3
7
  module Spider; module Model; module Storage; module Db; module Connectors
4
8
 
5
9
  module OCI8
@@ -626,7 +626,13 @@ module Spider
626
626
  Debugger.start
627
627
  end
628
628
  rescue LoadError, RuntimeError => exc
629
- Spider.logger.warn(exc.message)
629
+ msg = _('Unable to start debugger. Ensure ruby-debug is installed (or set debugger.start to false).')
630
+ if Spider.logger
631
+ Spider.logger.warn(exc.message)
632
+ Spider.logger.warn(msg)
633
+ else
634
+ puts msg
635
+ end
630
636
  end
631
637
  end
632
638
 
@@ -37,7 +37,7 @@ module Spider; module TemplateBlocks
37
37
  if options[:owner_class]
38
38
  cl += " wdgt-#{options[:owner_class].name.gsub('::', '-')}"
39
39
  end
40
- @el.set_attribute('id', "{ @widget[:full_id] }")
40
+ @el.set_attribute('id', "{ @widget[:shown_id] }")
41
41
  cl += ' ' unless cl.empty?
42
42
  cl += '{ @widget[:css_classes] }'
43
43
  end
@@ -15,6 +15,7 @@ module Spider
15
15
  end
16
16
 
17
17
  def render(*args)
18
+ $PUB_URL = Spider::HomeController.pub_url
18
19
  prepare_assets unless @assets_prepared
19
20
  super
20
21
  end
@@ -107,7 +108,11 @@ module Spider
107
108
  end
108
109
  if ass[:gettext] && type == :js
109
110
  msg_path = asset_gettext_messages_file(ass[:path])
110
- js_messages += JSON.parse(File.read(msg_path))
111
+ if File.exists?(msg_path)
112
+ js_messages += JSON.parse(File.read(msg_path))
113
+ else
114
+ Spider.logger.warn("Javascript Gettext file #{msg_path} not found")
115
+ end
111
116
  end
112
117
  end
113
118
  assets[:js].each do |ass|
@@ -296,6 +296,10 @@ module Spider
296
296
  w_templates = $2.split('|')
297
297
  end
298
298
  klass = Spider::Template.get_registered_class(w)
299
+ unless klass
300
+ Spider.logger.warn("tpl:assets requested non existent widget #{w}")
301
+ next
302
+ end
299
303
  w_templates ||= [klass.default_template]
300
304
  w_templates.each do |wt|
301
305
  t = klass.load_template(wt)
@@ -377,6 +381,9 @@ module Spider
377
381
  parse_asset(nmdass[:type], nmdass[:src], nmdass)
378
382
  }.flatten
379
383
  end
384
+ if attributes[:profiles]
385
+ ass[:profiles] = attributes[:profiles].split(/,\s*/).map{ |p| p.to_sym }
386
+ end
380
387
  if attributes[:app] == :runtime
381
388
  ass[:runtime] = src
382
389
  return [ass]
@@ -406,9 +413,13 @@ module Spider
406
413
  ass[:path] = res.path if res
407
414
  base_url = nil
408
415
  if controller.respond_to?(:pub_url)
409
- if src[0].chr == '/' && !(controller <= Spider::HomeController)
416
+ if src[0].chr == '/'
417
+ if controller <= Spider::HomeController
418
+ src = src[(1+controller.pub_path.length)..-1]
419
+ else
410
420
  # strips the app path from the src. FIXME: should probably be done somewhere else
411
- src = src[(2+controller.app.relative_path.length)..-1]
421
+ src = src[(2+controller.app.relative_path.length)..-1]
422
+ end
412
423
  end
413
424
  base_url = controller.pub_url+'/'
414
425
 
@@ -438,9 +449,6 @@ module Spider
438
449
  [:gettext, :media, :if_ie_lte, :cdn].each do |key|
439
450
  ass[key] = attributes[key] if attributes.key?(key)
440
451
  end
441
- if attributes[:profiles]
442
- ass[:profiles] = attributes[:profiles].split(/,\s*/).map{ |p| p.to_sym }
443
- end
444
452
  return [ass]
445
453
  end
446
454
 
@@ -505,7 +513,7 @@ module Spider
505
513
  ass_src = ass.get_attribute('src')
506
514
  if ass_src && ass_src[0].chr != '/'
507
515
  # ass.set_attribute('src', "/#{ext_app.relative_path}/#{ass_src}")
508
- ass.set_attribute('app', ext_app.relative_path)
516
+ ass.set_attribute('app', ext_app.relative_path) if ass.get_attribute('app').blank?
509
517
  end
510
518
  end
511
519
  @overrides += orig_overrides
@@ -238,6 +238,8 @@ module Spider
238
238
  i_attribute :use_template
239
239
  attribute :"sp:target-only"
240
240
  attribute :class
241
+ # shows the widget's local id in the html instead of the full id
242
+ attribute :keep_id, :type => Spider::Bool, :default => false
241
243
 
242
244
  default_asset 'jquery'
243
245
  default_asset 'spider'
data/spider.gemspec CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |s|
18
18
  'spider.gemspec'] \
19
19
  + Dir.glob('apps/**/*') \
20
20
  + Dir.glob('bin/*') \
21
- + Dir.glob('blueprints/**/*') \
21
+ + Dir.glob('blueprints/**/*', File::FNM_DOTMATCH) \
22
22
  + Dir.glob('data/**/*') \
23
23
  + Dir.glob('lib/**/*.rb') \
24
24
  + Dir.glob('views/**/*')
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spiderfw
3
3
  version: !ruby/object:Gem::Version
4
- hash: 3
4
+ hash: 1
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 6
9
- - 2
10
- version: 0.6.2
9
+ - 3
10
+ version: 0.6.3
11
11
  platform: ruby
12
12
  authors:
13
13
  - Ivan Pirlik
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-06-10 00:00:00 +02:00
18
+ date: 2011-06-28 00:00:00 +02:00
19
19
  default_executable: spider
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -462,6 +462,7 @@ files:
462
462
  - apps/core/components/public/js/jquery/plugins/jquery.form.js
463
463
  - apps/core/components/public/js/jquery/plugins/jquery.json.js
464
464
  - apps/core/components/public/js/jquery/plugins/jquery.query-2.1.6.js
465
+ - apps/core/components/public/js/jquery/plugins/jquery.ui.nestedSortable.js
465
466
  - apps/core/components/public/js/jquery/plugins/jquery.url.js
466
467
  - apps/core/components/public/js/jquery/plugins/treeview/changelog.txt
467
468
  - apps/core/components/public/js/jquery/plugins/treeview/images/ajax-loader.gif
@@ -963,15 +964,31 @@ files:
963
964
  - apps/worker/models/job.rb
964
965
  - apps/worker/worker.rb
965
966
  - bin/spider
967
+ - blueprints/.DS_Store
968
+ - blueprints/app/.dirs
966
969
  - blueprints/app/__APP__.appspec
967
970
  - blueprints/app/_init.rb
968
971
  - blueprints/app/controllers/__APP___controller.rb
972
+ - blueprints/app/models/.gitignore
973
+ - blueprints/app/public/.gitignore
969
974
  - blueprints/app/views/__APP__.layout.shtml
970
975
  - blueprints/app/views/index.shtml
976
+ - blueprints/app/widgets/.gitignore
977
+ - blueprints/home/.dirs
978
+ - blueprints/home/.DS_Store
979
+ - blueprints/home/.gitignore
980
+ - blueprints/home/apps/.gitignore
971
981
  - blueprints/home/config/config.yml
972
982
  - blueprints/home/Gemfile.disabled
973
983
  - blueprints/home/init.rb
984
+ - blueprints/home/public/.gitignore
974
985
  - blueprints/home/spider.gemfile
986
+ - blueprints/home/tmp/.gitignore
987
+ - blueprints/home/var/.gitignore
988
+ - blueprints/home/var/cache/.gitignore
989
+ - blueprints/home/var/log/.gitignore
990
+ - blueprints/home/var/sessions/.gitignore
991
+ - blueprints/install/.DS_Store
975
992
  - blueprints/install/config.ru
976
993
  - data/locale/it/LC_MESSAGES/spider.mo
977
994
  - data/locale/it/LC_MESSAGES/spider_auth.mo