rsence-pre 3.0.0.10 → 3.0.0.11

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 (31) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/client/conf/client_pkg.yaml +17 -1
  4. data/client/ext/Rakefile +42 -12
  5. data/client/js/comm/transporter/transporter.js +1 -0
  6. data/client/js/controls/numerictextcontrol/numerictextcontrol.coffee +10 -11
  7. data/client/js/controls/searchfield/themes/default/searchfield.css +56 -91
  8. data/client/js/controls/searchfield/themes/default/searchfield.html +10 -10
  9. data/client/js/controls/textcontrol/textcontrol.coffee +71 -65
  10. data/client/js/core/elem/elem.coffee +5 -0
  11. data/client/js/datetime/datepicker/datepicker.coffee +1 -0
  12. data/client/js/datetime/momentjs/momentjs.js +12 -4
  13. data/client/js/foundation/control/eventresponder/eventresponder.js +14 -0
  14. data/client/js/foundation/json_renderer/json_renderer.js +12 -12
  15. data/client/js/foundation/view/view.js +13 -4
  16. data/client/js/lists/radiobuttonlist/radiobuttonlist.js +9 -8
  17. data/client/js/media/mediaelement/mediaelement.js +1890 -0
  18. data/client/js/media/mediaelement_defaults/mediaelement_defaults.coffee +1 -0
  19. data/client/js/media/mediaelement_resources/mediaelement_resources.js +1 -0
  20. data/client/js/media/mediaelement_resources/themes/mejs/flashmediaelement.swf +0 -0
  21. data/client/js/media/mediaelement_resources/themes/mejs/mediaelement_resources.css +0 -0
  22. data/client/js/media/mediaelement_resources/themes/mejs/mediaelement_resources.html +0 -0
  23. data/client/js/media/mediaelement_resources/themes/mejs/silverlightmediaelement.xap +0 -0
  24. data/client/js/menus/combobox/combobox.coffee +6 -1
  25. data/client/js/menus/menuitem/themes/default/menuitem.css +5 -8
  26. data/client/js/menus/minimenu/minimenu.js +2 -2
  27. data/client/js/menus/minimenu/themes/default/minimenu.css +6 -22
  28. data/client/js/menus/minimenuitem/themes/default/minimenuitem.css +5 -8
  29. data/client/js/menus/popupmenu/themes/default/popupmenu.css +6 -27
  30. data/plugins/client_pkg/lib/client_pkg_build.rb +5 -1
  31. metadata +8 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1d5b5f7d60608bbab206276e6e1f1fe3a078fdc1
4
- data.tar.gz: d460c435b926b1d001c0079e60d03ee26bac4b9a
3
+ metadata.gz: e9b6d8279d4e6c4428be24337adf68655670640e
4
+ data.tar.gz: 0a2beb7fecc41ddb17883bd6b41bcebebc85eed1
5
5
  SHA512:
6
- metadata.gz: 2508420c6dbf347f43781cdb5ff772341df775f4867128a0b385d8c4a254e3f91d037fd306a92f58470e64d2c7f51e2cf12d606da91450ec52ebaaf6b5065435
7
- data.tar.gz: 25ffa628cc7916db622b614ad8a883191ec97be900945c17d0695e17e79a112abf6c238d4e6e88eef9b36561ade57f74e55433d447292ad47224d01b862f8ce7
6
+ metadata.gz: 44011410d1f605a478e1e29ac4116c6235326ac5e0b80c33fe0624b2f1b6763828e3dbb600ac61a34f2bd1f90f145fd66d9b1dab1602047b7bdbf5bad5c34ecf
7
+ data.tar.gz: 074b547410ecac12f7ba3f9600aacbe4f966c41f6b54541f1c8fbe6d3c1bf8932324aa6a484358e117a2d0500871c7dad0d376d3a1d3e78f4c8f3759741772f1
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.0.0.10.pre
1
+ 3.0.0.11.pre
@@ -7,6 +7,8 @@
7
7
  # List of theme names to include and pack
8
8
  :theme_names:
9
9
  - default # Makes default_theme.js containing css and html templates
10
+ - mejs # MediaElement.js resources
11
+ # - codemirror # default CodeMirror css theme
10
12
 
11
13
  # List of packages to build
12
14
  :packages:
@@ -24,7 +26,7 @@
24
26
  - event # Event
25
27
  - util_methods # UtilMethods
26
28
 
27
- - locale_settings # HLocaleSettings
29
+ - locale_settings # HLocaleSettings
28
30
 
29
31
  # RSence.Foundation
30
32
  - system # HSystem
@@ -64,6 +66,14 @@
64
66
  - scrollview # HScrollView
65
67
  - inlineview # HInlineView
66
68
 
69
+ mediaelement:
70
+ - mediaelement # MediaElement
71
+ - mediaelement_resources # MediaElement resources (swf and xap)
72
+ - mediaelement_defaults # default settings for MediaElement
73
+
74
+ # codemirror:
75
+ # - codemirror # CodeMirror
76
+
67
77
  # The default collection of simple control widgets (components)
68
78
  controls:
69
79
  - button # HButton
@@ -152,6 +162,11 @@
152
162
  - graphics
153
163
  - chat
154
164
  - servermessage
165
+ media:
166
+ - mejs_theme
167
+ - mediaelement
168
+ # code:
169
+ # - codemirror
155
170
  std_widgets:
156
171
  - default_theme
157
172
  - controls
@@ -180,6 +195,7 @@
180
195
  - .gif
181
196
  - .png
182
197
  - .swf
198
+ - .xap
183
199
  - .svg
184
200
  - .pdf
185
201
 
data/client/ext/Rakefile CHANGED
@@ -1,18 +1,48 @@
1
1
 
2
- path = File.split(__FILE__).first
3
- task :momentjs do
4
- moment_url = 'https://github.com/timrwood/moment.git'
5
- moment_path = File.expand_path( 'moment', path )
6
- if File.exist? moment_path
7
- `cd "#{moment_path}"; git pull`
2
+ $ext_path = File.split(__FILE__).first
3
+ $js_path = File.expand_path( 'js', File.split( $ext_path ).first )
4
+
5
+ def git_pull(url,proj_path)
6
+ if File.exist? proj_path
7
+ `cd "#{proj_path}"; git pull`
8
8
  else
9
- `git clone #{moment_url} "#{moment_path}"`
9
+ `git clone #{url} "#{proj_path}"`
10
10
  end
11
- client_path = File.split( path ).first
12
- src_js = File.expand_path( 'moment.js', moment_path )
13
- tgt_js = File.expand_path( 'js/datetime/momentjs/momentjs.js', client_path )
14
- `cp #{src_js} #{tgt_js}`
15
11
  end
16
12
 
17
- task :all => :momentjs
13
+ def ext_path( dir_name )
14
+ File.expand_path( dir_name, $ext_path )
15
+ end
16
+
17
+ def cp_rsrc( proj_path, proj_file, target_path )
18
+ src = File.expand_path( proj_file, proj_path )
19
+ tgt = File.expand_path( target_path, $js_path )
20
+ cp( src, tgt )
21
+ end
22
+
23
+ task :momentjs do
24
+ moment_url = 'https://github.com/timrwood/moment.git'
25
+ moment_path = ext_path( 'moment' )
26
+ git_pull( moment_url, moment_path )
27
+ cp_rsrc( moment_path, 'moment.js', 'datetime/momentjs/momentjs.js' )
28
+ end
29
+
30
+ task :mediaelement do
31
+ mediaelement_url = 'https://github.com/jammi/mediaelement.git'
32
+ mediaelement_path = ext_path( 'mediaelement' )
33
+ git_pull( mediaelement_url, mediaelement_path )
34
+ cp_rsrc( mediaelement_path, 'build/mediaelement.js', 'media/mediaelement/mediaelement.js' )
35
+ cp_rsrc( mediaelement_path, 'build/flashmediaelement.swf', 'media/mediaelement_resources/themes/mejs/flashmediaelement.swf' )
36
+ cp_rsrc( mediaelement_path, 'build/silverlightmediaelement.xap', 'media/mediaelement_resources/themes/mejs/silverlightmediaelement.xap' )
37
+ end
38
+
39
+ task :codemirror do
40
+ codemirror_url = 'https://github.com/marijnh/CodeMirror.git'
41
+ codemirror_path = ext_path( 'codemirror' )
42
+ git_pull( codemirror_url, codemirror_path )
43
+ cp_rsrc( codemirror_path, 'lib/codemirror.js', 'code/codemirror/codemirror.js' )
44
+ cp_rsrc( codemirror_path, 'lib/codemirror.css', 'code/codemirror/themes/codemirror/codemirror.css' )
45
+ end
46
+
47
+ task :all => [ :momentjs, :mediaelement, :codemirror ]
18
48
  task :default => :all
@@ -145,6 +145,7 @@ COMM.Transporter = HApplication.extend({
145
145
  _values = _responseArray[1],
146
146
  _session = COMM.Session,
147
147
  _queue = COMM.Queue,
148
+ _outputScript,
148
149
  _errorText;
149
150
  if(_sesKey === ''){
150
151
  console.log('Invalid session, error message should follow...');
@@ -35,7 +35,9 @@ HNumericTextControl = HTextControl.extend
35
35
  else
36
36
  _value = _value+@options.numberIncrement
37
37
  _value = @validateNumber(_value)
38
- @setValue( _value )
38
+ @setValue(_value) if @_isValid
39
+ @setTextFieldValue( _value, true )
40
+ true
39
41
 
40
42
  keyDown: (_key)->
41
43
  if _key == Event.KEY_UP
@@ -48,6 +50,10 @@ HNumericTextControl = HTextControl.extend
48
50
 
49
51
  _numbers: ['0','1','2','3','4','5','6','7','8','9']
50
52
  validateNumber: (_value)->
53
+ if isNaN( _value )
54
+ _value = @value
55
+ console.log('isNaN')
56
+ @setValid(false)
51
57
  if @options.decimalNumber
52
58
  _value = parseFloat(_value)
53
59
  if @options.decimalPlaces != null
@@ -55,9 +61,6 @@ HNumericTextControl = HTextControl.extend
55
61
  _value = Math.round(_value*_decPlaces)/_decPlaces
56
62
  else
57
63
  _value = parseInt( _value, 10 )
58
- if isNaN( _value )
59
- _value = @value
60
- @setValid(false)
61
64
  if _value > @maxValue
62
65
  _value = @maxValue
63
66
  @setValid(false)
@@ -82,12 +85,8 @@ HNumericTextControl = HTextControl.extend
82
85
  valueToField: (_value)->
83
86
  _value = @validateNumber(_value)
84
87
  if @options.decimalNumber and @options.decimalPlaces != null
85
- if _value - Math.round(_value) == 0
86
- _value = _value+@options.decimalSeparator
87
- for n in [0...@options.decimalPlaces]
88
- _value += '0'
89
- else
90
- _value = _value.toString().replace('.',@options.decimalSeparator)
88
+ _value = _value.toFixed(@options.decimalPlaces)
89
+ _value = _value.replace('.',@options.decimalSeparator)
91
90
  _value
92
91
 
93
92
  refreshValue: ->
@@ -101,7 +100,7 @@ HNumericTextControl = HTextControl.extend
101
100
  # validateText: (_value)-> _value
102
101
 
103
102
  drawSubviews: ->
104
- @setStyleOfPart('value','textAlign','right')
103
+ @setStyleOfPart('value','textAlign','right') unless @options.style? and @options.style.textAlign
105
104
  if @options.withStepper
106
105
  this._extraLabelRight += 14
107
106
  @setStyleOfPart('label','right',this._extraLabelRight+'px')
@@ -1,107 +1,72 @@
1
-
2
- .default .searchfield_input {
3
- position: absolute;
4
- display: block;
5
- font-family: Helvetica, Arial, sans-serif;
6
- font-size: 13px;
7
- color: #000;
1
+ .default.searchfield {
2
+ overflow: visible;
3
+ }
4
+ .default.searchfield > .input_parent {
5
+ position: absolute; z-index: 2;
6
+ left: 1px; top: 1px; right: 1px; bottom: 1px;
7
+ }
8
+ .default.searchfield > .input_parent > .input {
9
+ position: absolute; display: block;
10
+ font-family: Helvetica, Arial, sans-serif; line-height: 18px; text-overflow: ellipsis; white-space: nowrap; overflow: hidden;
11
+ font-size: 13px; color: #000;
8
12
  background-color: transparent;
9
13
  vertical-align: middle;
10
- border: 0px;
11
- left: 18px; top: 0px;
12
- line-height: 18px;
13
- text-overflow: ellipsis;
14
- white-space: nowrap;
15
- overflow: hidden;
16
- #{(
17
- (BROWSER_TYPE.firefox||BROWSER_TYPE.ie7||BROWSER_TYPE.ie8||BROWSER_TYPE.ie9||BROWSER_TYPE.ie10||BROWSER_TYPE.opera)?
18
- 'padding-left:2px;width:85% !important;height:90% !important;':
19
- 'padding:2px;padding-top:4px;right:3px;height:22px;width:auto;'
20
- )}
14
+ border: 0; left: 18px; top: 0;
15
+ right: 0; bottom: 0;
16
+ width: 100%; height: 100%;
17
+ -moz-box-sizing: border-box;
18
+ -webkit-box-sizing: border-box;
19
+ box-sizing: border-box;
21
20
  }
22
-
23
- .default .searchfield_input:focus {
24
- outline-color: transparent;
25
- outline-style: none;
21
+ .default.searchfield > .input_parent > .input::-ms-clear {
22
+ display: none;
26
23
  }
27
-
28
- .default .disabled .searchfield_input {
29
- color: #ccc;
24
+ .default.searchfield.disabled > .input_parent > .input { color: #333; }
25
+ .default.searchfield > .input_parent > .input:focus {
26
+ outline-color: transparent; outline-style: none;
30
27
  }
31
-
32
- .default .searchfield_input_parent {
33
- position: absolute;
34
- #{(
35
- (BROWSER_TYPE.firefox||BROWSER_TYPE.ie7||BROWSER_TYPE.ie8||BROWSER_TYPE.ie9||BROWSER_TYPE.ie10||BROWSER_TYPE.opera)?
36
- 'left:0;padding-left:1px;top:0;right:4px;bottom:0;':
37
- 'left:-2px;top:-2px;right:-2px;height:24px;'
38
- )}
28
+ .default.searchfield > .input_parent > .input_invalid {
29
+ position: absolute; white-space: nowrap; overflow: hidden;
30
+ vertical-align: bottom; visibility: hidden;
31
+ bottom: 1px; font-size: 10px; line-height: 6px;
32
+ color: #c00; z-index: 0; font-weight: bold;
39
33
  }
40
34
 
41
- .default .searchfield_fade,
42
- .default .searchfield_e,
43
- .default .searchfield_w,
44
- .default .searchfield_c {
45
- position: absolute;
46
- height: 24px;
35
+
36
+ .default.searchfield > .fade,
37
+ .default.searchfield > .bg > .e,
38
+ .default.searchfield > .bg > .w,
39
+ .default.searchfield > .bg > .c {
40
+ position: absolute; height: 24px;
47
41
  background-repeat: no-repeat;
48
42
  background-image: #url(searchfield_parts1.png);
49
43
  }
50
-
51
- .default .searchfield_fade {
52
- right: 0px; top: 0px; width: 10px;
53
- background-position: -48px 0px;
44
+ .default.searchfield > .fade {
45
+ right: 0; top: 0; width: 10px;
46
+ background-position: -48px 0;
54
47
  }
55
-
56
- .default .searchfield_e {
57
- right: 0px; top: 0px; width: 24px;
58
- background-position: -24px 0px;
48
+ .default.searchfield > .bg > .e {
49
+ right: 0; top: 0; width: 24px;
50
+ background-position: -24px 0;
59
51
  }
60
-
61
- .default .searchfield_c {
62
- left: 24px; right: 24px; top: 0px;
52
+ .default.searchfield > .bg > .c {
53
+ left: 24px; right: 24px; top: 0;
63
54
  background-repeat: repeat-x;
64
- background-position: 0px -24px;
65
- }
66
-
67
- .default .searchfield_w {
68
- left: 0px; top: 0px; width: 24px;
69
- background-position: 0px 0px;
70
- }
71
-
72
- .default .disabled > .searchfield_fade {
73
- background-position: -48px -96px;
74
- }
75
-
76
- .default .disabled > .searchfield_e {
77
- background-position: -24px -96px;
78
- }
79
-
80
- .default .disabled > .searchfield_c {
81
- background-position: 0px -120px;
82
- }
83
-
84
- .default .disabled > .searchfield_w {
85
- background-position: 0px -96px;
86
- }
87
-
88
- .default .active > .searchfield_fade {
89
- background-position: -48px -48px;
90
- }
91
-
92
- .default .active > .searchfield_e {
93
- background-position: -24px -48px;
94
- }
95
-
96
- .default .active > .searchfield_c {
97
- background-position: 0px -72px;
98
- }
99
-
100
- .default .active > .searchfield_w {
101
- background-position: 0px -48px;
102
- }
103
-
104
- .default > .searchfield_help {
55
+ background-position: 0 -24px;
56
+ }
57
+ .default.searchfield > .bg > .w {
58
+ left: 0; top: 0; width: 24px;
59
+ background-position: 0 0;
60
+ }
61
+ .default.searchfield.disabled > .fade { background-position: -48px -96px; }
62
+ .default.searchfield.disabled > .bg > .e { background-position: -24px -96px; }
63
+ .default.searchfield.disabled > .bg > .c { background-position: 0 -120px; }
64
+ .default.searchfield.disabled > .bg > .w { background-position: 0 -96px; }
65
+ .default.searchfield.active > .fade { background-position: -48px -48px; }
66
+ .default.searchfield.active > .bg > .e { background-position: -24px -48px; }
67
+ .default.searchfield.active > .bg > .c { background-position: 0 -72px; }
68
+ .default.searchfield.active > .bg > .w { background-position: 0 -48px; }
69
+ .default.searchfield > .help {
105
70
  position: absolute;
106
71
  left: 24px; top: 5px; right: 8px; height: 18px;
107
72
  color: #888;
@@ -1,11 +1,11 @@
1
- <div class="searchfield_w"></div>
2
- <div class="searchfield_c"></div>
3
- <div class="searchfield_e"></div>
4
- <div class="searchfield_help" id="help]I[" >#{this.options.helpText}</div>
5
- <div id="label]I[" title="#{this.label}" class="searchfield_input_parent">
6
- <input type="text" class="searchfield_input" #{this.enabled?'':'disabled'}
7
- onfocus="HSystem.views[#{this.viewId}].textFocus();"
8
- onblur="HSystem.views[#{this.viewId}].textBlur();"
9
- id="value]I[" value="#{this.value}" />
1
+ <div class="bg" id="bg]I[">
2
+ <div class="w"></div>
3
+ <div class="c"></div>
4
+ <div class="e"></div>
10
5
  </div>
11
- <div class="searchfield_fade"></div>
6
+ <div class="help" id="help]I[" >#{this.options.helpText}</div>
7
+ <div id="subview]I[" class="subview"></div>
8
+ <div id="label]I[" title="#{this.label}" class="input_parent">
9
+ <div class="input_invalid" id="invalid]I["></div>
10
+ </div>
11
+ <div class="fade"></div>
@@ -131,15 +131,38 @@ HTextControl = HControl.extend
131
131
  else
132
132
  @_setInvalidMarker()
133
133
 
134
+ resize: ->
135
+ @_ie8fix() if BROWSER_TYPE.ie8
136
+
137
+ _ie8fix: ->
138
+ h = @rect.height-4
139
+ @setStyleOfPart('value','paddingTop','2px')
140
+ @setStyleOfPart('value','lineHeight',h+'px')
141
+
142
+ _snatchField: (_parentId,_id)->
143
+ _idType = @typeChr(_id)
144
+ if _idType == 's'
145
+ _elemId = ELEM.bindId(_id)
146
+ else if _idType == 'n'
147
+ _elemId = ELEM.get(_id)
148
+ else
149
+ console.warn('Unknown id type for snatchField:',_id,' (type:'+_idType+'); assuming element...') if !@isProducton
150
+ _elemId = ELEM.bind(_id)
151
+ ELEM.moveToParent(_elemId,_parentId)
152
+ _elemId
153
+
134
154
  fieldType: 'text'
135
155
  drawMarkup: ->
136
156
  @base()
137
157
  @_invalidCharWidth = @stringWidth(@_invalidChar,null,@markupElemIds.invalid)
138
158
  _parentId = @markupElemIds.label
139
- if @multiline
140
- _elemId = ELEM.make(_parentId,'textarea')
159
+ if @options.snatchField?
160
+ _elemId = @_snatchField(_parentId,@options.snatchField)
141
161
  else
142
- _elemId = ELEM.make(_parentId,'input',{attr:{type:@fieldType,value:@value}})
162
+ if @multiline
163
+ _elemId = ELEM.make(_parentId,'textarea')
164
+ else
165
+ _elemId = ELEM.make(_parentId,'input',{attr:{type:@fieldType,value:@value}})
143
166
  @markupElemIds.value = _elemId
144
167
  @setCSSClass('value','input')
145
168
  Event.observe(_elemId,'focus',=>@textFocus())
@@ -147,6 +170,9 @@ HTextControl = HControl.extend
147
170
  if @options.focusOnCreate
148
171
  @getInputElement().focus()
149
172
  @setSelectionRange( @value.length, @value.length ) if @typeChr(@value) == 's'
173
+ if BROWSER_TYPE.ie8
174
+ @setResize( true ) unless @events.resize
175
+ @_ie8fix()
150
176
 
151
177
  lostActiveStatus: (_prevActive)->
152
178
  @base(_prevActive)
@@ -261,20 +287,17 @@ HTextControl = HControl.extend
261
287
  ## = Parameters
262
288
  ## +_value+:: The value to set.
263
289
  ###
264
- setTextFieldValue: (_value)->
290
+ setTextFieldValue: (_value, _override)->
265
291
  _inputElement = @getInputElement()
266
292
  return unless _inputElement?
267
293
  [ _selectionStart, _selectionEnd ] = @getSelectionRange()
268
294
  _value = @valueToField(_value)
269
295
  @_lastFieldValue = _value
270
- unless @hasTextFocus
296
+ if not @hasTextFocus or _override
271
297
  _inputElement.value = _value if _inputElement.value != _value.toString()
272
298
  @setSelectionRange( _selectionStart, _selectionEnd )
273
299
  @setValid(true) if _inputElement.value == _value
274
300
 
275
- # returns a random number prefixed and suffixed with '---'
276
- _randomMarker: -> '---'+Math.round((1+Math.random())*10000)+'---'
277
-
278
301
  die: ->
279
302
  @getInputElement().blur() if @hasTextFocus
280
303
  clearTimeout(@_refreshTimer) if @_refreshTimer
@@ -289,68 +312,46 @@ HTextControl = HControl.extend
289
312
  ###
290
313
  _getLeftAlignedSelectionRange: ->
291
314
  _inputElement = @getInputElement()
292
- if _inputElement == null or @hasTextFocus == false
293
- _rangeArr = [ 0, 0 ]
294
- ## Other browsers
295
- else if _inputElement.selectionStart
315
+ _rangeArr = [ 0, 0 ]
316
+ # if _inputElement == null or @hasTextFocus == false
317
+ # _rangeArr = [ 0, 0 ]
318
+ ## All except Internet Explorer
319
+ if _inputElement.selectionStart?
296
320
  _rangeArr = [ _inputElement.selectionStart, _inputElement.selectionEnd ]
297
321
  ## Internet Explorer:
298
- else if document.selection
299
- # create a range object
322
+ else if document.selection and document.selection.createRange
300
323
  _range = document.selection.createRange()
301
- # original range text
302
- _rangeText = _range.text
303
- _rangeLength = _rangeText.length
304
- # make a copy of the text and replace \r\n with \n
305
- _origValue = _inputElement.value.replace(/\r\n/g, "\n")
306
- # create random marker to replace the text with
307
- _marker = @_randomMarker()
308
- # re-generate marker if it's found in the text.
309
- _marker = @_randomMarker() while ~_origValue.indexOf( _marker )
310
- _markerLength = _marker.length
311
- # temporarily set the text of the selection to the unique marker
312
- _range.text = _marker
313
- _markerValue = _inputElement.value.replace(/\r\n/g, "\n")
314
- _range.text = _rangeText
315
- _markerIndex = _markerValue.indexOf( _marker )
316
- _rangeArr = [ _markerIndex, _markerIndex + _rangeLength ]
317
- ## No support:
318
- else
319
- _rangeArr = [ 0, 0 ]
324
+ if _range and _range.parentElement() == _inputElement
325
+ _len = _inputElement.value.length
326
+ _normalizedValue = _inputElement.value.replace(/\r\n/g, "\n")
327
+ # Create a working TextRange that lives only in the input
328
+ _textInputRange = _inputElement.createTextRange()
329
+ _textInputRange.moveToBookmark( _range.getBookmark() )
330
+
331
+ # Check if the start and end of the selection are at the very end
332
+ # of the input, since moveStart/moveEnd doesn't return what we want
333
+ # in those cases
334
+ _endRange = _inputElement.createTextRange()
335
+ _endRange.collapse(false)
336
+
337
+ if ~_textInputRange.compareEndPoints("StartToEnd", _endRange)
338
+ _rangeArr = [ _len, _len ]
339
+ else
340
+ _rangeArr[0] = 0-_textInputRange.moveStart("character", 0-_len)
341
+ _rangeArr[0] += (_normalizedValue.slice(0, _rangeArr[0]).split("\n").length - 1)
342
+ if ~_textInputRange.compareEndPoints("EndToEnd", _endRange)
343
+ _rangeArr[1] = _len
344
+ else
345
+ _rangeArr[1] = 0-_textInputRange.moveEnd("character", 0-_len)
346
+ _rangeArr[1] += (_normalizedValue.slice(0, _rangeArr[1]).split("\n").length - 1)
320
347
  return _rangeArr
321
348
  _getRightAlignedSelectionRange: ->
322
349
  _inputElement = @getInputElement()
323
350
  _inputValue = _inputElement.value
324
351
  _valueLength = _inputValue.length
325
- if _inputElement == null or @hasTextFocus == false
326
- _rangeArr = [ 0, 0 ]
327
- ## Other browsers
328
- else if _inputElement.selectionStart
329
- _rangeArr = [ _valueLength-_inputElement.selectionStart, _valueLength-_inputElement.selectionEnd ]
330
- ## Internet Explorer:
331
- else if document.selection
332
- # create a range object
333
- _range = document.selection.createRange()
334
- # original range text
335
- _rangeText = _range.text
336
- _rangeLength = _rangeText.length
337
- # make a copy of the text and replace \r\n with \n
338
- _origValue = _inputElement.value.replace(/\r\n/g, "\n")
339
- # create random marker to replace the text with
340
- _marker = @_randomMarker()
341
- # re-generate marker if it's found in the text.
342
- _marker = @_randomMarker() while ~_origValue.indexOf( _marker )
343
- _markerLength = _marker.length
344
- # temporarily set the text of the selection to the unique marker
345
- _range.text = _marker
346
- _markerValue = _inputElement.value.replace(/\r\n/g, "\n")
347
- _range.text = _rangeText
348
- _markerIndex = _markerValue.indexOf( _marker )
349
- _rangeArr = [ _valueLength-_markerIndex, _valueLength-_markerIndex + _rangeLength ]
350
- ## No support:
351
- else
352
- _rangeArr = [ 0, 0 ]
353
- return _rangeArr
352
+ _range = @_getLeftAlignedSelectionRange()
353
+ _range = [ _valueLength-_range[0], _valueLength-_range[1] ]
354
+ _range
354
355
  getSelectionRange: ->
355
356
  return @_getRightAlignedSelectionRange() if @styleOfPart('value','textAlign') == 'right'
356
357
  @_getLeftAlignedSelectionRange()
@@ -381,8 +382,7 @@ HTextControl = HControl.extend
381
382
  ###
382
383
  setSelectionRange: ( _selectionStart, _selectionEnd )->
383
384
  if @typeChr( _selectionStart ) == 'a'
384
- _selectionEnd = _selectionStart[1];
385
- _selectionStart = _selectionStart[0];
385
+ [ _selectionStart, _selectionEnd ] = _selectionStart
386
386
  unless _selectionEnd?
387
387
  _selectionEnd = _selectionStart
388
388
  _inputElement = @getInputElement()
@@ -394,7 +394,13 @@ HTextControl = HControl.extend
394
394
  # Internet Explorer
395
395
  if _inputElement.createTextRange
396
396
  _range = _inputElement.createTextRange()
397
- _range.move( 'character', _selectionStart, _selectionEnd )
397
+ _range.collapse()
398
+ _selectionEnd = _selectionEnd - _selectionStart
399
+ if _selectionEnd == 0
400
+ _range.move( 'character', _selectionStart )
401
+ else
402
+ _range.moveStart( 'character', _selectionStart )
403
+ _range.moveEnd( 'character', _selectionEnd )
398
404
  _range.select()
399
405
  # Other browsers:
400
406
  else if _inputElement.selectionStart
@@ -157,6 +157,11 @@ ELEM = HClass.extend
157
157
  append: (_srcId, _tgtId)->
158
158
  @_elements[_tgtId].appendChild @_elements[_srcId]
159
159
 
160
+ moveToParent: (_id,_parentId)->
161
+ _elem = @_elements[_id]
162
+ _elem.parentNode.removeChild( _elem )
163
+ @_elements[_parentId].appendChild( _elem )
164
+
160
165
  ###
161
166
  Replaces all styles of an element with a block of css text
162
167
  ###
@@ -20,6 +20,7 @@ HDatePicker = HTextControl.extend
20
20
  else if _delta < 0
21
21
  _date.subtract(1,@options.scrollUnit)
22
22
  @setValue(_date.unix())
23
+ @setTextFieldValue(@value,true)
23
24
  true
24
25
  valueToField: (_value)->
25
26
  _date = @moment(_value*1000)
@@ -1249,19 +1249,27 @@
1249
1249
  units = normalizeUnits(units);
1250
1250
 
1251
1251
  if (units === 'year' || units === 'month') {
1252
+ // average number of days in the months in the given dates
1252
1253
  diff = (this.daysInMonth() + that.daysInMonth()) * 432e5; // 24 * 60 * 60 * 1000 / 2
1254
+ // difference in months
1253
1255
  output = ((this.year() - that.year()) * 12) + (this.month() - that.month());
1254
- output += ((this - moment(this).startOf('month')) - (that - moment(that).startOf('month'))) / diff;
1256
+ // adjust by taking difference in days, average number of days
1257
+ // and dst in the given months.
1258
+ output += ((this - moment(this).startOf('month')) -
1259
+ (that - moment(that).startOf('month'))) / diff;
1260
+ // same as above but with zones, to negate all dst
1261
+ output -= ((this.zone() - moment(this).startOf('month').zone()) -
1262
+ (that.zone() - moment(that).startOf('month').zone())) * 6e4 / diff;
1255
1263
  if (units === 'year') {
1256
1264
  output = output / 12;
1257
1265
  }
1258
1266
  } else {
1259
- diff = (this - that) - zoneDiff;
1267
+ diff = (this - that);
1260
1268
  output = units === 'second' ? diff / 1e3 : // 1000
1261
1269
  units === 'minute' ? diff / 6e4 : // 1000 * 60
1262
1270
  units === 'hour' ? diff / 36e5 : // 1000 * 60 * 60
1263
- units === 'day' ? diff / 864e5 : // 1000 * 60 * 60 * 24
1264
- units === 'week' ? diff / 6048e5 : // 1000 * 60 * 60 * 24 * 7
1271
+ units === 'day' ? (diff - zoneDiff) / 864e5 : // 1000 * 60 * 60 * 24, negate dst
1272
+ units === 'week' ? (diff - zoneDiff) / 6048e5 : // 1000 * 60 * 60 * 24 * 7, negate dst
1265
1273
  diff;
1266
1274
  }
1267
1275
  return asFloat ? output : absRound(output);
@@ -439,6 +439,20 @@ HEventResponder = HClass.extend({
439
439
  return this;
440
440
  },
441
441
 
442
+ /** = Description
443
+ * Registers or releases event listening for resize events
444
+ * depending on the value of the flag argument.
445
+ *
446
+ * = Returns
447
+ * +self+
448
+ *
449
+ **/
450
+ setResize: function(_flag) {
451
+ this.events.resize = _flag;
452
+ this.setEvents();
453
+ return this;
454
+ },
455
+
442
456
  /** Same as +setClickable+
443
457
  **/
444
458
  setClick: function(_flag) {