pixelforce_cms 0.2

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 (28) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +29 -0
  6. data/Rakefile +1 -0
  7. data/lib/generators/pixelforce_cms/controller_generator.rb +29 -0
  8. data/lib/generators/pixelforce_cms/install_generator.rb +49 -0
  9. data/lib/generators/pixelforce_cms/templates/Gemfile +81 -0
  10. data/lib/generators/pixelforce_cms/templates/admin_controller.rb +39 -0
  11. data/lib/generators/pixelforce_cms/templates/application.html.haml +34 -0
  12. data/lib/generators/pixelforce_cms/templates/base_controller.rb +7 -0
  13. data/lib/generators/pixelforce_cms/templates/css/_variables.css.scss +15 -0
  14. data/lib/generators/pixelforce_cms/templates/css/application/chromeframe.css.scss +14 -0
  15. data/lib/generators/pixelforce_cms/templates/css/application/document.css.scss +0 -0
  16. data/lib/generators/pixelforce_cms/templates/css/application/html5.css.scss +33 -0
  17. data/lib/generators/pixelforce_cms/templates/css/application/media_queries.css.scss +0 -0
  18. data/lib/generators/pixelforce_cms/templates/css/application.css +17 -0
  19. data/lib/generators/pixelforce_cms/templates/css/jasny-bootstrap-responsive.css +170 -0
  20. data/lib/generators/pixelforce_cms/templates/css/jasny-bootstrap.css +1449 -0
  21. data/lib/generators/pixelforce_cms/templates/css/style.css.scss +101 -0
  22. data/lib/generators/pixelforce_cms/templates/css/style.responsive.css.scss +17 -0
  23. data/lib/generators/pixelforce_cms/templates/javascripts/application.js +17 -0
  24. data/lib/generators/pixelforce_cms/templates/javascripts/jasny-bootstrap.js +1119 -0
  25. data/lib/pixelforce_cms/version.rb +3 -0
  26. data/lib/pixelforce_cms.rb +1 -0
  27. data/pixelforce_cms.gemspec +23 -0
  28. metadata +98 -0
@@ -0,0 +1,1119 @@
1
+ /* =============================================================
2
+ * bootstrap-typeahead.js v2.3.1-j6
3
+ * http://twitter.github.com/bootstrap/javascript.html#typeahead
4
+ * =============================================================
5
+ * Copyright 2012 Twitter, Inc.
6
+ *
7
+ * Licensed under the Apache License, Version 2.0 (the "License");
8
+ * you may not use this file except in compliance with the License.
9
+ * You may obtain a copy of the License at
10
+ *
11
+ * http://www.apache.org/licenses/LICENSE-2.0
12
+ *
13
+ * Unless required by applicable law or agreed to in writing, software
14
+ * distributed under the License is distributed on an "AS IS" BASIS,
15
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ * See the License for the specific language governing permissions and
17
+ * limitations under the License.
18
+ * ============================================================ */
19
+
20
+
21
+ !function($){
22
+
23
+ "use strict"; // jshint ;_;
24
+
25
+
26
+ /* TYPEAHEAD PUBLIC CLASS DEFINITION
27
+ * ================================= */
28
+
29
+ var Typeahead = function (element, options) {
30
+ this.$element = $(element)
31
+ this.options = $.extend({}, $.fn.typeahead.defaults, options)
32
+ if (this.options.target) this.$target = $(this.options.target)
33
+ this.matcher = this.options.matcher || this.matcher
34
+ this.sorter = this.options.sorter || this.sorter
35
+ this.highlighter = this.options.highlighter || this.highlighter
36
+ this.updater = this.options.updater || this.updater
37
+ this.source = this.options.source
38
+ this.strict = this.options.strict
39
+ this.$menu = $(this.options.menu)
40
+ this.shown = false
41
+
42
+ if (typeof this.source == 'string') {
43
+ this.url = this.source
44
+ this.source = this.searchAjax
45
+ }
46
+
47
+ if (element.nodeName == 'SELECT') this.replaceSelect()
48
+
49
+ this.text = this.$element.val()
50
+
51
+ this.$element
52
+ .attr('data-text', this.value)
53
+ .attr('autocomplete', "off")
54
+
55
+ if (typeof this.$target != 'undefined') this.$element.attr('data-value', this.$target.val())
56
+ else if (typeof this.$element.attr('data-value') == 'undefined') this.$element.attr('data-value', this.strict ? '' : this.value)
57
+
58
+ this.$menu.css('min-width', this.$element.width() + 12)
59
+
60
+ this.listen()
61
+ }
62
+
63
+ Typeahead.prototype = {
64
+
65
+ constructor: Typeahead
66
+
67
+ , replaceSelect: function () {
68
+ this.$target = this.$element
69
+ this.$element = $('<input type="text" />')
70
+
71
+ this.source = {}
72
+ this.strict = true
73
+
74
+ var options = this.$target.find('option')
75
+ var $option;
76
+ for (var i=0; i<options.length; i++) {
77
+ $option = $(options[i]);
78
+ if ($option.val() === '') {
79
+ this.$element.attr('placeholder', $option.html());
80
+ continue;
81
+ }
82
+
83
+ this.source[$option.val()] = $option.html()
84
+ if (this.$target.val() == $option.val()) this.$element.val($option.html())
85
+ }
86
+
87
+ var attr = this.$target[0].attributes
88
+ for (i=0; i<attr.length; i++) {
89
+ if (attr[i].nodeName != 'type' && attr[i].nodeName != 'name' && attr[i].nodeName != 'id' && attr[i].nodeName != 'data-provide' && !attr[i].nodeName.match(/^on/)) {
90
+ this.$element.attr(attr[i].nodeName, attr[i].nodeValue)
91
+ }
92
+ }
93
+
94
+ this.$element.insertAfter(this.$target)
95
+ if (this.$target.attr('autofocus')) this.$element.trigger('focus').select()
96
+ this.$target.attr('autofocus', false)
97
+ this.$target.hide()
98
+ }
99
+
100
+ , destroyReplacement: function () {
101
+ // Detroy replacement element, so it doesn't mess up the browsers autofill on refresh
102
+ if (typeof this.$target != 'undefined' && this.$target[0].nodeName == 'SELECT') {
103
+ this.$element.replaceWith('');
104
+ }
105
+ }
106
+
107
+ , select: function () {
108
+ var li = this.$menu.find('.active')
109
+ , val = li.attr('data-value')
110
+ , text = li.find('.item-text').length > 0 ? li.find('.item-text').text() : li.text()
111
+
112
+ val = this.updater(val, 'value')
113
+ text = this.updater(text, 'text')
114
+
115
+ this.$element
116
+ .val(text)
117
+ .attr('data-value', val)
118
+
119
+ this.text = text
120
+
121
+ if (typeof this.$target != 'undefined') {
122
+ this.$target
123
+ .val(val)
124
+ .trigger('change')
125
+ }
126
+
127
+ this.$element.trigger('change')
128
+
129
+ return this.hide()
130
+ }
131
+
132
+ , updater: function (text, type) {
133
+ return text
134
+ }
135
+
136
+ , show: function () {
137
+ var pos = $.extend({}, this.$element.position(), {
138
+ height: this.$element[0].offsetHeight
139
+ })
140
+
141
+ this.$menu
142
+ .insertAfter(this.$element)
143
+ .css({
144
+ top: pos.top + pos.height
145
+ , left: pos.left
146
+ })
147
+ .show()
148
+
149
+ this.shown = true
150
+ return this
151
+ }
152
+
153
+ , hide: function () {
154
+ this.$menu.hide()
155
+ this.shown = false
156
+ return this
157
+ }
158
+
159
+ , lookup: function (event) {
160
+ var items
161
+
162
+ this.query = this.$element.val()
163
+
164
+ if (!this.query || this.query.length < this.options.minLength) {
165
+ return this.shown ? this.hide() : this
166
+ }
167
+
168
+ items = $.isFunction(this.source) ? this.source(this.query, $.proxy(this.process, this)) : this.source
169
+
170
+ return items ? this.process(items) : this
171
+ }
172
+
173
+ , process: function (items) {
174
+ return $.isArray(items) ? this.processArray(items) : this.processObject(items)
175
+ }
176
+
177
+ , processArray: function (items) {
178
+ var that = this
179
+
180
+ items = $.grep(items, function (item) {
181
+ return that.matcher(item)
182
+ })
183
+
184
+ items = this.sorter(items)
185
+
186
+ if (!items.length) {
187
+ return this.shown ? this.hide() : this
188
+ }
189
+
190
+ return this.render(items.slice(0, this.options.items)).show()
191
+ }
192
+
193
+ , processObject: function (itemsIn) {
194
+ var that = this
195
+ , items = {}
196
+ , i = 0
197
+
198
+ $.each(itemsIn, function (key, item) {
199
+ if (that.matcher(item)) items[key] = item
200
+ })
201
+
202
+ items = this.sorter(items)
203
+
204
+ if ($.isEmptyObject(items)) {
205
+ return this.shown ? this.hide() : this
206
+ }
207
+
208
+ $.each(items, function(key, item) {
209
+ if (i++ >= that.options.items) delete items[key]
210
+ })
211
+
212
+ return this.render(items).show()
213
+ }
214
+
215
+ , searchAjax: function (query, process) {
216
+ var that = this
217
+
218
+ if (this.ajaxTimeout) clearTimeout(this.ajaxTimeout)
219
+
220
+ this.ajaxTimeout = setTimeout(function () {
221
+ if (that.ajaxTimeout) clearTimeout(that.ajaxTimeout)
222
+
223
+ if (query === "") {
224
+ that.hide()
225
+ return
226
+ }
227
+
228
+ $.get(that.url, {'q': query, 'limit': that.options.items }, function (items) {
229
+ if (typeof items == 'string') items = JSON.parse(items)
230
+ process(items)
231
+ })
232
+ }, this.options.ajaxdelay)
233
+ }
234
+
235
+ , matcher: function (item) {
236
+ return ~item.toLowerCase().indexOf(this.query.toLowerCase())
237
+ }
238
+
239
+ , sorter: function (items) {
240
+ return $.isArray(items) ? this.sortArray(items) : this.sortObject(items)
241
+ }
242
+
243
+ , sortArray: function (items) {
244
+ var beginswith = []
245
+ , caseSensitive = []
246
+ , caseInsensitive = []
247
+ , item
248
+
249
+ while (item = items.shift()) {
250
+ if (!item.toLowerCase().indexOf(this.query.toLowerCase())) beginswith.push(item)
251
+ else if (~item.indexOf(this.query)) caseSensitive.push(item)
252
+ else caseInsensitive.push(item)
253
+ }
254
+
255
+ return beginswith.concat(caseSensitive, caseInsensitive)
256
+ }
257
+
258
+ , sortObject: function (items) {
259
+ var sorted = {}
260
+ , key;
261
+
262
+ for (key in items) {
263
+ if (!items[key].toLowerCase().indexOf(this.query.toLowerCase())) {
264
+ sorted[key] = items[key];
265
+ delete items[key]
266
+ }
267
+ }
268
+
269
+ for (key in items) {
270
+ if (~items[key].indexOf(this.query)) {
271
+ sorted[key] = items[key];
272
+ delete items[key]
273
+ }
274
+ }
275
+
276
+ for (key in items) {
277
+ sorted[key] = items[key]
278
+ }
279
+
280
+ return sorted
281
+ }
282
+
283
+ , highlighter: function (item) {
284
+ var query = this.query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&')
285
+ return item.replace(new RegExp('(' + query + ')', 'ig'), function ($1, match) {
286
+ return '<strong>' + match + '</strong>'
287
+ })
288
+ }
289
+
290
+ , render: function (items) {
291
+ var that = this
292
+ , list = $([])
293
+
294
+ $.map(items, function (item, value) {
295
+ if (list.length >= that.options.items) return
296
+
297
+ var li
298
+ , a
299
+
300
+ if ($.isArray(items)) value = item
301
+
302
+ li = $(that.options.item)
303
+ a = li.find('a').length ? li.find('a') : li
304
+ a.html(that.highlighter(item))
305
+
306
+ li.attr('data-value', value)
307
+ if (li.find('a').length === 0) li.addClass('dropdown-header')
308
+
309
+ list.push(li[0])
310
+ })
311
+
312
+ list.not('.dropdown-header').first().addClass('active')
313
+
314
+ this.$menu.html(list)
315
+
316
+ return this
317
+ }
318
+
319
+ , next: function (event) {
320
+ var active = this.$menu.find('.active').removeClass('active')
321
+ , next = active.nextAll('li:not(.dropdown-header)').first()
322
+
323
+ if (!next.length) {
324
+ next = $(this.$menu.find('li:not(.dropdown-header)')[0])
325
+ }
326
+
327
+ next.addClass('active')
328
+ }
329
+
330
+ , prev: function (event) {
331
+ var active = this.$menu.find('.active').removeClass('active')
332
+ , prev = active.prevAll('li:not(.dropdown-header)').first()
333
+
334
+ if (!prev.length) {
335
+ prev = this.$menu.find('li:not(.dropdown-header)').last()
336
+ }
337
+
338
+ prev.addClass('active')
339
+ }
340
+
341
+ , listen: function () {
342
+ this.$element
343
+ .on('focus', $.proxy(this.focus, this))
344
+ .on('blur', $.proxy(this.blur, this))
345
+ .on('change', $.proxy(this.change, this))
346
+ .on('keypress', $.proxy(this.keypress, this))
347
+ .on('keyup', $.proxy(this.keyup, this))
348
+
349
+ if (this.eventSupported('keydown')) {
350
+ this.$element.on('keydown', $.proxy(this.keydown, this))
351
+ }
352
+
353
+ this.$menu
354
+ .on('click', $.proxy(this.click, this))
355
+ .on('mouseenter', 'li', $.proxy(this.mouseenter, this))
356
+ .on('mouseleave', 'li', $.proxy(this.mouseleave, this))
357
+
358
+ $(window).on('unload', $.proxy(this.destroyReplacement, this))
359
+ }
360
+
361
+ , eventSupported: function(eventName) {
362
+ var isSupported = eventName in this.$element
363
+ if (!isSupported) {
364
+ this.$element.setAttribute(eventName, 'return;')
365
+ isSupported = typeof this.$element[eventName] === 'function'
366
+ }
367
+ return isSupported
368
+ }
369
+
370
+ , move: function (e) {
371
+ if (!this.shown) return
372
+
373
+ switch(e.keyCode) {
374
+ case 9: // tab
375
+ case 13: // enter
376
+ case 27: // escape
377
+ e.preventDefault()
378
+ break
379
+
380
+ case 38: // up arrow
381
+ e.preventDefault()
382
+ this.prev()
383
+ break
384
+
385
+ case 40: // down arrow
386
+ e.preventDefault()
387
+ this.next()
388
+ break
389
+ }
390
+
391
+ e.stopPropagation()
392
+ }
393
+
394
+ , keydown: function (e) {
395
+ this.suppressKeyPressRepeat = ~$.inArray(e.keyCode, [40,38,9,13,27])
396
+ this.move(e)
397
+ }
398
+
399
+ , keypress: function (e) {
400
+ if (this.suppressKeyPressRepeat) return
401
+ this.move(e)
402
+ }
403
+
404
+ , keyup: function (e) {
405
+ switch(e.keyCode) {
406
+ case 40: // down arrow
407
+ case 38: // up arrow
408
+ case 16: // shift
409
+ case 17: // ctrl
410
+ case 18: // alt
411
+ break
412
+
413
+ case 9: // tab
414
+ case 13: // enter
415
+ if (!this.shown) return
416
+ this.select()
417
+ break
418
+
419
+ case 27: // escape
420
+ if (!this.shown) return
421
+ this.hide()
422
+ break
423
+
424
+ default:
425
+ this.lookup()
426
+ }
427
+
428
+ e.stopPropagation()
429
+ e.preventDefault()
430
+ }
431
+
432
+ , change: function (e) {
433
+ var value
434
+
435
+ if (this.$element.val() != this.text) {
436
+ value = this.$element.val() === '' || this.strict ? '' : this.$element.val()
437
+
438
+ this.$element.val(value)
439
+ this.$element.attr('data-value', value)
440
+ this.text = value
441
+ if (typeof this.$target != 'undefined') this.$target.val(value)
442
+ }
443
+ }
444
+
445
+ , focus: function (e) {
446
+ this.focused = true
447
+ }
448
+
449
+ , blur: function (e) {
450
+ this.focused = false
451
+ if (!this.mousedover && this.shown) this.hide()
452
+ }
453
+
454
+ , click: function (e) {
455
+ e.stopPropagation()
456
+ e.preventDefault()
457
+ this.select()
458
+ this.$element.focus()
459
+ }
460
+
461
+ , mouseenter: function (e) {
462
+ this.mousedover = true
463
+ this.$menu.find('.active').removeClass('active')
464
+ $(e.currentTarget).addClass('active')
465
+ }
466
+
467
+ , mouseleave: function (e) {
468
+ this.mousedover = false
469
+ if (!this.focused && this.shown) this.hide()
470
+ }
471
+
472
+ }
473
+
474
+
475
+ /* TYPEAHEAD PLUGIN DEFINITION
476
+ * =========================== */
477
+
478
+ var old = $.fn.typeahead
479
+
480
+ $.fn.typeahead = function (option) {
481
+ return this.each(function () {
482
+ var $this = $(this)
483
+ , data = $this.data('typeahead')
484
+ , options = typeof option == 'object' && option
485
+ if (!data) $this.data('typeahead', (data = new Typeahead(this, options)))
486
+ if (typeof option == 'string') data[option]()
487
+ })
488
+ }
489
+
490
+ $.fn.typeahead.defaults = {
491
+ source: []
492
+ , items: 8
493
+ , menu: '<ul class="typeahead dropdown-menu"></ul>'
494
+ , item: '<li><a href="#"></a></li>'
495
+ , ajaxdelay: 400
496
+ , minLength: 1
497
+ }
498
+
499
+ $.fn.typeahead.Constructor = Typeahead
500
+
501
+
502
+ /* TYPEAHEAD NO CONFLICT
503
+ * =================== */
504
+
505
+ $.fn.typeahead.noConflict = function () {
506
+ $.fn.typeahead = old
507
+ return this
508
+ }
509
+
510
+
511
+ /* TYPEAHEAD DATA-API
512
+ * ================== */
513
+
514
+ $(document)
515
+ .off('focus.typeahead.data-api') // overwriting Twitter's typeahead
516
+ .on('focus.typeahead.data-api', '[data-provide="typeahead"]', function (e) {
517
+ var $this = $(this)
518
+ if ($this.data('typeahead')) return
519
+ if ($this.is('select')) $this.attr('autofocus', true)
520
+ e.preventDefault()
521
+ $this.typeahead($this.data())
522
+ })
523
+
524
+ }(window.jQuery);
525
+ /* ===========================================================
526
+ * bootstrap-inputmask.js j2
527
+ * http://twitter.github.com/bootstrap/javascript.html#tooltips
528
+ * Based on Masked Input plugin by Josh Bush (digitalbush.com)
529
+ * ===========================================================
530
+ * Copyright 2012 Jasny BV, Netherlands.
531
+ *
532
+ * Licensed under the Apache License, Version 2.0 (the "License")
533
+ * you may not use this file except in compliance with the License.
534
+ * You may obtain a copy of the License at
535
+ *
536
+ * http://www.apache.org/licenses/LICENSE-2.0
537
+ *
538
+ * Unless required by applicable law or agreed to in writing, software
539
+ * distributed under the License is distributed on an "AS IS" BASIS,
540
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
541
+ * See the License for the specific language governing permissions and
542
+ * limitations under the License.
543
+ * ========================================================== */
544
+
545
+ !function ($) {
546
+
547
+ "use strict"; // jshint ;_;
548
+
549
+ var isIphone = (window.orientation !== undefined),
550
+ isAndroid = navigator.userAgent.toLowerCase().indexOf("android") > -1
551
+
552
+
553
+ /* INPUTMASK PUBLIC CLASS DEFINITION
554
+ * ================================= */
555
+
556
+ var Inputmask = function (element, options) {
557
+ if (isAndroid) return // No support because caret positioning doesn't work on Android
558
+
559
+ this.$element = $(element)
560
+ this.options = $.extend({}, $.fn.inputmask.defaults, options)
561
+ this.mask = String(options.mask)
562
+
563
+ this.init()
564
+ this.listen()
565
+
566
+ this.checkVal() //Perform initial check for existing values
567
+ }
568
+
569
+ Inputmask.prototype = {
570
+
571
+ init: function() {
572
+ var defs = this.options.definitions
573
+ var len = this.mask.length
574
+
575
+ this.tests = []
576
+ this.partialPosition = this.mask.length
577
+ this.firstNonMaskPos = null
578
+
579
+ $.each(this.mask.split(""), $.proxy(function(i, c) {
580
+ if (c == '?') {
581
+ len--
582
+ this.partialPosition = i
583
+ } else if (defs[c]) {
584
+ this.tests.push(new RegExp(defs[c]))
585
+ if(this.firstNonMaskPos === null)
586
+ this.firstNonMaskPos = this.tests.length - 1
587
+ } else {
588
+ this.tests.push(null)
589
+ }
590
+ }, this))
591
+
592
+ this.buffer = $.map(this.mask.split(""), $.proxy(function(c, i) {
593
+ if (c != '?') return defs[c] ? this.options.placeholder : c
594
+ }, this))
595
+
596
+ this.focusText = this.$element.val()
597
+
598
+ this.$element.data("rawMaskFn", $.proxy(function() {
599
+ return $.map(this.buffer, function(c, i) {
600
+ return this.tests[i] && c != this.options.placeholder ? c : null
601
+ }).join('')
602
+ }, this))
603
+ },
604
+
605
+ listen: function() {
606
+ if (this.$element.attr("readonly")) return
607
+
608
+ var pasteEventName = (navigator.userAgent.match(/msie/i) ? 'paste' : 'input') + ".mask"
609
+
610
+ this.$element
611
+ .on("unmask", $.proxy(this.unmask, this))
612
+
613
+ .on("focus.mask", $.proxy(this.focusEvent, this))
614
+ .on("blur.mask", $.proxy(this.blurEvent, this))
615
+
616
+ .on("keydown.mask", $.proxy(this.keydownEvent, this))
617
+ .on("keypress.mask", $.proxy(this.keypressEvent, this))
618
+
619
+ .on(pasteEventName, $.proxy(this.pasteEvent, this))
620
+ },
621
+
622
+ //Helper Function for Caret positioning
623
+ caret: function(begin, end) {
624
+ if (this.$element.length === 0) return
625
+ if (typeof begin == 'number') {
626
+ end = (typeof end == 'number') ? end : begin
627
+ return this.$element.each(function() {
628
+ if (this.setSelectionRange) {
629
+ this.setSelectionRange(begin, end)
630
+ } else if (this.createTextRange) {
631
+ var range = this.createTextRange()
632
+ range.collapse(true)
633
+ range.moveEnd('character', end)
634
+ range.moveStart('character', begin)
635
+ range.select()
636
+ }
637
+ })
638
+ } else {
639
+ if (this.$element[0].setSelectionRange) {
640
+ begin = this.$element[0].selectionStart
641
+ end = this.$element[0].selectionEnd
642
+ } else if (document.selection && document.selection.createRange) {
643
+ var range = document.selection.createRange()
644
+ begin = 0 - range.duplicate().moveStart('character', -100000)
645
+ end = begin + range.text.length
646
+ }
647
+ return {
648
+ begin: begin,
649
+ end: end
650
+ }
651
+ }
652
+ },
653
+
654
+ seekNext: function(pos) {
655
+ var len = this.mask.length
656
+ while (++pos <= len && !this.tests[pos]);
657
+
658
+ return pos
659
+ },
660
+
661
+ seekPrev: function(pos) {
662
+ while (--pos >= 0 && !this.tests[pos]);
663
+
664
+ return pos
665
+ },
666
+
667
+ shiftL: function(begin,end) {
668
+ var len = this.mask.length
669
+
670
+ if(begin<0) return
671
+
672
+ for (var i = begin,j = this.seekNext(end); i < len; i++) {
673
+ if (this.tests[i]) {
674
+ if (j < len && this.tests[i].test(this.buffer[j])) {
675
+ this.buffer[i] = this.buffer[j]
676
+ this.buffer[j] = this.options.placeholder
677
+ } else
678
+ break
679
+ j = this.seekNext(j)
680
+ }
681
+ }
682
+ this.writeBuffer()
683
+ this.caret(Math.max(this.firstNonMaskPos, begin))
684
+ },
685
+
686
+ shiftR: function(pos) {
687
+ var len = this.mask.length
688
+
689
+ for (var i = pos, c = this.options.placeholder; i < len; i++) {
690
+ if (this.tests[i]) {
691
+ var j = this.seekNext(i)
692
+ var t = this.buffer[i]
693
+ this.buffer[i] = c
694
+ if (j < len && this.tests[j].test(t))
695
+ c = t
696
+ else
697
+ break
698
+ }
699
+ }
700
+ },
701
+
702
+ unmask: function() {
703
+ this.$element
704
+ .unbind(".mask")
705
+ .removeData("inputmask")
706
+ },
707
+
708
+ focusEvent: function() {
709
+ this.focusText = this.$element.val()
710
+ var len = this.mask.length
711
+ var pos = this.checkVal()
712
+ this.writeBuffer()
713
+
714
+ var that = this
715
+ var moveCaret = function() {
716
+ if (pos == len)
717
+ that.caret(0, pos)
718
+ else
719
+ that.caret(pos)
720
+ }
721
+
722
+ if ($.browser.msie)
723
+ moveCaret()
724
+ else
725
+ setTimeout(moveCaret, 0)
726
+ },
727
+
728
+ blurEvent: function() {
729
+ this.checkVal()
730
+ if (this.$element.val() != this.focusText)
731
+ this.$element.trigger('change')
732
+ },
733
+
734
+ keydownEvent: function(e) {
735
+ var k=e.which
736
+
737
+ //backspace, delete, and escape get special treatment
738
+ if (k == 8 || k == 46 || (isIphone && k == 127)) {
739
+ var pos = this.caret(),
740
+ begin = pos.begin,
741
+ end = pos.end
742
+
743
+ if (end-begin === 0) {
744
+ begin = k!=46 ? this.seekPrev(begin) : (end=this.seekNext(begin-1))
745
+ end = k==46 ? this.seekNext(end) : end
746
+ }
747
+ this.clearBuffer(begin, end)
748
+ this.shiftL(begin,end-1)
749
+
750
+ return false
751
+ } else if (k == 27) {//escape
752
+ this.$element.val(this.focusText)
753
+ this.caret(0, this.checkVal())
754
+ return false
755
+ }
756
+ },
757
+
758
+ keypressEvent: function(e) {
759
+ var len = this.mask.length
760
+
761
+ var k = e.which,
762
+ pos = this.caret()
763
+
764
+ if (e.ctrlKey || e.altKey || e.metaKey || k<32) {//Ignore
765
+ return true
766
+ } else if (k) {
767
+ if (pos.end - pos.begin !== 0) {
768
+ this.clearBuffer(pos.begin, pos.end)
769
+ this.shiftL(pos.begin, pos.end-1)
770
+ }
771
+
772
+ var p = this.seekNext(pos.begin - 1)
773
+ if (p < len) {
774
+ var c = String.fromCharCode(k)
775
+ if (this.tests[p].test(c)) {
776
+ this.shiftR(p)
777
+ this.buffer[p] = c
778
+ this.writeBuffer()
779
+ var next = this.seekNext(p)
780
+ this.caret(next)
781
+ }
782
+ }
783
+ return false
784
+ }
785
+ },
786
+
787
+ pasteEvent: function() {
788
+ var that = this
789
+
790
+ setTimeout(function() {
791
+ that.caret(that.checkVal(true))
792
+ }, 0)
793
+ },
794
+
795
+ clearBuffer: function(start, end) {
796
+ var len = this.mask.length
797
+
798
+ for (var i = start; i < end && i < len; i++) {
799
+ if (this.tests[i])
800
+ this.buffer[i] = this.options.placeholder
801
+ }
802
+ },
803
+
804
+ writeBuffer: function() {
805
+ return this.$element.val(this.buffer.join('')).val()
806
+ },
807
+
808
+ checkVal: function(allow) {
809
+ var len = this.mask.length
810
+ //try to place characters where they belong
811
+ var test = this.$element.val()
812
+ var lastMatch = -1
813
+
814
+ for (var i = 0, pos = 0; i < len; i++) {
815
+ if (this.tests[i]) {
816
+ this.buffer[i] = this.options.placeholder
817
+ while (pos++ < test.length) {
818
+ var c = test.charAt(pos - 1)
819
+ if (this.tests[i].test(c)) {
820
+ this.buffer[i] = c
821
+ lastMatch = i
822
+ break
823
+ }
824
+ }
825
+ if (pos > test.length)
826
+ break
827
+ } else if (this.buffer[i] == test.charAt(pos) && i != this.partialPosition) {
828
+ pos++
829
+ lastMatch = i
830
+ }
831
+ }
832
+ if (!allow && lastMatch + 1 < this.partialPosition) {
833
+ this.$element.val("")
834
+ this.clearBuffer(0, len)
835
+ } else if (allow || lastMatch + 1 >= this.partialPosition) {
836
+ this.writeBuffer()
837
+ if (!allow) this.$element.val(this.$element.val().substring(0, lastMatch + 1))
838
+ }
839
+ return (this.partialPosition ? i : this.firstNonMaskPos)
840
+ }
841
+ }
842
+
843
+
844
+ /* INPUTMASK PLUGIN DEFINITION
845
+ * =========================== */
846
+
847
+ $.fn.inputmask = function (options) {
848
+ return this.each(function () {
849
+ var $this = $(this)
850
+ , data = $this.data('inputmask')
851
+ if (!data) $this.data('inputmask', (data = new Inputmask(this, options)))
852
+ })
853
+ }
854
+
855
+ $.fn.inputmask.defaults = {
856
+ mask: "",
857
+ placeholder: "_",
858
+ definitions: {
859
+ '9': "[0-9]",
860
+ 'a': "[A-Za-z]",
861
+ '?': "[A-Za-z0-9]",
862
+ '*': "."
863
+ }
864
+ }
865
+
866
+ $.fn.inputmask.Constructor = Inputmask
867
+
868
+
869
+ /* INPUTMASK DATA-API
870
+ * ================== */
871
+
872
+ $(document).on('focus.inputmask.data-api', '[data-mask]', function (e) {
873
+ var $this = $(this)
874
+ if ($this.data('inputmask')) return
875
+ e.preventDefault()
876
+ $this.inputmask($this.data())
877
+ })
878
+
879
+ }(window.jQuery);
880
+ /* ============================================================
881
+ * bootstrap-rowlink.js j1
882
+ * http://jasny.github.com/bootstrap/javascript.html#rowlink
883
+ * ============================================================
884
+ * Copyright 2012 Jasny BV, Netherlands.
885
+ *
886
+ * Licensed under the Apache License, Version 2.0 (the "License");
887
+ * you may not use this file except in compliance with the License.
888
+ * You may obtain a copy of the License at
889
+ *
890
+ * http://www.apache.org/licenses/LICENSE-2.0
891
+ *
892
+ * Unless required by applicable law or agreed to in writing, software
893
+ * distributed under the License is distributed on an "AS IS" BASIS,
894
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
895
+ * See the License for the specific language governing permissions and
896
+ * limitations under the License.
897
+ * ============================================================ */
898
+
899
+ !function ($) {
900
+
901
+ "use strict"; // jshint ;_;
902
+
903
+ var Rowlink = function (element, options) {
904
+ options = $.extend({}, $.fn.rowlink.defaults, options)
905
+ var tr = element.nodeName.toLowerCase() == 'tr' ? $(element) : $(element).find('tr:has(td)')
906
+
907
+ tr.each(function() {
908
+ var link = $(this).find(options.target).first()
909
+ if (!link.length) return
910
+
911
+ var href = link.attr('href')
912
+
913
+ $(this).find('td').not('.nolink').click(function() {
914
+ window.location = href;
915
+ })
916
+
917
+ $(this).addClass('rowlink')
918
+ link.replaceWith(link.html())
919
+ })
920
+ }
921
+
922
+
923
+ /* ROWLINK PLUGIN DEFINITION
924
+ * =========================== */
925
+
926
+ $.fn.rowlink = function (options) {
927
+ return this.each(function () {
928
+ var $this = $(this)
929
+ , data = $this.data('rowlink')
930
+ if (!data) $this.data('rowlink', (data = new Rowlink(this, options)))
931
+ })
932
+ }
933
+
934
+ $.fn.rowlink.defaults = {
935
+ target: "a"
936
+ }
937
+
938
+ $.fn.rowlink.Constructor = Rowlink
939
+
940
+
941
+ /* ROWLINK DATA-API
942
+ * ================== */
943
+
944
+ $(function () {
945
+ $('[data-provide="rowlink"],[data-provides="rowlink"]').each(function () {
946
+ $(this).rowlink($(this).data())
947
+ })
948
+ })
949
+
950
+ }(window.jQuery);
951
+ /* ===========================================================
952
+ * bootstrap-fileupload.js j2
953
+ * http://jasny.github.com/bootstrap/javascript.html#fileupload
954
+ * ===========================================================
955
+ * Copyright 2012 Jasny BV, Netherlands.
956
+ *
957
+ * Licensed under the Apache License, Version 2.0 (the "License")
958
+ * you may not use this file except in compliance with the License.
959
+ * You may obtain a copy of the License at
960
+ *
961
+ * http://www.apache.org/licenses/LICENSE-2.0
962
+ *
963
+ * Unless required by applicable law or agreed to in writing, software
964
+ * distributed under the License is distributed on an "AS IS" BASIS,
965
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
966
+ * See the License for the specific language governing permissions and
967
+ * limitations under the License.
968
+ * ========================================================== */
969
+
970
+ !function ($) {
971
+
972
+ "use strict"; // jshint ;_
973
+
974
+ /* FILEUPLOAD PUBLIC CLASS DEFINITION
975
+ * ================================= */
976
+
977
+ var Fileupload = function (element, options) {
978
+ this.$element = $(element)
979
+ this.type = this.$element.data('uploadtype') || (this.$element.find('.thumbnail').length > 0 ? "image" : "file")
980
+
981
+ this.$input = this.$element.find(':file')
982
+ if (this.$input.length === 0) return
983
+
984
+ this.name = this.$input.attr('name') || options.name
985
+
986
+ this.$hidden = this.$element.find('input[type=hidden][name="'+this.name+'"]')
987
+ if (this.$hidden.length === 0) {
988
+ this.$hidden = $('<input type="hidden" />')
989
+ this.$element.prepend(this.$hidden)
990
+ }
991
+
992
+ this.$preview = this.$element.find('.fileupload-preview')
993
+ var height = this.$preview.css('height')
994
+ if (this.$preview.css('display') != 'inline' && height != '0px' && height != 'none') this.$preview.css('line-height', height)
995
+
996
+ this.original = {
997
+ 'exists': this.$element.hasClass('fileupload-exists'),
998
+ 'preview': this.$preview.html(),
999
+ 'hiddenVal': this.$hidden.val()
1000
+ }
1001
+
1002
+ this.$remove = this.$element.find('[data-dismiss="fileupload"]')
1003
+
1004
+ this.$element.find('[data-trigger="fileupload"]').on('click.fileupload', $.proxy(this.trigger, this))
1005
+
1006
+ this.listen()
1007
+ }
1008
+
1009
+ Fileupload.prototype = {
1010
+
1011
+ listen: function() {
1012
+ this.$input.on('change.fileupload', $.proxy(this.change, this))
1013
+ $(this.$input[0].form).on('reset.fileupload', $.proxy(this.reset, this))
1014
+ if (this.$remove) this.$remove.on('click.fileupload', $.proxy(this.clear, this))
1015
+ },
1016
+
1017
+ change: function(e, invoked) {
1018
+ if (invoked === 'clear') return
1019
+
1020
+ var file = e.target.files !== undefined ? e.target.files[0] : (e.target.value ? { name: e.target.value.replace(/^.+\\/, '') } : null)
1021
+
1022
+ if (!file) {
1023
+ this.clear()
1024
+ return
1025
+ }
1026
+
1027
+ this.$hidden.val('')
1028
+ this.$hidden.attr('name', '')
1029
+ this.$input.attr('name', this.name)
1030
+
1031
+ if (this.type === "image" && this.$preview.length > 0 && (typeof file.type !== "undefined" ? file.type.match('image.*') : file.name.match(/\.(gif|png|jpe?g)$/i)) && typeof FileReader !== "undefined") {
1032
+ var reader = new FileReader()
1033
+ var preview = this.$preview
1034
+ var element = this.$element
1035
+
1036
+ reader.onload = function(e) {
1037
+ preview.html('<img src="' + e.target.result + '" ' + (preview.css('max-height') != 'none' ? 'style="max-height: ' + preview.css('max-height') + ';"' : '') + ' />')
1038
+ element.addClass('fileupload-exists').removeClass('fileupload-new')
1039
+ }
1040
+
1041
+ reader.readAsDataURL(file)
1042
+ } else {
1043
+ this.$preview.text(file.name)
1044
+ this.$element.addClass('fileupload-exists').removeClass('fileupload-new')
1045
+ }
1046
+ },
1047
+
1048
+ clear: function(e) {
1049
+ this.$hidden.val('')
1050
+ this.$hidden.attr('name', this.name)
1051
+ this.$input.attr('name', '')
1052
+
1053
+ //ie8+ doesn't support changing the value of input with type=file so clone instead
1054
+ if (navigator.userAgent.match(/msie/i)){
1055
+ var inputClone = this.$input.clone(true);
1056
+ this.$input.after(inputClone);
1057
+ this.$input.remove();
1058
+ this.$input = inputClone;
1059
+ }else{
1060
+ this.$input.val('')
1061
+ }
1062
+
1063
+ this.$preview.html('')
1064
+ this.$element.addClass('fileupload-new').removeClass('fileupload-exists')
1065
+
1066
+ if (e) {
1067
+ this.$input.trigger('change', [ 'clear' ])
1068
+ e.preventDefault()
1069
+ }
1070
+ },
1071
+
1072
+ reset: function(e) {
1073
+ this.clear()
1074
+
1075
+ this.$hidden.val(this.original.hiddenVal)
1076
+ this.$preview.html(this.original.preview)
1077
+
1078
+ if (this.original.exists) this.$element.addClass('fileupload-exists').removeClass('fileupload-new')
1079
+ else this.$element.addClass('fileupload-new').removeClass('fileupload-exists')
1080
+ },
1081
+
1082
+ trigger: function(e) {
1083
+ this.$input.trigger('click')
1084
+ e.preventDefault()
1085
+ }
1086
+ }
1087
+
1088
+
1089
+ /* FILEUPLOAD PLUGIN DEFINITION
1090
+ * =========================== */
1091
+
1092
+ $.fn.fileupload = function (options) {
1093
+ return this.each(function () {
1094
+ var $this = $(this)
1095
+ , data = $this.data('fileupload')
1096
+ if (!data) $this.data('fileupload', (data = new Fileupload(this, options)))
1097
+ if (typeof options == 'string') data[options]()
1098
+ })
1099
+ }
1100
+
1101
+ $.fn.fileupload.Constructor = Fileupload
1102
+
1103
+
1104
+ /* FILEUPLOAD DATA-API
1105
+ * ================== */
1106
+
1107
+ $(document).on('click.fileupload.data-api', '[data-provides="fileupload"]', function (e) {
1108
+ var $this = $(this)
1109
+ if ($this.data('fileupload')) return
1110
+ $this.fileupload($this.data())
1111
+
1112
+ var $target = $(e.target).closest('[data-dismiss="fileupload"],[data-trigger="fileupload"]');
1113
+ if ($target.length > 0) {
1114
+ $target.trigger('click.fileupload')
1115
+ e.preventDefault()
1116
+ }
1117
+ })
1118
+
1119
+ }(window.jQuery);