Keyboard shortcuts optimizations (#70, #109)

This commit is contained in:
RainLoop Team 2014-04-08 23:22:17 +04:00
parent 0b30bac43f
commit 05f455c34e
17 changed files with 400 additions and 264 deletions

View file

@ -158,6 +158,13 @@ NewHtmlEditorWrapper.prototype.init = function ()
oConfig.language = Globals.oHtmlEditorLangsMap[sLanguage] || 'en'; oConfig.language = Globals.oHtmlEditorLangsMap[sLanguage] || 'en';
self.editor = window.CKEDITOR.appendTo(self.$element[0], oConfig); self.editor = window.CKEDITOR.appendTo(self.$element[0], oConfig);
self.editor.on('key', function(oEvent) {
if (oEvent && oEvent.data && 9 === oEvent.data.keyCode)
{
return false;
}
});
self.editor.on('blur', function() { self.editor.on('blur', function() {
self.blurTrigger(); self.blurTrigger();
}); });

View file

@ -75,7 +75,15 @@ function Selector(oKoList, oKoFocusedItem, oKoSelectedItem,
if (this.useItemSelectCallback) if (this.useItemSelectCallback)
{ {
this.selectItemCallbacks(oItem); if (oItem)
{
this.selectItemCallbacks(oItem, !!oItem.__clicked);
oItem.__clicked = false;
}
else
{
this.selectItemCallbacks(null);
}
} }
}, this); }, this);
@ -169,19 +177,19 @@ function Selector(oKoList, oKoFocusedItem, oKoSelectedItem,
this.selectItemCallbacksThrottle = _.debounce(this.selectItemCallbacks, 300); this.selectItemCallbacksThrottle = _.debounce(this.selectItemCallbacks, 300);
} }
Selector.prototype.selectItemCallbacks = function (oItem) Selector.prototype.selectItemCallbacks = function (oItem, bClick)
{ {
(this.oCallbacks['onItemSelect'] || this.emptyFunction)(oItem); (this.oCallbacks['onItemSelect'] || this.emptyFunction)(oItem, bClick);
}; };
Selector.prototype.goDown = function () Selector.prototype.goDown = function (bForceSelect)
{ {
this.newSelectPosition(Enums.EventKeyCode.Down, false); this.newSelectPosition(Enums.EventKeyCode.Down, false, bForceSelect);
}; };
Selector.prototype.goUp = function () Selector.prototype.goUp = function (bForceSelect)
{ {
this.newSelectPosition(Enums.EventKeyCode.Up, false); this.newSelectPosition(Enums.EventKeyCode.Up, false, bForceSelect);
}; };
Selector.prototype.init = function (oContentVisible, oContentScrollable, sKeyScope) Selector.prototype.init = function (oContentVisible, oContentScrollable, sKeyScope)
@ -205,7 +213,8 @@ Selector.prototype.init = function (oContentVisible, oContentScrollable, sKeySco
} }
}) })
.on('click', this.sItemSelector, function (oEvent) { .on('click', this.sItemSelector, function (oEvent) {
self.actionClick(ko.dataFor(this), oEvent); self.actionClick(ko.dataFor(this), oEvent, true);
return false;
}) })
.on('click', this.sItemCheckedSelector, function (oEvent) { .on('click', this.sItemCheckedSelector, function (oEvent) {
var oItem = ko.dataFor(this); var oItem = ko.dataFor(this);
@ -244,6 +253,10 @@ Selector.prototype.init = function (oContentVisible, oContentScrollable, sKeySco
} }
}); });
key('ctrl+up, command+up, ctrl+down, command+down', sKeyScope, function () {
return false;
});
key('up, shift+up, down, shift+down, home, end, pageup, pagedown, insert, space', sKeyScope, function (event, handler) { key('up, shift+up, down, shift+down, home, end, pageup, pagedown, insert, space', sKeyScope, function (event, handler) {
if (event && handler && handler.shortcut) if (event && handler && handler.shortcut)
{ {
@ -340,8 +353,9 @@ Selector.prototype.getItemUid = function (oItem)
/** /**
* @param {number} iEventKeyCode * @param {number} iEventKeyCode
* @param {boolean} bShiftKey * @param {boolean} bShiftKey
* @param {boolean=} bForceSelect = false
*/ */
Selector.prototype.newSelectPosition = function (iEventKeyCode, bShiftKey) Selector.prototype.newSelectPosition = function (iEventKeyCode, bShiftKey, bForceSelect)
{ {
var var
self = this, self = this,
@ -462,7 +476,7 @@ Selector.prototype.newSelectPosition = function (iEventKeyCode, bShiftKey)
this.focusedItem(oResult); this.focusedItem(oResult);
if (this.bAutoSelect && Enums.EventKeyCode.Space !== iEventKeyCode) if ((this.bAutoSelect || !!bForceSelect) && Enums.EventKeyCode.Space !== iEventKeyCode)
{ {
window.clearTimeout(this.iSelectTimer); window.clearTimeout(this.iSelectTimer);
this.iSelectTimer = window.setTimeout(function () { this.iSelectTimer = window.setTimeout(function () {
@ -572,8 +586,9 @@ Selector.prototype.eventClickFunction = function (oItem, oEvent)
/** /**
* @param {Object} oItem * @param {Object} oItem
* @param {Object=} oEvent * @param {Object=} oEvent
* @param {boolean=} bRealClick
*/ */
Selector.prototype.actionClick = function (oItem, oEvent) Selector.prototype.actionClick = function (oItem, oEvent, bRealClick)
{ {
if (oItem) if (oItem)
{ {
@ -607,6 +622,11 @@ Selector.prototype.actionClick = function (oItem, oEvent)
if (bClick) if (bClick)
{ {
if (bRealClick)
{
oItem.__clicked = true;
}
this.selectedItem(oItem); this.selectedItem(oItem);
} }
} }

View file

@ -1235,6 +1235,17 @@ Utils.removeBlockquoteSwitcher = function (oMessageTextBody)
} }
}; };
/**
* @param {Object} oMessageTextBody
*/
Utils.toggleMessageBlockquote = function (oMessageTextBody)
{
if (oMessageTextBody)
{
oMessageTextBody.find('.rlBlockquoteSwitcher').click();
}
};
/** /**
* @param {string} sName * @param {string} sName
* @param {Function} ViewModelClass * @param {Function} ViewModelClass

View file

@ -262,6 +262,7 @@ function WebMailDataStorage()
if (!oMessage) if (!oMessage)
{ {
this.message.focused(false); this.message.focused(false);
this.hideMessageBodies();
} }
else if (Enums.Layout.NoPreview === this.layout()) else if (Enums.Layout.NoPreview === this.layout())
{ {
@ -303,7 +304,6 @@ function WebMailDataStorage()
if (null === oMessage) if (null === oMessage)
{ {
this.currentMessage(null); this.currentMessage(null);
this.hideMessageBodies();
} }
}, this); }, this);

View file

@ -196,16 +196,21 @@ function MailBoxMessageListViewModel()
'.messageListItem .actionHandle', '.messageListItem.selected', '.messageListItem .checkboxMessage', '.messageListItem .actionHandle', '.messageListItem.selected', '.messageListItem .checkboxMessage',
'.messageListItem.focused'); '.messageListItem.focused');
this.selector.on('onItemSelect', _.bind(function (oMessage) { this.selector.on('onItemSelect', _.bind(function (oMessage, bClick) {
if (oMessage) if (oMessage)
{ {
oData.message(oData.staticMessageList.populateByMessageListItem(oMessage));
this.populateMessageBody(oData.message());
if (Enums.Layout.NoPreview === oData.layout()) if (Enums.Layout.NoPreview === oData.layout())
{ {
kn.setHash(RL.link().messagePreview(), true); kn.setHash(RL.link().messagePreview(), true);
oData.message.focused(true);
}
else if (bClick)
{
oData.message.focused(false);
} }
oData.message(oData.staticMessageList.populateByMessageListItem(oMessage));
this.populateMessageBody(oData.message());
} }
else else
{ {
@ -226,10 +231,10 @@ function MailBoxMessageListViewModel()
RL RL
.sub('mailbox.message-list.selector.go-down', function () { .sub('mailbox.message-list.selector.go-down', function () {
this.selector.goDown(); this.selector.goDown(true);
}, this) }, this)
.sub('mailbox.message-list.selector.go-up', function () { .sub('mailbox.message-list.selector.go-up', function () {
this.selector.goUp(); this.selector.goUp(true);
}, this) }, this)
; ;
@ -696,7 +701,7 @@ MailBoxMessageListViewModel.prototype.initShortcuts = function ()
}); });
// change focused state // change focused state
key('tab', Enums.KeyState.MessageList, function () { key('tab, shift+tab', Enums.KeyState.MessageList, function () {
if (oData.useKeyboardShortcuts()) if (oData.useKeyboardShortcuts())
{ {
if (self.message()) if (self.message())

View file

@ -450,15 +450,16 @@ MailBoxMessageViewViewModel.prototype.initShortcuts = function ()
} }
}); });
key('ctrl+left, command+left', Enums.KeyState.MessageView, function () { // toggle message blockquotes
if (oData.useKeyboardShortcuts()) key('b', Enums.KeyState.MessageView, function () {
if (oData.useKeyboardShortcuts() && oData.message() && oData.message().body)
{ {
self.goDownCommand(); Utils.toggleMessageBlockquote(oData.message().body);
return false; return false;
} }
}); });
key('ctrl+right, command+right', Enums.KeyState.MessageView, function () { key('ctrl+left, command+left, ctrl+up, command+up', Enums.KeyState.MessageView, function () {
if (oData.useKeyboardShortcuts()) if (oData.useKeyboardShortcuts())
{ {
self.goUpCommand(); self.goUpCommand();
@ -466,6 +467,14 @@ MailBoxMessageViewViewModel.prototype.initShortcuts = function ()
} }
}); });
key('ctrl+right, command+right, ctrl+down, command+down', Enums.KeyState.MessageView, function () {
if (oData.useKeyboardShortcuts())
{
self.goDownCommand();
return false;
}
});
// print // print
key('ctrl+p, command+p', Enums.KeyState.MessageView, function () { key('ctrl+p, command+p', Enums.KeyState.MessageView, function () {
if (oData.useKeyboardShortcuts()) if (oData.useKeyboardShortcuts())
@ -505,7 +514,7 @@ MailBoxMessageViewViewModel.prototype.initShortcuts = function ()
}); });
// change focused state // change focused state
key('tab', Enums.KeyState.MessageView, function () { key('tab, shift+tab', Enums.KeyState.MessageView, function () {
if (oData.useKeyboardShortcuts()) if (oData.useKeyboardShortcuts())
{ {
if (!self.fullScreenMode() && self.message()) if (!self.fullScreenMode() && self.message())

View file

@ -92,7 +92,7 @@
<span class="i18n" data-i18n-text="COMPOSE/TITLE_SUBJECT"></span> <span class="i18n" data-i18n-text="COMPOSE/TITLE_SUBJECT"></span>
</div> </div>
<div class="e-cell e-value"> <div class="e-cell e-value">
<input type="text" size="70" data-bind="value: subject" /> <input type="text" size="70" data-bind="value: subject, valueUpdate: 'afterkeydown'" />
</div> </div>
</div> </div>
<div class="e-row"> <div class="e-row">

View file

@ -1581,7 +1581,7 @@ table {
height : 5px; height : 5px;
} }
.nano:hover > .pane, .nano:hover > .pane2, .pane.active, .pane2.active, .pane.flashed, .pane2.flashed { .nano:hover > .pane, .nano:hover > .pane2, .pane.activescroll, .pane2.activescroll, .pane.active, .pane2.active, .pane.flashed, .pane2.flashed {
visibility : visible\9; /* Target only IE7 and IE8 with this hack */ visibility : visible\9; /* Target only IE7 and IE8 with this hack */
opacity : 0.99; opacity : 0.99;
filter: alpha(opacity=99); filter: alpha(opacity=99);

File diff suppressed because one or more lines are too long

View file

@ -1950,6 +1950,17 @@ Utils.removeBlockquoteSwitcher = function (oMessageTextBody)
} }
}; };
/**
* @param {Object} oMessageTextBody
*/
Utils.toggleMessageBlockquote = function (oMessageTextBody)
{
if (oMessageTextBody)
{
oMessageTextBody.find('.rlBlockquoteSwitcher').click();
}
};
/** /**
* @param {string} sName * @param {string} sName
* @param {Function} ViewModelClass * @param {Function} ViewModelClass

File diff suppressed because one or more lines are too long

View file

@ -1954,6 +1954,17 @@ Utils.removeBlockquoteSwitcher = function (oMessageTextBody)
} }
}; };
/**
* @param {Object} oMessageTextBody
*/
Utils.toggleMessageBlockquote = function (oMessageTextBody)
{
if (oMessageTextBody)
{
oMessageTextBody.find('.rlBlockquoteSwitcher').click();
}
};
/** /**
* @param {string} sName * @param {string} sName
* @param {Function} ViewModelClass * @param {Function} ViewModelClass
@ -3823,6 +3834,13 @@ NewHtmlEditorWrapper.prototype.init = function ()
oConfig.language = Globals.oHtmlEditorLangsMap[sLanguage] || 'en'; oConfig.language = Globals.oHtmlEditorLangsMap[sLanguage] || 'en';
self.editor = window.CKEDITOR.appendTo(self.$element[0], oConfig); self.editor = window.CKEDITOR.appendTo(self.$element[0], oConfig);
self.editor.on('key', function(oEvent) {
if (oEvent && oEvent.data && 9 === oEvent.data.keyCode)
{
return false;
}
});
self.editor.on('blur', function() { self.editor.on('blur', function() {
self.blurTrigger(); self.blurTrigger();
}); });
@ -3959,7 +3977,15 @@ function Selector(oKoList, oKoFocusedItem, oKoSelectedItem,
if (this.useItemSelectCallback) if (this.useItemSelectCallback)
{ {
this.selectItemCallbacks(oItem); if (oItem)
{
this.selectItemCallbacks(oItem, !!oItem.__clicked);
oItem.__clicked = false;
}
else
{
this.selectItemCallbacks(null);
}
} }
}, this); }, this);
@ -4053,19 +4079,19 @@ function Selector(oKoList, oKoFocusedItem, oKoSelectedItem,
this.selectItemCallbacksThrottle = _.debounce(this.selectItemCallbacks, 300); this.selectItemCallbacksThrottle = _.debounce(this.selectItemCallbacks, 300);
} }
Selector.prototype.selectItemCallbacks = function (oItem) Selector.prototype.selectItemCallbacks = function (oItem, bClick)
{ {
(this.oCallbacks['onItemSelect'] || this.emptyFunction)(oItem); (this.oCallbacks['onItemSelect'] || this.emptyFunction)(oItem, bClick);
}; };
Selector.prototype.goDown = function () Selector.prototype.goDown = function (bForceSelect)
{ {
this.newSelectPosition(Enums.EventKeyCode.Down, false); this.newSelectPosition(Enums.EventKeyCode.Down, false, bForceSelect);
}; };
Selector.prototype.goUp = function () Selector.prototype.goUp = function (bForceSelect)
{ {
this.newSelectPosition(Enums.EventKeyCode.Up, false); this.newSelectPosition(Enums.EventKeyCode.Up, false, bForceSelect);
}; };
Selector.prototype.init = function (oContentVisible, oContentScrollable, sKeyScope) Selector.prototype.init = function (oContentVisible, oContentScrollable, sKeyScope)
@ -4089,7 +4115,8 @@ Selector.prototype.init = function (oContentVisible, oContentScrollable, sKeySco
} }
}) })
.on('click', this.sItemSelector, function (oEvent) { .on('click', this.sItemSelector, function (oEvent) {
self.actionClick(ko.dataFor(this), oEvent); self.actionClick(ko.dataFor(this), oEvent, true);
return false;
}) })
.on('click', this.sItemCheckedSelector, function (oEvent) { .on('click', this.sItemCheckedSelector, function (oEvent) {
var oItem = ko.dataFor(this); var oItem = ko.dataFor(this);
@ -4128,6 +4155,10 @@ Selector.prototype.init = function (oContentVisible, oContentScrollable, sKeySco
} }
}); });
key('ctrl+up, command+up, ctrl+down, command+down', sKeyScope, function () {
return false;
});
key('up, shift+up, down, shift+down, home, end, pageup, pagedown, insert, space', sKeyScope, function (event, handler) { key('up, shift+up, down, shift+down, home, end, pageup, pagedown, insert, space', sKeyScope, function (event, handler) {
if (event && handler && handler.shortcut) if (event && handler && handler.shortcut)
{ {
@ -4224,8 +4255,9 @@ Selector.prototype.getItemUid = function (oItem)
/** /**
* @param {number} iEventKeyCode * @param {number} iEventKeyCode
* @param {boolean} bShiftKey * @param {boolean} bShiftKey
* @param {boolean=} bForceSelect = false
*/ */
Selector.prototype.newSelectPosition = function (iEventKeyCode, bShiftKey) Selector.prototype.newSelectPosition = function (iEventKeyCode, bShiftKey, bForceSelect)
{ {
var var
self = this, self = this,
@ -4346,7 +4378,7 @@ Selector.prototype.newSelectPosition = function (iEventKeyCode, bShiftKey)
this.focusedItem(oResult); this.focusedItem(oResult);
if (this.bAutoSelect && Enums.EventKeyCode.Space !== iEventKeyCode) if ((this.bAutoSelect || !!bForceSelect) && Enums.EventKeyCode.Space !== iEventKeyCode)
{ {
window.clearTimeout(this.iSelectTimer); window.clearTimeout(this.iSelectTimer);
this.iSelectTimer = window.setTimeout(function () { this.iSelectTimer = window.setTimeout(function () {
@ -4456,8 +4488,9 @@ Selector.prototype.eventClickFunction = function (oItem, oEvent)
/** /**
* @param {Object} oItem * @param {Object} oItem
* @param {Object=} oEvent * @param {Object=} oEvent
* @param {boolean=} bRealClick
*/ */
Selector.prototype.actionClick = function (oItem, oEvent) Selector.prototype.actionClick = function (oItem, oEvent, bRealClick)
{ {
if (oItem) if (oItem)
{ {
@ -4491,6 +4524,11 @@ Selector.prototype.actionClick = function (oItem, oEvent)
if (bClick) if (bClick)
{ {
if (bRealClick)
{
oItem.__clicked = true;
}
this.selectedItem(oItem); this.selectedItem(oItem);
} }
} }
@ -11924,16 +11962,21 @@ function MailBoxMessageListViewModel()
'.messageListItem .actionHandle', '.messageListItem.selected', '.messageListItem .checkboxMessage', '.messageListItem .actionHandle', '.messageListItem.selected', '.messageListItem .checkboxMessage',
'.messageListItem.focused'); '.messageListItem.focused');
this.selector.on('onItemSelect', _.bind(function (oMessage) { this.selector.on('onItemSelect', _.bind(function (oMessage, bClick) {
if (oMessage) if (oMessage)
{ {
oData.message(oData.staticMessageList.populateByMessageListItem(oMessage));
this.populateMessageBody(oData.message());
if (Enums.Layout.NoPreview === oData.layout()) if (Enums.Layout.NoPreview === oData.layout())
{ {
kn.setHash(RL.link().messagePreview(), true); kn.setHash(RL.link().messagePreview(), true);
oData.message.focused(true);
}
else if (bClick)
{
oData.message.focused(false);
} }
oData.message(oData.staticMessageList.populateByMessageListItem(oMessage));
this.populateMessageBody(oData.message());
} }
else else
{ {
@ -11954,10 +11997,10 @@ function MailBoxMessageListViewModel()
RL RL
.sub('mailbox.message-list.selector.go-down', function () { .sub('mailbox.message-list.selector.go-down', function () {
this.selector.goDown(); this.selector.goDown(true);
}, this) }, this)
.sub('mailbox.message-list.selector.go-up', function () { .sub('mailbox.message-list.selector.go-up', function () {
this.selector.goUp(); this.selector.goUp(true);
}, this) }, this)
; ;
@ -12424,7 +12467,7 @@ MailBoxMessageListViewModel.prototype.initShortcuts = function ()
}); });
// change focused state // change focused state
key('tab', Enums.KeyState.MessageList, function () { key('tab, shift+tab', Enums.KeyState.MessageList, function () {
if (oData.useKeyboardShortcuts()) if (oData.useKeyboardShortcuts())
{ {
if (self.message()) if (self.message())
@ -13009,15 +13052,16 @@ MailBoxMessageViewViewModel.prototype.initShortcuts = function ()
} }
}); });
key('ctrl+left, command+left', Enums.KeyState.MessageView, function () { // toggle message blockquotes
if (oData.useKeyboardShortcuts()) key('b', Enums.KeyState.MessageView, function () {
if (oData.useKeyboardShortcuts() && oData.message() && oData.message().body)
{ {
self.goDownCommand(); Utils.toggleMessageBlockquote(oData.message().body);
return false; return false;
} }
}); });
key('ctrl+right, command+right', Enums.KeyState.MessageView, function () { key('ctrl+left, command+left, ctrl+up, command+up', Enums.KeyState.MessageView, function () {
if (oData.useKeyboardShortcuts()) if (oData.useKeyboardShortcuts())
{ {
self.goUpCommand(); self.goUpCommand();
@ -13025,6 +13069,14 @@ MailBoxMessageViewViewModel.prototype.initShortcuts = function ()
} }
}); });
key('ctrl+right, command+right, ctrl+down, command+down', Enums.KeyState.MessageView, function () {
if (oData.useKeyboardShortcuts())
{
self.goDownCommand();
return false;
}
});
// print // print
key('ctrl+p, command+p', Enums.KeyState.MessageView, function () { key('ctrl+p, command+p', Enums.KeyState.MessageView, function () {
if (oData.useKeyboardShortcuts()) if (oData.useKeyboardShortcuts())
@ -13064,7 +13116,7 @@ MailBoxMessageViewViewModel.prototype.initShortcuts = function ()
}); });
// change focused state // change focused state
key('tab', Enums.KeyState.MessageView, function () { key('tab, shift+tab', Enums.KeyState.MessageView, function () {
if (oData.useKeyboardShortcuts()) if (oData.useKeyboardShortcuts())
{ {
if (!self.fullScreenMode() && self.message()) if (!self.fullScreenMode() && self.message())
@ -14889,6 +14941,7 @@ function WebMailDataStorage()
if (!oMessage) if (!oMessage)
{ {
this.message.focused(false); this.message.focused(false);
this.hideMessageBodies();
} }
else if (Enums.Layout.NoPreview === this.layout()) else if (Enums.Layout.NoPreview === this.layout())
{ {
@ -14930,7 +14983,6 @@ function WebMailDataStorage()
if (null === oMessage) if (null === oMessage)
{ {
this.currentMessage(null); this.currentMessage(null);
this.hideMessageBodies();
} }
}, this); }, this);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -336,6 +336,23 @@
*/ */
NanoScroll.prototype.scrollClassTimer = 0;
NanoScroll.prototype.scrollClassTrigger = function() {
window.clearTimeout(this.scrollClassTimer);
var _this = this;
_this.pane.addClass('activescroll');
_this.pane2.addClass('activescroll');
this.scrollClassTimer = window.setTimeout(function () {
_this.pane.removeClass('activescroll');
_this.pane2.removeClass('activescroll');
}, 1000);
};
NanoScroll.prototype.nativeScrolling = function() { NanoScroll.prototype.nativeScrolling = function() {
this.$content.css({ this.$content.css({
WebkitOverflowScrolling: 'touch' WebkitOverflowScrolling: 'touch'
@ -366,7 +383,7 @@
this.sliderTop = this.contentScrollTop * this.maxSliderTop / this.maxScrollTop; this.sliderTop = this.contentScrollTop * this.maxSliderTop / this.maxScrollTop;
this.slider2Left = this.contentScroll2Left * this.maxSlider2Left / this.maxScroll2Left; this.slider2Left = this.contentScroll2Left * this.maxSlider2Left / this.maxScroll2Left;
} }
}; };
/** /**
Creates event related methods Creates event related methods
@ -471,6 +488,10 @@
} }
_this.$el.trigger('scrolltop'); _this.$el.trigger('scrolltop');
} }
if (!_this.iOSNativeScrolling) {
_this.scrollClassTrigger();
}
}, },
/** /**
* @param {{wheelDeltaY:number, delta:number}} e * @param {{wheelDeltaY:number, delta:number}} e

View file

@ -95,7 +95,7 @@
height : 5px; height : 5px;
} }
.nano:hover > .pane, .nano:hover > .pane2, .pane.active, .pane2.active, .pane.flashed, .pane2.flashed { .nano:hover > .pane, .nano:hover > .pane2, .pane.activescroll, .pane2.activescroll, .pane.active, .pane2.active, .pane.flashed, .pane2.flashed {
visibility : visible\9; /* Target only IE7 and IE8 with this hack */ visibility : visible\9; /* Target only IE7 and IE8 with this hack */
opacity : 0.99; opacity : 0.99;
filter: alpha(opacity=99); filter: alpha(opacity=99);