Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions src/browser/eventPlugins/ChangeEventPlugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

"use strict";

var ExecutionEnvironment = require('ExecutionEnvironment');

var EventConstants = require('EventConstants');
var EventPluginHub = require('EventPluginHub');
var EventPropagators = require('EventPropagators');
Expand Down Expand Up @@ -340,10 +342,10 @@ var ChangeEventPlugin = {

var getTargetIDFunc, handleEventFunc;
if (shouldUseChangeEvent(topLevelTarget)) {
if (doesChangeEventBubble) {
getTargetIDFunc = getTargetIDForChangeEvent;
} else {
if (ExecutionEnvironment.isIE8) {
handleEventFunc = handleEventsForChangeEventIE8;
} else {
getTargetIDFunc = getTargetIDForChangeEvent;
}
} else if (isTextInputElement(topLevelTarget)) {
if (isInputEventSupported) {
Expand Down
10 changes: 4 additions & 6 deletions src/browser/eventPlugins/EnterLeaveEventPlugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

"use strict";

var ExecutionEnvironment = require('ExecutionEnvironment');

var EventConstants = require('EventConstants');
var EventPropagators = require('EventPropagators');
var SyntheticMouseEvent = require('SyntheticMouseEvent');
Expand Down Expand Up @@ -87,12 +89,8 @@ var EnterLeaveEventPlugin = {
win = topLevelTarget;
} else {
// TODO: Figure out why `ownerDocument` is sometimes undefined in IE8.
var doc = topLevelTarget.ownerDocument;
if (doc) {
win = doc.defaultView || doc.parentWindow;
} else {
win = window;
}
var doc = topLevelTarget.ownerDocument || document;
win = ExecutionEnvironment.isIE8 ? doc.parentWindow : doc.defaultView;
}

var from, to;
Expand Down
25 changes: 14 additions & 11 deletions src/browser/syntheticEvents/SyntheticMouseEvent.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

"use strict";

var ExecutionEnvironment = require('ExecutionEnvironment');
var SyntheticUIEvent = require('SyntheticUIEvent');
var ViewportMetrics = require('ViewportMetrics');

Expand All @@ -42,15 +43,16 @@ var MouseEventInterface = {
// Webkit, Firefox, IE9+
// which: 1 2 3
// button: 0 1 2 (standard)
var button = event.button;
if ('which' in event) {
return button;
}

// IE<9
// which: undefined
// button: 0 0 0
// button: 1 4 2 (onmouseup)
return button === 2 ? 2 : button === 4 ? 1 : 0;

// IE8: uses non-standard button values
return ExecutionEnvironment.isIE8 ?
(button === 2 ? 2 : button === 4 ? 1 : 0) :
event.button;
},
buttons: null,
relatedTarget: function(event) {
Expand All @@ -61,15 +63,16 @@ var MouseEventInterface = {
);
},
// "Proprietary" Interface.
// IE8: does not support pageX/Y
pageX: function(event) {
return 'pageX' in event ?
event.pageX :
event.clientX + ViewportMetrics.currentScrollLeft;
return ExecutionEnvironment.isIE8 ?
event.clientX + ViewportMetrics.currentScrollLeft :
event.pageX;
},
pageY: function(event) {
return 'pageY' in event ?
event.pageY :
event.clientY + ViewportMetrics.currentScrollTop;
return ExecutionEnvironment.isIE8 ?
event.clientY + ViewportMetrics.currentScrollTop :
event.pageY;
}
};

Expand Down
9 changes: 3 additions & 6 deletions src/browser/syntheticEvents/SyntheticUIEvent.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

"use strict";

var ExecutionEnvironment = require('ExecutionEnvironment');
var SyntheticEvent = require('SyntheticEvent');

var getEventTarget = require('getEventTarget');
Expand All @@ -39,13 +40,9 @@ var UIEventInterface = {
return target;
}

var doc = target.ownerDocument;
// TODO: Figure out why `ownerDocument` is sometimes undefined in IE8.
if (doc) {
return doc.defaultView || doc.parentWindow;
} else {
return window;
}
var doc = target.ownerDocument || document;
win = ExecutionEnvironment.isIE8 ? doc.parentWindow : doc.defaultView;
},
detail: function(event) {
return event.detail || 0;
Expand Down
10 changes: 7 additions & 3 deletions src/browser/syntheticEvents/SyntheticWheelEvent.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

"use strict";

var ExecutionEnvironment = require('ExecutionEnvironment');
var SyntheticMouseEvent = require('SyntheticMouseEvent');

/**
Expand All @@ -34,12 +35,15 @@ var WheelEventInterface = {
);
},
deltaY: function(event) {
if (ExecutionEnvironment.isIE8) {
// Fallback to `wheelDelta` for IE<9 and normalize (down is positive).
return -event.wheelDelta;
}

return (
'deltaY' in event ? event.deltaY :
// Fallback to `wheelDeltaY` for Webkit and normalize (down is positive).
'wheelDeltaY' in event ? -event.wheelDeltaY :
// Fallback to `wheelDelta` for IE<9 and normalize (down is positive).
'wheelDelta' in event ? -event.wheelDelta : 0
'wheelDeltaY' in event ? -event.wheelDeltaY : 0
);
},
deltaZ: null,
Expand Down
44 changes: 25 additions & 19 deletions src/browser/ui/ReactInputSelection.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

"use strict";

var ExecutionEnvironment = require('ExecutionEnvironment');

var ReactDOMSelection = require('ReactDOMSelection');

var containsNode = require('containsNode');
Expand Down Expand Up @@ -85,23 +87,25 @@ var ReactInputSelection = {
getSelection: function(input) {
var selection;

if ('selectionStart' in input) {
if (ExecutionEnvironment.isIE8) {
if (document.selection && input.nodeName === 'INPUT') {
// IE8 input.
var range = document.selection.createRange();
// There can only be one selection per document in IE, so it must
// be in our element.
if (range.parentElement() === input) {
selection = {
start: -range.moveStart('character', -input.value.length),
end: -range.moveEnd('character', -input.value.length)
};
}
}
} else if ('selectionStart' in input) {
// Modern browser with input or textarea.
selection = {
start: input.selectionStart,
end: input.selectionEnd
};
} else if (document.selection && input.nodeName === 'INPUT') {
// IE8 input.
var range = document.selection.createRange();
// There can only be one selection per document in IE, so it must
// be in our element.
if (range.parentElement() === input) {
selection = {
start: -range.moveStart('character', -input.value.length),
end: -range.moveEnd('character', -input.value.length)
};
}
} else {
// Content editable or old IE textarea.
selection = ReactDOMSelection.getOffsets(input);
Expand All @@ -123,15 +127,17 @@ var ReactInputSelection = {
end = start;
}

if ('selectionStart' in input) {
if (ExecutionEnvironment.isIE8) {
if (document.selection && input.nodeName === 'INPUT') {
var range = input.createTextRange();
range.collapse(true);
range.moveStart('character', start);
range.moveEnd('character', end - start);
range.select();
}
} else if ('selectionStart' in input) {
input.selectionStart = start;
input.selectionEnd = Math.min(end, input.value.length);
} else if (document.selection && input.nodeName === 'INPUT') {
var range = input.createTextRange();
range.collapse(true);
range.moveStart('character', start);
range.moveEnd('character', end - start);
range.select();
} else {
ReactDOMSelection.setOffsets(input, offsets);
}
Expand Down
4 changes: 3 additions & 1 deletion src/browser/ui/dom/CSSPropertyOperations.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

"use strict";

var ExecutionEnvironment = require('ExecutionEnvironment');

var CSSProperty = require('CSSProperty');

var dangerousStyleValue = require('dangerousStyleValue');
Expand Down Expand Up @@ -79,7 +81,7 @@ var CSSPropertyOperations = {
style[styleName] = styleValue;
} else {
var expansion = CSSProperty.shorthandPropertyExpansions[styleName];
if (expansion) {
if (ExecutionEnvironment.isIE8 && expansion) {
// Shorthand property that IE8 won't like unsetting, so unset each
// component to placate it
for (var individualStyleName in expansion) {
Expand Down
29 changes: 11 additions & 18 deletions src/browser/ui/dom/DOMChildrenOperations.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,24 +52,17 @@ function insertChildAt(parentNode, childNode, index) {
);
}

var updateTextContent;
if (textContentAccessor === 'textContent') {
/**
* Sets the text content of `node` to `text`.
*
* @param {DOMElement} node Node to change
* @param {string} text New text content
*/
updateTextContent = function(node, text) {
node.textContent = text;
};
} else {
/**
* Sets the text content of `node` to `text`.
*
* @param {DOMElement} node Node to change
* @param {string} text New text content
*/
/**
* Sets the text content of `node` to `text`.
*
* @param {DOMElement} node Node to change
* @param {string} text New text content
*/
var updateTextContent = function(node, text) {
node.textContent = text;
};

if (ExecutionEnvironment.isIE8) {
updateTextContent = function(node, text) {
// In order to preserve newlines correctly, we can't use .innerText to set
// the contents (see #1080), so we empty the element then append a text node
Expand Down
63 changes: 29 additions & 34 deletions src/browser/ui/dom/setInnerHTML.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,46 +32,41 @@ var setInnerHTML = function(node, html) {
node.innerHTML = html;
};

if (ExecutionEnvironment.canUseDOM) {
if (ExecutionEnvironment.isIE8) {
// IE8: When updating a just created node with innerHTML only leading
// whitespace is removed. When updating an existing node with innerHTML
// whitespace in root TextNodes is also collapsed.
// @see quirksmode.org/bugreports/archives/2004/11/innerhtml_and_t.html

// Feature detection; only IE8 is known to behave improperly like this.
var testElement = document.createElement('div');
testElement.innerHTML = ' ';
if (testElement.innerHTML === '') {
setInnerHTML = function(node, html) {
// Magic theory: IE8 supposedly differentiates between added and updated
// nodes when processing innerHTML, innerHTML on updated nodes suffers
// from worse whitespace behavior. Re-adding a node like this triggers
// the initial and more favorable whitespace behavior.
// TODO: What to do on a detached node?
if (node.parentNode) {
node.parentNode.replaceChild(node, node);
}
setInnerHTML = function(node, html) {
// Magic theory: IE8 supposedly differentiates between added and updated
// nodes when processing innerHTML, innerHTML on updated nodes suffers
// from worse whitespace behavior. Re-adding a node like this triggers
// the initial and more favorable whitespace behavior.
// TODO: What to do on a detached node?
if (node.parentNode) {
node.parentNode.replaceChild(node, node);
}

// We also implement a workaround for non-visible tags disappearing into
// thin air on IE8, this only happens if there is no visible text
// in-front of the non-visible tags. Piggyback on the whitespace fix
// and simply check if any non-visible tags appear in the source.
if (html.match(/^[ \r\n\t\f]/) ||
html[0] === '<' && (
html.indexOf('<noscript') !== -1 ||
html.indexOf('<script') !== -1 ||
html.indexOf('<style') !== -1 ||
html.indexOf('<meta') !== -1 ||
html.indexOf('<link') !== -1)) {
// Recover leading whitespace by temporarily prepending any character.
// \uFEFF has the potential advantage of being zero-width/invisible.
node.innerHTML = '\uFEFF' + html;
node.firstChild.deleteData(0, 1);
} else {
node.innerHTML = html;
}
};
}
// We also implement a workaround for non-visible tags disappearing into
// thin air on IE8, this only happens if there is no visible text
// in-front of the non-visible tags. Piggyback on the whitespace fix
// and simply check if any non-visible tags appear in the source.
if (html.match(/^[ \r\n\t\f]/) ||
html[0] === '<' && (
html.indexOf('<noscript') !== -1 ||
html.indexOf('<script') !== -1 ||
html.indexOf('<style') !== -1 ||
html.indexOf('<meta') !== -1 ||
html.indexOf('<link') !== -1)) {
// Recover leading whitespace by temporarily prepending any character.
// \uFEFF has the potential advantage of being zero-width/invisible.
node.innerHTML = '\uFEFF' + html;
node.firstChild.deleteData(0, 1);
} else {
node.innerHTML = html;
}
};
}

module.exports = setInnerHTML;
4 changes: 3 additions & 1 deletion src/vendor/core/ExecutionEnvironment.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
var canUseDOM = !!(
typeof window !== 'undefined' &&
window.document &&
window.document.createElement
document.createElement
);

/**
Expand All @@ -43,6 +43,8 @@ var ExecutionEnvironment = {

canUseViewport: canUseDOM && !!window.screen,

isIE8: canUseDOM && document.documentMode === 8,

isInWorker: !canUseDOM // For now, this is true - might change in the future.

};
Expand Down
9 changes: 8 additions & 1 deletion src/vendor/core/dom/focusNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,21 @@

"use strict";

var ExecutionEnvironment = require('ExecutionEnvironment');

/**
* IE8 throws if an input/textarea is disabled and we try to focus it.
* Focus only when necessary.
*
* @param {DOMElement} node input/textarea to focus
*/
function focusNode(node) {
if (!node.disabled) {
if (ExecutionEnvironment.isIE8) {
try {
node.focus();
} catch(e) {
}
} else {
node.focus();
}
}
Expand Down