ende 0.3.3 → 0.3.4
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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/lib/assets/javascripts/aura/extensions/models.js.coffee.erb +0 -1
- data/lib/assets/javascripts/aura/extensions/rivets/accounting.js.coffee +28 -0
- data/lib/assets/javascripts/aura/extensions/rivets/formatters.js.coffee +7 -18
- data/lib/assets/javascripts/aura/extensions/rivets.js.coffee +7 -8
- data/lib/assets/javascripts/widgets/content/main.js.coffee +6 -0
- data/lib/assets/javascripts/widgets/viewer/main.js.coffee +27 -6
- data/lib/ende/version.rb +1 -1
- data/lib/ende.rb +0 -1
- data/vendor/assets/javascripts/accounting/accounting.js +412 -0
- metadata +4 -3
- data/lib/assets/javascripts/aura/extensions/rivets/#formatters.js.coffee# +0 -183
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d24ccd4924909fbc2f6b8b2efd1cd7f726150ee1
|
4
|
+
data.tar.gz: 38ad8038c472810465940bc4da1b6f26c8d7932a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9c1e7a3e80b3d7915a61597bb57c6208659b50f3ab90cb3343fcb8d8fd8028a1cc6feade21af6397e89fe5df410058fec8aaf15210d2f75b6d5aaafd8914212a
|
7
|
+
data.tar.gz: f862326bf57c4dd40bb4d31319a3096403dbddb7141805b6db2ac822a9fdcb25c2c1094f4865853dab7433bda16da4a74da588fdfa3d8c0d24d7c4a30366ac65
|
data/.gitignore
CHANGED
@@ -0,0 +1,28 @@
|
|
1
|
+
#= require accounting/accounting
|
2
|
+
|
3
|
+
define 'aura/extensions/rivets/accounting', ['vendor/accounting'], (accounting) ->
|
4
|
+
|
5
|
+
rivets = require 'mikeric-rivets/dist/rivets'
|
6
|
+
|
7
|
+
rivets.configure
|
8
|
+
formatters:
|
9
|
+
# ### currency
|
10
|
+
# ```data-text="user.accountBalance | currency"```
|
11
|
+
#
|
12
|
+
# You must include [accounting.js](http://josscrowcroft.github.com/accounting.js/) on your page to use this. It is not bundled.
|
13
|
+
#
|
14
|
+
# Returns the value currency formatted by accounting.js
|
15
|
+
currency: (v) -> accounting.formatMoney v
|
16
|
+
|
17
|
+
initialize: (application) ->
|
18
|
+
{core} = application
|
19
|
+
|
20
|
+
core.util.extend accounting.settings.currency,
|
21
|
+
symbol: 'R$'
|
22
|
+
thousand: '.'
|
23
|
+
decimal: ','
|
24
|
+
|
25
|
+
core.util.extend accounting.settings.number,
|
26
|
+
thousand: '.'
|
27
|
+
decimal: ','
|
28
|
+
|
@@ -1,4 +1,4 @@
|
|
1
|
-
define 'extensions/rivets/formatters',
|
1
|
+
define 'extensions/rivets/formatters',
|
2
2
|
|
3
3
|
# ### exists
|
4
4
|
# ```data-show="user.name | exists"```
|
@@ -20,14 +20,6 @@ define 'extensions/rivets/formatters',
|
|
20
20
|
# Returns the value date formatted by moment.js
|
21
21
|
# date: (v) -> moment(v).format 'MMM DD, YYYY'
|
22
22
|
|
23
|
-
# ### money
|
24
|
-
# ```data-text="user.accountBalance | money"```
|
25
|
-
#
|
26
|
-
# You must include [accounting.js](http://josscrowcroft.github.com/accounting.js/) on your page to use this. It is not bundled.
|
27
|
-
#
|
28
|
-
# Returns the value currency formatted by accounting.js
|
29
|
-
# money: (v) -> accounting.formatMoney v
|
30
|
-
|
31
23
|
# ### toNumber
|
32
24
|
# ```data-value="user.sweetText | toNumber"```
|
33
25
|
#
|
@@ -141,17 +133,17 @@ define 'extensions/rivets/formatters',
|
|
141
133
|
# Sorts collection in asc or desc order on a field
|
142
134
|
sortBy: (arr, field, direction='asc') ->
|
143
135
|
reverse = (direction is 'desc')
|
144
|
-
sortFn = (a, b) ->
|
145
|
-
if a[field] < b[field]
|
136
|
+
sortFn = (a, b) ->
|
137
|
+
if a[field] < b[field]
|
146
138
|
out = -1
|
147
139
|
else if a[field] > b[field]
|
148
|
-
out = 1
|
149
|
-
else
|
140
|
+
out = 1
|
141
|
+
else
|
150
142
|
out = 0
|
151
143
|
return out*[1,-1][+!!reverse]
|
152
144
|
|
153
145
|
return arr.sort sortFn
|
154
|
-
|
146
|
+
|
155
147
|
|
156
148
|
float: (value) ->
|
157
149
|
throw new TypeError "Invalid value passed to float formatter: #{value}" unless value?
|
@@ -166,7 +158,4 @@ define 'extensions/rivets/formatters',
|
|
166
158
|
(isNaN(value)) && (value = 0)
|
167
159
|
|
168
160
|
# Format value
|
169
|
-
value.toFixed(2).toString().replace '.', ','
|
170
|
-
|
171
|
-
currency: (value) ->
|
172
|
-
'R$ ' + rivets.formatters.float value
|
161
|
+
value.toFixed(2).toString().replace '.', ','
|
@@ -11,12 +11,10 @@ define 'aura/extensions/rivets', ['extensions/rivets/formatters'], (formatters)-
|
|
11
11
|
Rivets = rivets._
|
12
12
|
|
13
13
|
observable_configuration = require 'indefinido-observable/lib/adapters/rivets'
|
14
|
-
|
15
|
-
|
16
|
-
extend rivets.formatters, formatters
|
17
14
|
|
18
15
|
rivets.configure observable_configuration
|
19
16
|
rivets.configure
|
17
|
+
formatters: formatters
|
20
18
|
templateDelimiters: ['{{', '}}']
|
21
19
|
|
22
20
|
# Custom rivets view because we don't want to prefix attributes
|
@@ -217,9 +215,6 @@ define 'aura/extensions/rivets', ['extensions/rivets/formatters'], (formatters)-
|
|
217
215
|
el.value = if value? then value else ''
|
218
216
|
|
219
217
|
|
220
|
-
|
221
|
-
|
222
|
-
|
223
218
|
(application) ->
|
224
219
|
version: '0.1.0'
|
225
220
|
|
@@ -229,8 +224,12 @@ define 'aura/extensions/rivets', ['extensions/rivets/formatters'], (formatters)-
|
|
229
224
|
# TODO implement small view interface
|
230
225
|
original_bind = rivets.bind
|
231
226
|
rivets.bind = (selector, presentation) ->
|
232
|
-
for name, model of presentation
|
233
|
-
|
227
|
+
for name, model of presentation
|
228
|
+
unless model?
|
229
|
+
console.warn "Model object not specified for key #{name}"
|
230
|
+
model = {}
|
231
|
+
|
232
|
+
presentation[name] = observable model unless model.observed?
|
234
233
|
|
235
234
|
original_bind.apply rivets, arguments
|
236
235
|
|
@@ -25,6 +25,12 @@ define ->
|
|
25
25
|
|
26
26
|
throw new TypeError "content.initialize: No uri provided to load content" unless normalized_options.uri?
|
27
27
|
|
28
|
+
# In the case of instantiating the widget without uri
|
29
|
+
#
|
30
|
+
# TODO create a event listener that executes only one time and
|
31
|
+
# store the uri on first load
|
32
|
+
@options.uri ||= normalized_options.uri
|
33
|
+
|
28
34
|
normalized_options.url = normalized_options.uri
|
29
35
|
delete normalized_options.uri
|
30
36
|
|
@@ -124,7 +124,7 @@ define [
|
|
124
124
|
viewed: (event, in_view, horizontal, vertical) ->
|
125
125
|
boo[if in_view then 'pride' else 'shame'] event.target
|
126
126
|
|
127
|
-
version: '0.2.
|
127
|
+
version: '0.2.1'
|
128
128
|
|
129
129
|
# TODO better separation of concerns
|
130
130
|
# TODO Current remote page that is beign displayed
|
@@ -199,7 +199,10 @@ define [
|
|
199
199
|
# use it here instead of pushing each record
|
200
200
|
viewer.items = records
|
201
201
|
|
202
|
-
|
202
|
+
# Start widgets created by bindings
|
203
|
+
@syncronize_children()
|
204
|
+
|
205
|
+
@fetching.done (records) =>
|
203
206
|
if viewer.items.length
|
204
207
|
# boo.initialize @$el.find '.results .items'
|
205
208
|
@$el.addClass 'filled'
|
@@ -209,9 +212,6 @@ define [
|
|
209
212
|
@$el.addClass 'empty'
|
210
213
|
@$el.removeClass 'filled'
|
211
214
|
|
212
|
-
# Start widgets that may have been created by bindings
|
213
|
-
@sandbox.start @$el
|
214
|
-
|
215
215
|
@sandbox.emit "viewer.#{@identifier}.populated", records
|
216
216
|
|
217
217
|
@fetching.always =>
|
@@ -269,7 +269,8 @@ define [
|
|
269
269
|
@bind @presentation, @presenter.presentation
|
270
270
|
|
271
271
|
# Start widgets that may have been created by bindings
|
272
|
-
@sandbox.start
|
272
|
+
@sandbox.emit 'aura.sandbox.start', @sandbox
|
273
|
+
@syncronize_children()
|
273
274
|
|
274
275
|
@handles 'click', 'back', '.back'
|
275
276
|
|
@@ -287,6 +288,26 @@ define [
|
|
287
288
|
scrollable widget: @ if options.scroll
|
288
289
|
scopable @ if options.scope or options.scopable
|
289
290
|
|
291
|
+
# TODO move this method to an extension
|
292
|
+
syncronize_children: ->
|
293
|
+
@sandbox._children ||= []
|
294
|
+
|
295
|
+
# Add possible new childs
|
296
|
+
@constructor.startAll(@$el).done (widgets...) =>
|
297
|
+
for widget in widgets
|
298
|
+
widget.sandbox._widget = widget
|
299
|
+
widget.sandbox._parent = @sandbox
|
300
|
+
|
301
|
+
@sandbox._children = @sandbox._children.concat widgets
|
302
|
+
|
303
|
+
# TODO better internal aura widget selection
|
304
|
+
# Prevent other child to be instantiated
|
305
|
+
@$el.find('[data-aura-widget]').each (i, element) ->
|
306
|
+
current = element.getAttribute 'data-aura-widget'
|
307
|
+
element.removeAttribute 'data-aura-widget'
|
308
|
+
element.setAttribute 'aura-widget', current
|
309
|
+
|
310
|
+
# TODO move this method to an extension
|
290
311
|
# TODO listen for future parent presentation changes
|
291
312
|
inherit_parent_presentation: ->
|
292
313
|
return unless view = @sandbox?._parent?._view
|
data/lib/ende/version.rb
CHANGED
data/lib/ende.rb
CHANGED
@@ -17,7 +17,6 @@ module Ende
|
|
17
17
|
assets.paths << current_dir.join('vendor', 'assets', 'javascripts').to_s
|
18
18
|
assets.paths << current_dir.join('vendor', 'assets', 'stylesheets').to_s
|
19
19
|
assets.paths << current_dir.join('vendor', 'assets', 'components' ).to_s
|
20
|
-
|
21
20
|
end
|
22
21
|
|
23
22
|
# Check if devise exists and extend devise controllers to send
|
@@ -0,0 +1,412 @@
|
|
1
|
+
/*!
|
2
|
+
* accounting.js v0.3.2
|
3
|
+
* Copyright 2011, Joss Crowcroft
|
4
|
+
*
|
5
|
+
* Freely distributable under the MIT license.
|
6
|
+
* Portions of accounting.js are inspired or borrowed from underscore.js
|
7
|
+
*
|
8
|
+
* Full details and documentation:
|
9
|
+
* http://josscrowcroft.github.com/accounting.js/
|
10
|
+
*/
|
11
|
+
|
12
|
+
(function(root, undefined) {
|
13
|
+
|
14
|
+
/* --- Setup --- */
|
15
|
+
|
16
|
+
// Create the local library object, to be exported or referenced globally later
|
17
|
+
var lib = {};
|
18
|
+
|
19
|
+
// Current version
|
20
|
+
lib.version = '0.3.2';
|
21
|
+
|
22
|
+
|
23
|
+
/* --- Exposed settings --- */
|
24
|
+
|
25
|
+
// The library's settings configuration object. Contains default parameters for
|
26
|
+
// currency and number formatting
|
27
|
+
lib.settings = {
|
28
|
+
currency: {
|
29
|
+
symbol : "$", // default currency symbol is '$'
|
30
|
+
format : "%s%v", // controls output: %s = symbol, %v = value (can be object, see docs)
|
31
|
+
decimal : ".", // decimal point separator
|
32
|
+
thousand : ",", // thousands separator
|
33
|
+
precision : 2, // decimal places
|
34
|
+
grouping : 3 // digit grouping (not implemented yet)
|
35
|
+
},
|
36
|
+
number: {
|
37
|
+
precision : 0, // default precision on numbers is 0
|
38
|
+
grouping : 3, // digit grouping (not implemented yet)
|
39
|
+
thousand : ",",
|
40
|
+
decimal : "."
|
41
|
+
}
|
42
|
+
};
|
43
|
+
|
44
|
+
|
45
|
+
/* --- Internal Helper Methods --- */
|
46
|
+
|
47
|
+
// Store reference to possibly-available ECMAScript 5 methods for later
|
48
|
+
var nativeMap = Array.prototype.map,
|
49
|
+
nativeIsArray = Array.isArray,
|
50
|
+
toString = Object.prototype.toString;
|
51
|
+
|
52
|
+
/**
|
53
|
+
* Tests whether supplied parameter is a string
|
54
|
+
* from underscore.js
|
55
|
+
*/
|
56
|
+
function isString(obj) {
|
57
|
+
return !!(obj === '' || (obj && obj.charCodeAt && obj.substr));
|
58
|
+
}
|
59
|
+
|
60
|
+
/**
|
61
|
+
* Tests whether supplied parameter is a string
|
62
|
+
* from underscore.js, delegates to ECMA5's native Array.isArray
|
63
|
+
*/
|
64
|
+
function isArray(obj) {
|
65
|
+
return nativeIsArray ? nativeIsArray(obj) : toString.call(obj) === '[object Array]';
|
66
|
+
}
|
67
|
+
|
68
|
+
/**
|
69
|
+
* Tests whether supplied parameter is a true object
|
70
|
+
*/
|
71
|
+
function isObject(obj) {
|
72
|
+
return obj && toString.call(obj) === '[object Object]';
|
73
|
+
}
|
74
|
+
|
75
|
+
/**
|
76
|
+
* Extends an object with a defaults object, similar to underscore's _.defaults
|
77
|
+
*
|
78
|
+
* Used for abstracting parameter handling from API methods
|
79
|
+
*/
|
80
|
+
function defaults(object, defs) {
|
81
|
+
var key;
|
82
|
+
object = object || {};
|
83
|
+
defs = defs || {};
|
84
|
+
// Iterate over object non-prototype properties:
|
85
|
+
for (key in defs) {
|
86
|
+
if (defs.hasOwnProperty(key)) {
|
87
|
+
// Replace values with defaults only if undefined (allow empty/zero values):
|
88
|
+
if (object[key] == null) object[key] = defs[key];
|
89
|
+
}
|
90
|
+
}
|
91
|
+
return object;
|
92
|
+
}
|
93
|
+
|
94
|
+
/**
|
95
|
+
* Implementation of `Array.map()` for iteration loops
|
96
|
+
*
|
97
|
+
* Returns a new Array as a result of calling `iterator` on each array value.
|
98
|
+
* Defers to native Array.map if available
|
99
|
+
*/
|
100
|
+
function map(obj, iterator, context) {
|
101
|
+
var results = [], i, j;
|
102
|
+
|
103
|
+
if (!obj) return results;
|
104
|
+
|
105
|
+
// Use native .map method if it exists:
|
106
|
+
if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
|
107
|
+
|
108
|
+
// Fallback for native .map:
|
109
|
+
for (i = 0, j = obj.length; i < j; i++ ) {
|
110
|
+
results[i] = iterator.call(context, obj[i], i, obj);
|
111
|
+
}
|
112
|
+
return results;
|
113
|
+
}
|
114
|
+
|
115
|
+
/**
|
116
|
+
* Check and normalise the value of precision (must be positive integer)
|
117
|
+
*/
|
118
|
+
function checkPrecision(val, base) {
|
119
|
+
val = Math.round(Math.abs(val));
|
120
|
+
return isNaN(val)? base : val;
|
121
|
+
}
|
122
|
+
|
123
|
+
|
124
|
+
/**
|
125
|
+
* Parses a format string or object and returns format obj for use in rendering
|
126
|
+
*
|
127
|
+
* `format` is either a string with the default (positive) format, or object
|
128
|
+
* containing `pos` (required), `neg` and `zero` values (or a function returning
|
129
|
+
* either a string or object)
|
130
|
+
*
|
131
|
+
* Either string or format.pos must contain "%v" (value) to be valid
|
132
|
+
*/
|
133
|
+
function checkCurrencyFormat(format) {
|
134
|
+
var defaults = lib.settings.currency.format;
|
135
|
+
|
136
|
+
// Allow function as format parameter (should return string or object):
|
137
|
+
if ( typeof format === "function" ) format = format();
|
138
|
+
|
139
|
+
// Format can be a string, in which case `value` ("%v") must be present:
|
140
|
+
if ( isString( format ) && format.match("%v") ) {
|
141
|
+
|
142
|
+
// Create and return positive, negative and zero formats:
|
143
|
+
return {
|
144
|
+
pos : format,
|
145
|
+
neg : format.replace("-", "").replace("%v", "-%v"),
|
146
|
+
zero : format
|
147
|
+
};
|
148
|
+
|
149
|
+
// If no format, or object is missing valid positive value, use defaults:
|
150
|
+
} else if ( !format || !format.pos || !format.pos.match("%v") ) {
|
151
|
+
|
152
|
+
// If defaults is a string, casts it to an object for faster checking next time:
|
153
|
+
return ( !isString( defaults ) ) ? defaults : lib.settings.currency.format = {
|
154
|
+
pos : defaults,
|
155
|
+
neg : defaults.replace("%v", "-%v"),
|
156
|
+
zero : defaults
|
157
|
+
};
|
158
|
+
|
159
|
+
}
|
160
|
+
// Otherwise, assume format was fine:
|
161
|
+
return format;
|
162
|
+
}
|
163
|
+
|
164
|
+
|
165
|
+
/* --- API Methods --- */
|
166
|
+
|
167
|
+
/**
|
168
|
+
* Takes a string/array of strings, removes all formatting/cruft and returns the raw float value
|
169
|
+
* alias: accounting.`parse(string)`
|
170
|
+
*
|
171
|
+
* Decimal must be included in the regular expression to match floats (defaults to
|
172
|
+
* accounting.settings.number.decimal), so if the number uses a non-standard decimal
|
173
|
+
* separator, provide it as the second argument.
|
174
|
+
*
|
175
|
+
* Also matches bracketed negatives (eg. "$ (1.99)" => -1.99)
|
176
|
+
*
|
177
|
+
* Doesn't throw any errors (`NaN`s become 0) but this may change in future
|
178
|
+
*/
|
179
|
+
var unformat = lib.unformat = lib.parse = function(value, decimal) {
|
180
|
+
// Recursively unformat arrays:
|
181
|
+
if (isArray(value)) {
|
182
|
+
return map(value, function(val) {
|
183
|
+
return unformat(val, decimal);
|
184
|
+
});
|
185
|
+
}
|
186
|
+
|
187
|
+
// Fails silently (need decent errors):
|
188
|
+
value = value || 0;
|
189
|
+
|
190
|
+
// Return the value as-is if it's already a number:
|
191
|
+
if (typeof value === "number") return value;
|
192
|
+
|
193
|
+
// Default decimal point comes from settings, but could be set to eg. "," in opts:
|
194
|
+
decimal = decimal || lib.settings.number.decimal;
|
195
|
+
|
196
|
+
// Build regex to strip out everything except digits, decimal point and minus sign:
|
197
|
+
var regex = new RegExp("[^0-9-" + decimal + "]", ["g"]),
|
198
|
+
unformatted = parseFloat(
|
199
|
+
("" + value)
|
200
|
+
.replace(/\((.*)\)/, "-$1") // replace bracketed values with negatives
|
201
|
+
.replace(regex, '') // strip out any cruft
|
202
|
+
.replace(decimal, '.') // make sure decimal point is standard
|
203
|
+
);
|
204
|
+
|
205
|
+
// This will fail silently which may cause trouble, let's wait and see:
|
206
|
+
return !isNaN(unformatted) ? unformatted : 0;
|
207
|
+
};
|
208
|
+
|
209
|
+
|
210
|
+
/**
|
211
|
+
* Implementation of toFixed() that treats floats more like decimals
|
212
|
+
*
|
213
|
+
* Fixes binary rounding issues (eg. (0.615).toFixed(2) === "0.61") that present
|
214
|
+
* problems for accounting- and finance-related software.
|
215
|
+
*/
|
216
|
+
var toFixed = lib.toFixed = function(value, precision) {
|
217
|
+
precision = checkPrecision(precision, lib.settings.number.precision);
|
218
|
+
var power = Math.pow(10, precision);
|
219
|
+
|
220
|
+
// Multiply up by precision, round accurately, then divide and use native toFixed():
|
221
|
+
return (Math.round(lib.unformat(value) * power) / power).toFixed(precision);
|
222
|
+
};
|
223
|
+
|
224
|
+
|
225
|
+
/**
|
226
|
+
* Format a number, with comma-separated thousands and custom precision/decimal places
|
227
|
+
*
|
228
|
+
* Localise by overriding the precision and thousand / decimal separators
|
229
|
+
* 2nd parameter `precision` can be an object matching `settings.number`
|
230
|
+
*/
|
231
|
+
var formatNumber = lib.formatNumber = function(number, precision, thousand, decimal) {
|
232
|
+
// Resursively format arrays:
|
233
|
+
if (isArray(number)) {
|
234
|
+
return map(number, function(val) {
|
235
|
+
return formatNumber(val, precision, thousand, decimal);
|
236
|
+
});
|
237
|
+
}
|
238
|
+
|
239
|
+
// Clean up number:
|
240
|
+
number = unformat(number);
|
241
|
+
|
242
|
+
// Build options object from second param (if object) or all params, extending defaults:
|
243
|
+
var opts = defaults(
|
244
|
+
(isObject(precision) ? precision : {
|
245
|
+
precision : precision,
|
246
|
+
thousand : thousand,
|
247
|
+
decimal : decimal
|
248
|
+
}),
|
249
|
+
lib.settings.number
|
250
|
+
),
|
251
|
+
|
252
|
+
// Clean up precision
|
253
|
+
usePrecision = checkPrecision(opts.precision),
|
254
|
+
|
255
|
+
// Do some calc:
|
256
|
+
negative = number < 0 ? "-" : "",
|
257
|
+
base = parseInt(toFixed(Math.abs(number || 0), usePrecision), 10) + "",
|
258
|
+
mod = base.length > 3 ? base.length % 3 : 0;
|
259
|
+
|
260
|
+
// Format the number:
|
261
|
+
return negative + (mod ? base.substr(0, mod) + opts.thousand : "") + base.substr(mod).replace(/(\d{3})(?=\d)/g, "$1" + opts.thousand) + (usePrecision ? opts.decimal + toFixed(Math.abs(number), usePrecision).split('.')[1] : "");
|
262
|
+
};
|
263
|
+
|
264
|
+
|
265
|
+
/**
|
266
|
+
* Format a number into currency
|
267
|
+
*
|
268
|
+
* Usage: accounting.formatMoney(number, symbol, precision, thousandsSep, decimalSep, format)
|
269
|
+
* defaults: (0, "$", 2, ",", ".", "%s%v")
|
270
|
+
*
|
271
|
+
* Localise by overriding the symbol, precision, thousand / decimal separators and format
|
272
|
+
* Second param can be an object matching `settings.currency` which is the easiest way.
|
273
|
+
*
|
274
|
+
* To do: tidy up the parameters
|
275
|
+
*/
|
276
|
+
var formatMoney = lib.formatMoney = function(number, symbol, precision, thousand, decimal, format) {
|
277
|
+
// Resursively format arrays:
|
278
|
+
if (isArray(number)) {
|
279
|
+
return map(number, function(val){
|
280
|
+
return formatMoney(val, symbol, precision, thousand, decimal, format);
|
281
|
+
});
|
282
|
+
}
|
283
|
+
|
284
|
+
// Clean up number:
|
285
|
+
number = unformat(number);
|
286
|
+
|
287
|
+
// Build options object from second param (if object) or all params, extending defaults:
|
288
|
+
var opts = defaults(
|
289
|
+
(isObject(symbol) ? symbol : {
|
290
|
+
symbol : symbol,
|
291
|
+
precision : precision,
|
292
|
+
thousand : thousand,
|
293
|
+
decimal : decimal,
|
294
|
+
format : format
|
295
|
+
}),
|
296
|
+
lib.settings.currency
|
297
|
+
),
|
298
|
+
|
299
|
+
// Check format (returns object with pos, neg and zero):
|
300
|
+
formats = checkCurrencyFormat(opts.format),
|
301
|
+
|
302
|
+
// Choose which format to use for this value:
|
303
|
+
useFormat = number > 0 ? formats.pos : number < 0 ? formats.neg : formats.zero;
|
304
|
+
|
305
|
+
// Return with currency symbol added:
|
306
|
+
return useFormat.replace('%s', opts.symbol).replace('%v', formatNumber(Math.abs(number), checkPrecision(opts.precision), opts.thousand, opts.decimal));
|
307
|
+
};
|
308
|
+
|
309
|
+
|
310
|
+
/**
|
311
|
+
* Format a list of numbers into an accounting column, padding with whitespace
|
312
|
+
* to line up currency symbols, thousand separators and decimals places
|
313
|
+
*
|
314
|
+
* List should be an array of numbers
|
315
|
+
* Second parameter can be an object containing keys that match the params
|
316
|
+
*
|
317
|
+
* Returns array of accouting-formatted number strings of same length
|
318
|
+
*
|
319
|
+
* NB: `white-space:pre` CSS rule is required on the list container to prevent
|
320
|
+
* browsers from collapsing the whitespace in the output strings.
|
321
|
+
*/
|
322
|
+
lib.formatColumn = function(list, symbol, precision, thousand, decimal, format) {
|
323
|
+
if (!list) return [];
|
324
|
+
|
325
|
+
// Build options object from second param (if object) or all params, extending defaults:
|
326
|
+
var opts = defaults(
|
327
|
+
(isObject(symbol) ? symbol : {
|
328
|
+
symbol : symbol,
|
329
|
+
precision : precision,
|
330
|
+
thousand : thousand,
|
331
|
+
decimal : decimal,
|
332
|
+
format : format
|
333
|
+
}),
|
334
|
+
lib.settings.currency
|
335
|
+
),
|
336
|
+
|
337
|
+
// Check format (returns object with pos, neg and zero), only need pos for now:
|
338
|
+
formats = checkCurrencyFormat(opts.format),
|
339
|
+
|
340
|
+
// Whether to pad at start of string or after currency symbol:
|
341
|
+
padAfterSymbol = formats.pos.indexOf("%s") < formats.pos.indexOf("%v") ? true : false,
|
342
|
+
|
343
|
+
// Store value for the length of the longest string in the column:
|
344
|
+
maxLength = 0,
|
345
|
+
|
346
|
+
// Format the list according to options, store the length of the longest string:
|
347
|
+
formatted = map(list, function(val, i) {
|
348
|
+
if (isArray(val)) {
|
349
|
+
// Recursively format columns if list is a multi-dimensional array:
|
350
|
+
return lib.formatColumn(val, opts);
|
351
|
+
} else {
|
352
|
+
// Clean up the value
|
353
|
+
val = unformat(val);
|
354
|
+
|
355
|
+
// Choose which format to use for this value (pos, neg or zero):
|
356
|
+
var useFormat = val > 0 ? formats.pos : val < 0 ? formats.neg : formats.zero,
|
357
|
+
|
358
|
+
// Format this value, push into formatted list and save the length:
|
359
|
+
fVal = useFormat.replace('%s', opts.symbol).replace('%v', formatNumber(Math.abs(val), checkPrecision(opts.precision), opts.thousand, opts.decimal));
|
360
|
+
|
361
|
+
if (fVal.length > maxLength) maxLength = fVal.length;
|
362
|
+
return fVal;
|
363
|
+
}
|
364
|
+
});
|
365
|
+
|
366
|
+
// Pad each number in the list and send back the column of numbers:
|
367
|
+
return map(formatted, function(val, i) {
|
368
|
+
// Only if this is a string (not a nested array, which would have already been padded):
|
369
|
+
if (isString(val) && val.length < maxLength) {
|
370
|
+
// Depending on symbol position, pad after symbol or at index 0:
|
371
|
+
return padAfterSymbol ? val.replace(opts.symbol, opts.symbol+(new Array(maxLength - val.length + 1).join(" "))) : (new Array(maxLength - val.length + 1).join(" ")) + val;
|
372
|
+
}
|
373
|
+
return val;
|
374
|
+
});
|
375
|
+
};
|
376
|
+
|
377
|
+
|
378
|
+
/* --- Module Definition --- */
|
379
|
+
|
380
|
+
// Export accounting for CommonJS. If being loaded as an AMD module, define it as such.
|
381
|
+
// Otherwise, just add `accounting` to the global object
|
382
|
+
if (typeof exports !== 'undefined') {
|
383
|
+
if (typeof module !== 'undefined' && module.exports) {
|
384
|
+
exports = module.exports = lib;
|
385
|
+
}
|
386
|
+
exports.accounting = lib;
|
387
|
+
} else if (typeof define === 'function' && define.amd) {
|
388
|
+
// Return the library as an AMD module:
|
389
|
+
define('vendor/accounting', [], function() {
|
390
|
+
return lib;
|
391
|
+
});
|
392
|
+
} else {
|
393
|
+
// Use accounting.noConflict to restore `accounting` back to its original value.
|
394
|
+
// Returns a reference to the library's `accounting` object;
|
395
|
+
// e.g. `var numbers = accounting.noConflict();`
|
396
|
+
lib.noConflict = (function(oldAccounting) {
|
397
|
+
return function() {
|
398
|
+
// Reset the value of the root's `accounting` variable:
|
399
|
+
root.accounting = oldAccounting;
|
400
|
+
// Delete the noConflict method:
|
401
|
+
lib.noConflict = undefined;
|
402
|
+
// Return reference to the library to re-assign it:
|
403
|
+
return lib;
|
404
|
+
};
|
405
|
+
})(root.accounting);
|
406
|
+
|
407
|
+
// Declare `fx` on the root (global/window) object:
|
408
|
+
root['accounting'] = lib;
|
409
|
+
}
|
410
|
+
|
411
|
+
// Root will be `window` in browser or `global` on the server:
|
412
|
+
}(this));
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ende
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Heitor Salazar
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-01-
|
11
|
+
date: 2014-01-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -76,7 +76,7 @@ files:
|
|
76
76
|
- lib/assets/javascripts/aura/extensions/mediator.js
|
77
77
|
- lib/assets/javascripts/aura/extensions/models.js.coffee.erb
|
78
78
|
- lib/assets/javascripts/aura/extensions/rivets.js.coffee
|
79
|
-
- lib/assets/javascripts/aura/extensions/rivets
|
79
|
+
- lib/assets/javascripts/aura/extensions/rivets/accounting.js.coffee
|
80
80
|
- lib/assets/javascripts/aura/extensions/rivets/formatters.js.coffee
|
81
81
|
- lib/assets/javascripts/aura/extensions/rivets/formatters.js.coffee~
|
82
82
|
- lib/assets/javascripts/aura/extensions/routes.js.coffee
|
@@ -140,6 +140,7 @@ files:
|
|
140
140
|
- lib/tasks/.gitkeep
|
141
141
|
- vendor/assets/components/ende_build.css
|
142
142
|
- vendor/assets/components/ende_build.js
|
143
|
+
- vendor/assets/javascripts/accounting/accounting.js
|
143
144
|
- vendor/assets/javascripts/ende/build.js
|
144
145
|
- vendor/assets/javascripts/jquery/inputmask.extensions.js
|
145
146
|
- vendor/assets/javascripts/jquery/inputmask.js
|
@@ -1,183 +0,0 @@
|
|
1
|
-
prevent = require 'prevent'
|
2
|
-
|
3
|
-
# # Binding Formatters
|
4
|
-
# dermis provides some default data binding formatters to help you get going as quickly as possible
|
5
|
-
#
|
6
|
-
# The functions below can be used as standard rivets formatters and can be used in combination with one another to do crazy things.
|
7
|
-
|
8
|
-
cfg =
|
9
|
-
preloadData: true
|
10
|
-
formatters:
|
11
|
-
# ### exists
|
12
|
-
# ```data-show="user.name | exists"```
|
13
|
-
#
|
14
|
-
# Returns true or false if the value exists
|
15
|
-
exists: (v) -> v?
|
16
|
-
|
17
|
-
# ### empty
|
18
|
-
# ```data-hide="user.friends | empty"```
|
19
|
-
#
|
20
|
-
# Returns true if the value is non-existent or has a length of zero.
|
21
|
-
empty: (v) -> !(v? and v?.length isnt 0)
|
22
|
-
|
23
|
-
# ### date
|
24
|
-
# ```data-text="user.birthday | date"```
|
25
|
-
#
|
26
|
-
# You must include [moment.js](http://momentjs.com/) on your page to use this. It is not bundled.
|
27
|
-
#
|
28
|
-
# Returns the value date formatted by moment.js
|
29
|
-
date: (v) -> moment(v).format 'MMM DD, YYYY'
|
30
|
-
|
31
|
-
# ### money
|
32
|
-
# ```data-text="user.accountBalance | money"```
|
33
|
-
#
|
34
|
-
# You must include [accounting.js](http://josscrowcroft.github.com/accounting.js/) on your page to use this. It is not bundled.
|
35
|
-
#
|
36
|
-
# Returns the value currency formatted by accounting.js
|
37
|
-
money: (v) -> accounting.formatMoney v
|
38
|
-
|
39
|
-
# ### toNumber
|
40
|
-
# ```data-value="user.sweetText | toNumber"```
|
41
|
-
#
|
42
|
-
# Returns the value converted to a number
|
43
|
-
toNumber: (v) -> +v
|
44
|
-
|
45
|
-
# ### toString
|
46
|
-
# ```data-value="user.sweetNumber | toString"```
|
47
|
-
#
|
48
|
-
# Returns the value converted to a string
|
49
|
-
toString: (v) -> String v
|
50
|
-
|
51
|
-
# ### negate
|
52
|
-
# ```data-show="user.badBoy | exists | negate"```
|
53
|
-
#
|
54
|
-
# Returns the boolean opposite of the value (true=false, false=true)
|
55
|
-
negate: (v) -> !v
|
56
|
-
|
57
|
-
# ### is
|
58
|
-
# ```data-show="user.name | is John"```
|
59
|
-
#
|
60
|
-
# Returns true if the value equals the argument
|
61
|
-
is: (v,a) -> v is a
|
62
|
-
|
63
|
-
# ### isnt
|
64
|
-
# ```data-hide="user.name | isnt John"```
|
65
|
-
#
|
66
|
-
# Returns true if the value doesn't equal the argument
|
67
|
-
isnt: (v,a) -> v isnt a
|
68
|
-
|
69
|
-
# ### gt
|
70
|
-
# ```data-show="user.friends | length | gt 5"```
|
71
|
-
#
|
72
|
-
# Returns true if the value is greater than the argument
|
73
|
-
gt: (v,a) -> v > a
|
74
|
-
|
75
|
-
# ### lt
|
76
|
-
# ```data-hide="user.friends | length | lt 5"```
|
77
|
-
#
|
78
|
-
# Returns true if the value is less than the argument
|
79
|
-
lt: (v,a) -> v < a
|
80
|
-
|
81
|
-
# ### at
|
82
|
-
# ```data-text="user.friends | at 0"```
|
83
|
-
#
|
84
|
-
# Returns the item at the index specified for values
|
85
|
-
at: (v, a) ->
|
86
|
-
return v unless v?
|
87
|
-
return v[parseInt(a)]
|
88
|
-
|
89
|
-
# ### join
|
90
|
-
# ```data-text="user.friends | join ,"```
|
91
|
-
#
|
92
|
-
# Returns the output of value joined by the argument
|
93
|
-
join: (v, a) ->
|
94
|
-
return v unless v?
|
95
|
-
return v.join a
|
96
|
-
|
97
|
-
# ### split
|
98
|
-
# ```data-each-friend="user.friendList | split ,"```
|
99
|
-
#
|
100
|
-
# Returns an array of value split by the argument
|
101
|
-
split: (v, a) ->
|
102
|
-
return v unless v?
|
103
|
-
return v.split a
|
104
|
-
|
105
|
-
# ### prepend
|
106
|
-
# ```data-href="user.name | prepend /users/"```
|
107
|
-
#
|
108
|
-
# Returns a string of argument + value
|
109
|
-
prepend: (v,a...) -> a.join(' ')+v
|
110
|
-
|
111
|
-
# ### append
|
112
|
-
# ```data-href="user.name | prepend /users/ | append /messages"```
|
113
|
-
#
|
114
|
-
# Returns a string of value + argument
|
115
|
-
append: (v,a...) -> v+a.join(' ')
|
116
|
-
|
117
|
-
# ### length
|
118
|
-
# ```data-text="user.friends | length"```
|
119
|
-
#
|
120
|
-
# Returns the length of the value
|
121
|
-
length: (v) ->
|
122
|
-
return v unless v?
|
123
|
-
return v.length
|
124
|
-
|
125
|
-
# ### cancelEvent
|
126
|
-
# ```data-on-submit="user:save | cancelEvent"```
|
127
|
-
#
|
128
|
-
# Extremely useful for preventing forms from submitting but can be used to stop all event propagation.
|
129
|
-
#
|
130
|
-
# Returns a new function wrapping value that stops event propagation.
|
131
|
-
cancelEvent: (v) ->
|
132
|
-
return v unless v?
|
133
|
-
return (e) ->
|
134
|
-
prevent e
|
135
|
-
v.call @, e
|
136
|
-
return false
|
137
|
-
|
138
|
-
# ### sort
|
139
|
-
# ```data-each="movies.models | sort [asc | desc]"```
|
140
|
-
#
|
141
|
-
# Sorts collection in asc or desc order
|
142
|
-
sort: (arr, direction='asc') ->
|
143
|
-
return arr.sort().reverse() if direction is 'desc'
|
144
|
-
return arr.sort()
|
145
|
-
|
146
|
-
# ### sortBy
|
147
|
-
# ```data-each="movies | sortBy field, [asc | desc]"```
|
148
|
-
#
|
149
|
-
# Sorts collection in asc or desc order on a field
|
150
|
-
sortBy: (arr, field, direction='asc') ->
|
151
|
-
reverse = (direction is 'desc')
|
152
|
-
sortFn = (a, b) ->
|
153
|
-
if a[field] < b[field]
|
154
|
-
out = -1
|
155
|
-
else if a[field] > b[field]
|
156
|
-
out = 1
|
157
|
-
else
|
158
|
-
out = 0
|
159
|
-
return out*[1,-1][+!!reverse]
|
160
|
-
|
161
|
-
return arr.sort sortFn
|
162
|
-
|
163
|
-
|
164
|
-
adapter:
|
165
|
-
subscribe: (obj, kp, cb) ->
|
166
|
-
obj.on "change:#{kp}", cb
|
167
|
-
return
|
168
|
-
|
169
|
-
unsubscribe: (obj, kp, cb) ->
|
170
|
-
obj.removeListener "change:#{kp}", cb
|
171
|
-
return
|
172
|
-
|
173
|
-
read: (obj, kp) -> obj.get kp
|
174
|
-
|
175
|
-
publish: (obj, kp, val) ->
|
176
|
-
obj.set kp, val
|
177
|
-
return
|
178
|
-
|
179
|
-
publishers = ["toNumber", "toString"]
|
180
|
-
for k,v of cfg.formatters when publishers.indexOf(k) isnt -1
|
181
|
-
v.publish = v.read = v
|
182
|
-
|
183
|
-
module.exports = cfg
|