sproutcore 1.0.1042 → 1.0.1043
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.
- data/VERSION.yml +3 -3
- data/doc_templates/sproutcore/publish.js +2 -1
- data/frameworks/sproutcore/apps/tests/english.lproj/main_page.css +8 -3
- data/frameworks/sproutcore/apps/tests/english.lproj/main_page.js +5 -4
- data/frameworks/sproutcore/frameworks/animation/core.js +80 -30
- data/frameworks/sproutcore/frameworks/animation/tests/core.js +26 -1
- data/frameworks/sproutcore/frameworks/datastore/system/store.js +47 -4
- data/frameworks/sproutcore/frameworks/desktop/english.lproj/toolbar.css +0 -1
- data/frameworks/sproutcore/frameworks/foundation/mixins/button.js +9 -2
- data/frameworks/sproutcore/frameworks/foundation/system/datetime.js +331 -122
- data/frameworks/sproutcore/frameworks/foundation/system/root_responder.js +92 -1
- data/frameworks/sproutcore/frameworks/foundation/tests/mixins/button/ui.js +68 -0
- data/frameworks/sproutcore/frameworks/foundation/tests/system/datetime.js +191 -90
- data/frameworks/sproutcore/frameworks/mobile/system/root_responder.js +0 -97
- data/frameworks/sproutcore/frameworks/runtime/mixins/observable.js +1 -0
- data/frameworks/sproutcore/frameworks/runtime/tests/mixins/observable/observable.js +6 -0
- data/frameworks/sproutcore/themes/standard_theme/Source/SproutCore Theme Buttons.psd +0 -0
- data/lib/sproutcore/builders/minify.rb +6 -7
- data/lib/sproutcore/models/target.rb +8 -8
- data/lib/sproutcore/rack/builder.rb +10 -1
- data/lib/sproutcore/tools/build.rb +21 -16
- metadata +4 -2
data/VERSION.yml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
:digest:
|
2
|
+
:digest: 27241da4db9a4fd342f444b171b497ccb7272fe0
|
3
3
|
:dist:
|
4
|
-
frameworks/sproutcore:
|
4
|
+
frameworks/sproutcore: e9b957ac68b9adc9eb9cef27396eea85f3075553
|
5
5
|
:major: 1
|
6
6
|
:minor: 0
|
7
|
-
:patch:
|
7
|
+
:patch: 1043
|
@@ -13,7 +13,8 @@ function superTextile(s) {
|
|
13
13
|
['\\+', '\\+', 'ins'], //fixed
|
14
14
|
['~', '~', 'sub'],
|
15
15
|
['\\^', '\\^', 'sup'], // me
|
16
|
-
['{{{', '}}}', 'code']
|
16
|
+
['{{{', '}}}', 'code'],
|
17
|
+
['@', '@', 'code']];
|
17
18
|
|
18
19
|
for (var i=0;i<qtags.length;i++) {
|
19
20
|
var ttag_o = qtags[i][0], ttag_c = qtags[i][1], htag = qtags[i][2];
|
@@ -26,7 +26,8 @@ h1.app-title img {
|
|
26
26
|
}
|
27
27
|
|
28
28
|
.sc-view.sc-toolbar-view.navigation-bar {
|
29
|
-
border-
|
29
|
+
border-top:0;
|
30
|
+
border-bottom: 1px #4D5567 solid;
|
30
31
|
}
|
31
32
|
|
32
33
|
.sc-label-view.center-label {
|
@@ -34,8 +35,12 @@ h1.app-title img {
|
|
34
35
|
opacity: 0.8;
|
35
36
|
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=80);
|
36
37
|
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=80)";
|
37
|
-
-moz-opacity:0.8;
|
38
|
-
|
38
|
+
-moz-opacity:0.8;
|
39
|
+
}
|
40
|
+
|
41
|
+
.sc-view.sc-toolbar-view.bottom-toolbar {
|
42
|
+
z-index:2;
|
43
|
+
-webkit-box-shadow: none;
|
39
44
|
}
|
40
45
|
|
41
46
|
.sc-view.sc-toolbar-view .sc-checkbox-view {
|
@@ -62,6 +62,7 @@ TestRunner.mainPage = SC.Page.design({
|
|
62
62
|
anchorLocation: SC.ANCHOR_BOTTOM,
|
63
63
|
|
64
64
|
childViews: 'logo continuousIntegrationCheckbox runTestsButton'.w(),
|
65
|
+
classNames: 'bottom-toolbar',
|
65
66
|
|
66
67
|
logo: SC.View.design({
|
67
68
|
layout: { left: 0, top: 0, bottom: 0, width: 200 },
|
@@ -204,17 +205,17 @@ TestRunner.mainPage = SC.Page.design({
|
|
204
205
|
navigationView: SC.ToolbarView.design({
|
205
206
|
classNames: 'navigation-bar',
|
206
207
|
|
207
|
-
layout: { top:
|
208
|
+
layout: { top: 0, left: 0, right: 0, height: 32 },
|
208
209
|
childViews: "backButton locationLabel".w(),
|
209
210
|
|
210
211
|
backButton: SC.ButtonView.design({
|
211
|
-
layout: {
|
212
|
+
layout: { left: 8, centerY: 0, width: 80, height: 24 },
|
212
213
|
title: "« Tests",
|
213
214
|
action: "back"
|
214
215
|
}),
|
215
216
|
|
216
217
|
locationLabel: SC.LabelView.design({
|
217
|
-
layout: { right: 8,
|
218
|
+
layout: { right: 8, centerY: -2, height: 16, left: 100 },
|
218
219
|
textAlign: SC.ALIGN_RIGHT,
|
219
220
|
valueBinding: "TestRunner.detailController.displayName"
|
220
221
|
})
|
@@ -222,7 +223,7 @@ TestRunner.mainPage = SC.Page.design({
|
|
222
223
|
}),
|
223
224
|
|
224
225
|
webView: SC.WebView.design({
|
225
|
-
layout: { top:
|
226
|
+
layout: { top: 33, left: 2, right: 0, bottom: 0 },
|
226
227
|
valueBinding: "TestRunner.detailController.uncachedUrl"
|
227
228
|
})
|
228
229
|
})
|
@@ -75,6 +75,9 @@ SC.Animatable = {
|
|
75
75
|
// substitute our didUpdateLayer method (but saving the old one)
|
76
76
|
this._animatable_original_did_update_layer = this.didUpdateLayer || function(){};
|
77
77
|
this.didUpdateLayer = this._animatable_did_update_layer;
|
78
|
+
|
79
|
+
this._animatable_original_willRemoveFromParent = this.willRemoveFromParent || function(){};
|
80
|
+
this.willRemoveFromParent = this._animatable_will_remove_from_parent;
|
78
81
|
|
79
82
|
// for debugging
|
80
83
|
this._animateTickPixel.displayName = "animate-tick";
|
@@ -101,12 +104,20 @@ SC.Animatable = {
|
|
101
104
|
}
|
102
105
|
|
103
106
|
// live animators
|
107
|
+
this._animatableCurrentStyle = null;
|
104
108
|
this._animators = {}; // keyAnimated => object describing it.
|
105
109
|
this._animatableSetCSS = "";
|
106
110
|
this._last_transition_css = ""; // to keep from re-setting unnecessarily
|
107
111
|
this._disableAnimation = 0; // calls to disableAnimation add one; enableAnimation remove one.
|
108
112
|
},
|
109
113
|
|
114
|
+
/**
|
115
|
+
Stops all animations on the layer when this occurs by calling resetAnimation.
|
116
|
+
*/
|
117
|
+
_animatable_will_remove_from_parent: function() {
|
118
|
+
this.resetAnimation();
|
119
|
+
},
|
120
|
+
|
110
121
|
/**
|
111
122
|
Disables animation.
|
112
123
|
|
@@ -114,12 +125,17 @@ SC.Animatable = {
|
|
114
125
|
If you call disable twice, you need two enables to start it. Three times, you need
|
115
126
|
three enables.
|
116
127
|
*/
|
117
|
-
disableAnimation: function() {
|
128
|
+
disableAnimation: function() {
|
129
|
+
this._disableAnimation++;
|
130
|
+
},
|
118
131
|
|
119
132
|
/**
|
120
133
|
Enables animation if it was disabled (or moves towards that direction, at least).
|
121
134
|
*/
|
122
|
-
enableAnimation: function() {
|
135
|
+
enableAnimation: function() {
|
136
|
+
this._disableAnimation--;
|
137
|
+
if (this._disableAnimation < 0) this._disableAnimation = 0;
|
138
|
+
},
|
123
139
|
|
124
140
|
/**
|
125
141
|
Adds support for some style properties to adjust.
|
@@ -175,17 +191,40 @@ SC.Animatable = {
|
|
175
191
|
// call base with whatever is leftover
|
176
192
|
return this;
|
177
193
|
},
|
178
|
-
|
194
|
+
|
179
195
|
/**
|
180
|
-
|
196
|
+
Returns the current set of styles and layout according to JavaScript transitions.
|
197
|
+
|
198
|
+
That is, for transitions managed by JavaScript (rather than CSS), the current position
|
199
|
+
(even mid-transition) will be returned. For CSS-based transitions, the target position
|
200
|
+
will be returned. This function is mostly useful for testing.
|
201
|
+
|
202
|
+
It will return null if there is no such style.
|
203
|
+
*/
|
204
|
+
getCurrentJavaScriptStyles: function() {
|
205
|
+
return this._animatableCurrentStyle
|
206
|
+
},
|
181
207
|
|
182
|
-
|
183
|
-
|
208
|
+
/**
|
209
|
+
Resets animation, stopping all existing animations.
|
184
210
|
*/
|
185
|
-
resetAnimation: function()
|
186
|
-
|
187
|
-
this.
|
211
|
+
resetAnimation: function() {
|
212
|
+
this._animatableCurrentStyle = null;
|
213
|
+
this._stopJavaScriptAnimations();
|
214
|
+
this.disableAnimation();
|
188
215
|
this.updateStyle();
|
216
|
+
this.enableAnimation();
|
217
|
+
},
|
218
|
+
|
219
|
+
/**
|
220
|
+
Stops all JavaScript animations on the object. In their tracks. Hah hah.
|
221
|
+
*/
|
222
|
+
_stopJavaScriptAnimations: function() {
|
223
|
+
for (var i in this._animators) {
|
224
|
+
if (this._animators[i] && this._animators[i].isQueued) {
|
225
|
+
SC.Animatable.removeTimer(this._animators[i]);
|
226
|
+
}
|
227
|
+
}
|
189
228
|
},
|
190
229
|
|
191
230
|
_getStartStyleHash: function(start, target)
|
@@ -196,6 +235,7 @@ SC.Animatable = {
|
|
196
235
|
this.layout = start;
|
197
236
|
|
198
237
|
// get our frame and parent's frame
|
238
|
+
this.notifyPropertyChange("layout");
|
199
239
|
var f = this.get("frame");
|
200
240
|
var p = this.getPath("layoutView.frame");
|
201
241
|
|
@@ -211,7 +251,7 @@ SC.Animatable = {
|
|
211
251
|
if (f)
|
212
252
|
{
|
213
253
|
if (i == "left") { l[i] = f.x; continue; }
|
214
|
-
else if (i == "
|
254
|
+
else if (i == "top") { l[i] = f.y; continue; }
|
215
255
|
else if (i == "right") { l[i] = p.width - f.x - f.width; continue; }
|
216
256
|
else if (i == "bottom") { l[i] = p.height - f.y - f.height; continue; }
|
217
257
|
else if (i == "width") { l[i] = f.width; continue; }
|
@@ -248,7 +288,7 @@ SC.Animatable = {
|
|
248
288
|
// make sure there _is_ a previous style to animate from. Otherwise,
|
249
289
|
// we don't animate—and this is sometimes used to temporarily disable animation.
|
250
290
|
var i;
|
251
|
-
if (!this._animatableCurrentStyle || this._disableAnimation > 0)
|
291
|
+
if (!this._animatableCurrentStyle || this._disableAnimation > 0 || !layer)
|
252
292
|
{
|
253
293
|
// clone it to be a nice starting point next time.
|
254
294
|
this._animatableCurrentStyle = {};
|
@@ -430,7 +470,7 @@ SC.Animatable = {
|
|
430
470
|
_animatableApplyStyles: function(layer, styles)
|
431
471
|
{
|
432
472
|
if (!layer) return;
|
433
|
-
|
473
|
+
|
434
474
|
// handle a specific style first: display. There is a special case because it disrupts transitions.
|
435
475
|
if (styles["display"]) {
|
436
476
|
layer.style["display"] = styles["display"];
|
@@ -447,23 +487,21 @@ SC.Animatable = {
|
|
447
487
|
|
448
488
|
// get timer
|
449
489
|
var timer = this._animators["display-styles"];
|
450
|
-
|
451
|
-
//
|
452
|
-
if (timer.isQueued) {
|
453
|
-
// timer.action.call(timer, 0);
|
454
|
-
}
|
455
|
-
|
490
|
+
|
491
|
+
// set settings
|
456
492
|
timer.holder = this;
|
457
493
|
timer.action = this._animatableApplyNonDisplayStyles;
|
458
494
|
timer.layer = layer;
|
459
495
|
timer.styles = styles;
|
460
496
|
this._animatableCurrentStyle = styles;
|
497
|
+
|
498
|
+
// schedule.
|
461
499
|
SC.Animatable.addTimer(timer);
|
462
500
|
},
|
463
501
|
|
464
502
|
_animatableApplyNonDisplayStyles: function(){
|
465
503
|
var loop = SC.RunLoop.begin();
|
466
|
-
var layer = this.layer, styles = this.styles;
|
504
|
+
var layer = this.layer, styles = this.styles; // this == timer
|
467
505
|
var styleHelpers = {
|
468
506
|
opacity: this.holder._style_opacity_helper
|
469
507
|
// more to be added here...
|
@@ -495,7 +533,7 @@ SC.Animatable = {
|
|
495
533
|
// apply the styles (but we have to mix it in, because we still have transitions, etc. that we set)
|
496
534
|
var ls = this.holder.get("layoutStyle");
|
497
535
|
for (var key in ls) {
|
498
|
-
if (SC.none(ls[key]))
|
536
|
+
if (SC.none(ls[key])) style[key] = ""; // because IE is stupid and can't handle delete or null
|
499
537
|
else if (style[key] != ls[key]) style[key] = ls[key];
|
500
538
|
}
|
501
539
|
|
@@ -511,17 +549,20 @@ SC.Animatable = {
|
|
511
549
|
_animatable_did_update_layer: function()
|
512
550
|
{
|
513
551
|
this._animatable_original_did_update_layer();
|
514
|
-
var styles = this._animatableCurrentStyle
|
552
|
+
var styles = this._animatableCurrentStyle, layer = this.get("layer");
|
553
|
+
if (!styles) {
|
554
|
+
styles = {};
|
555
|
+
var s = this.get("style");
|
556
|
+
var l = this.get("layout");
|
557
|
+
SC.mixin(styles, s, l);
|
558
|
+
}
|
515
559
|
this._animatableApplyStyles(layer, styles);
|
516
560
|
},
|
517
561
|
|
518
562
|
/**
|
519
563
|
Overriden to support animation.
|
520
564
|
|
521
|
-
Works by
|
522
|
-
Whenever the layout needs updating, the old layout is consulted.
|
523
|
-
|
524
|
-
"layout" is kept at the new layout
|
565
|
+
Works by copying the styles to the object's "style" property.
|
525
566
|
*/
|
526
567
|
updateLayout: function(context, firstTime)
|
527
568
|
{
|
@@ -533,7 +574,7 @@ SC.Animatable = {
|
|
533
574
|
var key = ls[i];
|
534
575
|
if (style[key] !== newLayout[key])
|
535
576
|
{
|
536
|
-
if (SC.none(newLayout[key]))
|
577
|
+
if (SC.none(newLayout[key])) style[key] = ""; // because IE is stupid and can't handle delete or debug.
|
537
578
|
else style[key] = newLayout[key];
|
538
579
|
didChange = YES;
|
539
580
|
}
|
@@ -796,7 +837,7 @@ SC.mixin(SC.Animatable, {
|
|
796
837
|
TRANSITION_CSS_EASE: "ease",
|
797
838
|
TRANSITION_CSS_EASE_IN: "ease-in",
|
798
839
|
TRANSITION_CSS_EASE_OUT: "ease-out",
|
799
|
-
|
840
|
+
TRANSITION_CSS_EASE_IN_OUT: "ease-in-out",
|
800
841
|
|
801
842
|
// JavaScript-enabled
|
802
843
|
TRANSITION_EASE: [0.25, 0.1, 0.25, 1.0],
|
@@ -833,14 +874,22 @@ SC.mixin(SC.Animatable, {
|
|
833
874
|
lastFPS: 0
|
834
875
|
}),
|
835
876
|
|
836
|
-
addTimer: function(animator)
|
837
|
-
{
|
877
|
+
addTimer: function(animator) {
|
838
878
|
if (animator.isQueued) return;
|
879
|
+
animator.prev = SC.Animatable.baseTimer;
|
839
880
|
animator.next = SC.Animatable.baseTimer.next;
|
840
|
-
SC.Animatable.baseTimer.next = animator;
|
881
|
+
if (SC.Animatable.baseTimer.next) SC.Animatable.baseTimer.next.prev = animator; // adjust next prev.
|
882
|
+
SC.Animatable.baseTimer.next = animator; // switcheroo.
|
841
883
|
animator.isQueued = true;
|
842
884
|
if (!SC.Animatable.going) SC.Animatable.start();
|
843
885
|
},
|
886
|
+
|
887
|
+
removeTimer: function(animator) {
|
888
|
+
if (!animator.isQueued) return;
|
889
|
+
if (animator.next) animator.next.prev = animator.prev; // splice ;)
|
890
|
+
animator.prev.next = animator.next; // it should always have a prev.
|
891
|
+
animator.isQueued = false;
|
892
|
+
},
|
844
893
|
|
845
894
|
start: function()
|
846
895
|
{
|
@@ -865,6 +914,7 @@ SC.mixin(SC.Animatable, {
|
|
865
914
|
var t = next.next;
|
866
915
|
next.isQueued = false;
|
867
916
|
next.next = null;
|
917
|
+
next.prev = null;
|
868
918
|
next.action.call(next, start);
|
869
919
|
next = t;
|
870
920
|
i++;
|
@@ -8,10 +8,12 @@ module("Animatable", {
|
|
8
8
|
setup: function() {
|
9
9
|
view = SC.View.create(SC.Animatable, {
|
10
10
|
layout: { left: 100, top: 100, height: 100, width: 100 },
|
11
|
+
style: { opacity: .5 },
|
11
12
|
transitions: {
|
12
13
|
left: 0.25,
|
13
14
|
top: { duration: 0.35 },
|
14
|
-
width: { duration: 0.2, timing: SC.Animatable.TRANSITION_EASE_IN_OUT }
|
15
|
+
width: { duration: 0.2, timing: SC.Animatable.TRANSITION_EASE_IN_OUT },
|
16
|
+
style: { opacity: 1 }
|
15
17
|
}
|
16
18
|
});
|
17
19
|
|
@@ -63,3 +65,26 @@ test("animatable should handle concatenated transitions properly", function(){
|
|
63
65
|
equals(width["timing"], SC.Animatable.TRANSITION_EASE_IN_OUT, "SC.Animatable.TRANSITION_EASE_IN_OUT for width.");
|
64
66
|
});
|
65
67
|
|
68
|
+
test("animatable handler for layer update should ensure both layout and styles are set in the 'current style'.", function() {
|
69
|
+
var original_transition_enabled = SC.Animatable.enableCSSTransitions;
|
70
|
+
SC.Animatable.enableCSSTransitions = NO;
|
71
|
+
|
72
|
+
// check current style (should be none yet)
|
73
|
+
var current = view.getCurrentJavaScriptStyles();
|
74
|
+
equals(current, null, "There should be no current style yet.");
|
75
|
+
|
76
|
+
// create the layer
|
77
|
+
view.createLayer();
|
78
|
+
view.updateLayer();
|
79
|
+
|
80
|
+
// check again. Now, we should have a style
|
81
|
+
current = view.getCurrentJavaScriptStyles();
|
82
|
+
ok(!SC.none(current), "There now SHOULD be a current JS style.");
|
83
|
+
|
84
|
+
// and now, make sure we have both style AND layout set properly.
|
85
|
+
equals(current["opacity"], .5, "opacity should be .5");
|
86
|
+
equals(current["left"], 100, "left should be 100");
|
87
|
+
|
88
|
+
// go back to the beginning
|
89
|
+
SC.Animatable.enableCSSTransitions = original_transition_enabled;
|
90
|
+
});
|
@@ -1683,6 +1683,52 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
1683
1683
|
array.length = 0 ;
|
1684
1684
|
return this;
|
1685
1685
|
},
|
1686
|
+
|
1687
|
+
/**
|
1688
|
+
Convenience method can be called by the store or other parts of your
|
1689
|
+
application to load a record into the store. This method will take a
|
1690
|
+
recordType and a data hashes and either add or update the
|
1691
|
+
record in the store.
|
1692
|
+
|
1693
|
+
The loaded records will be in an SC.Record.READY_CLEAN state, indicating
|
1694
|
+
they were loaded from the data source and do not need to be committed
|
1695
|
+
back before changing.
|
1696
|
+
|
1697
|
+
This method will check the state of the storeKey and call either
|
1698
|
+
pushRetrieve() or dataSourceDidComplete(). The standard state constraints
|
1699
|
+
for these methods apply here.
|
1700
|
+
|
1701
|
+
The return value will be the storeKey used for the push. This is often
|
1702
|
+
convenient to pass into loadQuery(), if you are fetching a remote query.
|
1703
|
+
|
1704
|
+
If you are upgrading from a pre SproutCore 1.0 application, this method
|
1705
|
+
is the closest to the old updateRecord().
|
1706
|
+
|
1707
|
+
@param {SC.Record} recordType the record type
|
1708
|
+
@param {Array} dataHash to update
|
1709
|
+
@param {Array} id optional. if not passed lookup on the hash
|
1710
|
+
@returns {String} store keys assigned to these id
|
1711
|
+
*/
|
1712
|
+
loadRecord: function(recordType, dataHash, id) {
|
1713
|
+
var K = SC.Record,
|
1714
|
+
ret, primaryKey, dataHash, storeKey;
|
1715
|
+
|
1716
|
+
// save lookup info
|
1717
|
+
recordType = recordType || SC.Record;
|
1718
|
+
primaryKey = recordType.prototype.primaryKey;
|
1719
|
+
|
1720
|
+
|
1721
|
+
// push each record
|
1722
|
+
id = id || dataHash[primaryKey];
|
1723
|
+
ret = storeKey = recordType.storeKeyFor(id); // needed to cache
|
1724
|
+
|
1725
|
+
if (this.readStatus(storeKey) & K.BUSY) {
|
1726
|
+
this.dataSourceDidComplete(storeKey, dataHash, id);
|
1727
|
+
} else this.pushRetrieve(recordType, id, dataHash, storeKey);
|
1728
|
+
|
1729
|
+
// return storeKey
|
1730
|
+
return ret ;
|
1731
|
+
},
|
1686
1732
|
|
1687
1733
|
/**
|
1688
1734
|
Convenience method can be called by the store or other parts of your
|
@@ -1730,11 +1776,8 @@ SC.Store = SC.Object.extend( /** @scope SC.Store.prototype */ {
|
|
1730
1776
|
primaryKey = recordType.prototype.primaryKey ;
|
1731
1777
|
}
|
1732
1778
|
id = (ids) ? ids.objectAt(idx) : dataHash[primaryKey];
|
1733
|
-
ret[idx] =
|
1779
|
+
ret[idx] = this.loadRecord(recordType, dataHash, id);
|
1734
1780
|
|
1735
|
-
if (this.readStatus(storeKey) & K.BUSY) {
|
1736
|
-
this.dataSourceDidComplete(storeKey, dataHash, id);
|
1737
|
-
} else this.pushRetrieve(recordType, id, dataHash, storeKey);
|
1738
1781
|
}
|
1739
1782
|
|
1740
1783
|
// return storeKeys
|
@@ -168,6 +168,7 @@ SC.Button = {
|
|
168
168
|
// get the icon. If there is an icon, then get the image and update it.
|
169
169
|
// if there is no image element yet, create it and insert it just before
|
170
170
|
// title.
|
171
|
+
|
171
172
|
if (icon) {
|
172
173
|
var blank = SC.BLANK_IMAGE_URL;
|
173
174
|
|
@@ -192,10 +193,16 @@ SC.Button = {
|
|
192
193
|
if(needsTitle) {
|
193
194
|
if(this.get('needsEllipsis')){
|
194
195
|
elem.addClass('ellipsis');
|
195
|
-
if(this._ImageTitleCached !== imgTitle)
|
196
|
+
if(this._ImageTitleCached !== imgTitle) {
|
197
|
+
this._ImageTitleCached = imgTitle; // Update the cache
|
198
|
+
htmlNode.innerHTML = imgTitle;
|
199
|
+
}
|
196
200
|
}else{
|
197
201
|
elem.removeClass('ellipsis');
|
198
|
-
if(this._ImageTitleCached !== imgTitle)
|
202
|
+
if(this._ImageTitleCached !== imgTitle) {
|
203
|
+
this._ImageTitleCached = imgTitle; // Update the cache
|
204
|
+
htmlNode.innerHTML = imgTitle;
|
205
|
+
}
|
199
206
|
}
|
200
207
|
}
|
201
208
|
else { htmlNode.innerHTML = ''; }
|