diff --git a/docs/_posts/2014-09-03-introducing-the-jsx-specification.md b/docs/_posts/2014-09-03-introducing-the-jsx-specification.md
new file mode 100644
index 000000000000..ced22b4a6dda
--- /dev/null
+++ b/docs/_posts/2014-09-03-introducing-the-jsx-specification.md
@@ -0,0 +1,14 @@
+---
+title: "Introducing the JSX Specification"
+author: Sebastian Markbåge
+---
+
+At Facebook we've been using JSX for a long time. We originally introduced it to the world last year alongside React, but we actually used it in another form before that to create native DOM nodes. We've also seen some similar efforts grow out of our work in order to be used with other libraries and in interesting ways. At this point React JSX is just one of many implementations.
+
+In order to make it easier to implement new versions and to make sure that the syntax remains compatible, we're now formalizing the syntax of JSX in a stand-alone spec without any semantic meaning. It's completely stand-alone from React itself.
+
+Read the spec now at <http://facebook.github.io/jsx/>.
+
+This is not a proposal to be standardized in ECMAScript. It's just a reference document that transpiler writers and syntax highlighters can agree on. It's currently in a draft stage and will probably continue to be a living document.
+
+Feel free to [open an Issue](https://github.com/facebook/jsx/issues/new) or Pull Request if you find something wrong.
diff --git a/docs/docs/09.1-animation.md b/docs/docs/09.1-animation.md
index df7cfc72628d..53256dd5753e 100644
--- a/docs/docs/09.1-animation.md
+++ b/docs/docs/09.1-animation.md
@@ -85,7 +85,7 @@ You'll notice that when you try to remove an item `ReactCSSTransitionGroup` keep
 
 ### Animation Group Must Be Mounted To Work
 
-In order for it to apply transitions to its children, the `ReactCSSTransitionGroup` must already be mounted in the DOM. The example below would not work, because the `ReactCSSTransitionGroup` is being mounted along with the new item, instead of the new item being mounted within it. Compare this to the [Getting Started](/docs/docs/09.1-animation.md#getting-started) section above to see the difference.
+In order for it to apply transitions to its children, the `ReactCSSTransitionGroup` must already be mounted in the DOM. The example below would not work, because the `ReactCSSTransitionGroup` is being mounted along with the new item, instead of the new item being mounted within it. Compare this to the [Getting Started](#getting-started) section above to see the difference.
 
 ```javascript{12-14}
   render: function() {
diff --git a/docs/docs/ref-04-tags-and-attributes.md b/docs/docs/ref-04-tags-and-attributes.md
index f43b05cc3c4a..c0d0108190c2 100644
--- a/docs/docs/ref-04-tags-and-attributes.md
+++ b/docs/docs/ref-04-tags-and-attributes.md
@@ -17,8 +17,8 @@ The following HTML elements are supported:
 ```
 a abbr address area article aside audio b base bdi bdo big blockquote body br
 button canvas caption cite code col colgroup data datalist dd del details dfn
-div dl dt em embed fieldset figcaption figure footer form h1 h2 h3 h4 h5 h6
-head header hr html i iframe img input ins kbd keygen label legend li link
+dialog div dl dt em embed fieldset figcaption figure footer form h1 h2 h3 h4 h5
+h6 head header hr html i iframe img input ins kbd keygen label legend li link
 main map mark menu menuitem meta meter nav noscript object ol optgroup option
 output p param pre progress q rp rt ruby s samp script section select small
 source span strong style sub summary sup table tbody td textarea tfoot th
@@ -58,7 +58,7 @@ className cols colSpan content contentEditable contextMenu controls coords
 crossOrigin data dateTime defer dir disabled download draggable encType form
 formNoValidate frameBorder height hidden href hrefLang htmlFor httpEquiv icon
 id label lang list loop max maxLength mediaGroup method min multiple muted
-name noValidate pattern placeholder poster preload radioGroup readOnly rel
+name noValidate open pattern placeholder poster preload radioGroup readOnly rel
 required role rows rowSpan sandbox scope scrollLeft scrolling scrollTop
 seamless selected shape size span spellCheck src srcDoc srcSet start step
 style tabIndex target title type useMap value width wmode
diff --git a/src/browser/ReactDOM.js b/src/browser/ReactDOM.js
index 5c666d7adff6..bebd1aa98cc0 100644
--- a/src/browser/ReactDOM.js
+++ b/src/browser/ReactDOM.js
@@ -95,6 +95,7 @@ var ReactDOM = mapObject({
   del: false,
   details: false,
   dfn: false,
+  dialog: false,
   div: false,
   dl: false,
   dt: false,
diff --git a/src/browser/eventPlugins/ChangeEventPlugin.js b/src/browser/eventPlugins/ChangeEventPlugin.js
index 499a88280283..9e233b49eca6 100644
--- a/src/browser/eventPlugins/ChangeEventPlugin.js
+++ b/src/browser/eventPlugins/ChangeEventPlugin.js
@@ -153,50 +153,32 @@ if (ExecutionEnvironment.canUseDOM) {
   );
 }
 
-/**
- * (For old IE.) Replacement getter/setter for the `value` property that gets
- * set on the active element.
- */
-var newValueProp =  {
-  get: function() {
-    return activeElementValueProp.get.call(this);
-  },
-  set: function(val) {
-    // Cast to a string so we can do equality checks.
-    activeElementValue = '' + val;
-    activeElementValueProp.set.call(this, val);
-  }
-};
-
 /**
  * (For old IE.) Starts tracking propertychange events on the passed-in element
  * and override the value property so that we can distinguish user events from
  * value changes in JS.
+ * IE7 fix: changed behaviour choncerning IE7 does not support getter and setter
+ * To distinguish user events from value changes in JS special DOM attribute
+ * data-ie8_value is used
  */
 function startWatchingForValueChange(target, targetID) {
   activeElement = target;
   activeElementID = targetID;
   activeElementValue = target.value;
-  activeElementValueProp = Object.getOwnPropertyDescriptor(
-    target.constructor.prototype,
-    'value'
-  );
 
-  Object.defineProperty(activeElement, 'value', newValueProp);
   activeElement.attachEvent('onpropertychange', handlePropertyChange);
 }
 
 /**
  * (For old IE.) Removes the event listeners from the currently-tracked element,
  * if any exists.
+ * IE7 fix: do not need to delete value attribute anymore
  */
 function stopWatchingForValueChange() {
   if (!activeElement) {
     return;
   }
 
-  // delete restores the original property definition
-  delete activeElement.value;
   activeElement.detachEvent('onpropertychange', handlePropertyChange);
 
   activeElement = null;
@@ -213,6 +195,12 @@ function handlePropertyChange(nativeEvent) {
   if (nativeEvent.propertyName !== 'value') {
     return;
   }
+  // IE7 fix: check if JS value change was made.
+  // True if value and data-ie8_value attribute are equal
+  var oldvalue = nativeEvent.srcElement.getAttribute('data-ie8_value');
+  if (oldvalue !== activeElementValue) {
+    activeElementValue = oldvalue;
+  }
   var value = nativeEvent.srcElement.value;
   if (value === activeElementValue) {
     return;
diff --git a/src/browser/ui/ReactDOMIDOperations.js b/src/browser/ui/ReactDOMIDOperations.js
index ea206cd065b9..e822b55a9c31 100644
--- a/src/browser/ui/ReactDOMIDOperations.js
+++ b/src/browser/ui/ReactDOMIDOperations.js
@@ -30,6 +30,8 @@ var ReactPerf = require('ReactPerf');
 var invariant = require('invariant');
 var setInnerHTML = require('setInnerHTML');
 
+var ExecutionEnvironment = require("ExecutionEnvironment");
+
 /**
  * Errors for properties that should not be updated with `updatePropertyById()`.
  *
@@ -72,6 +74,17 @@ var ReactDOMIDOperations = {
       // from the DOM node instead of inadvertantly setting to a string. This
       // brings us in line with the same behavior we have on initial render.
       if (value != null) {
+        // IE7 fix: for input and textarea we set data-ie8_value attribute first
+        // to distinguish value setter made by JS from user event value changes
+        if (ExecutionEnvironment.canUseDOM && !!window.attachEvent &&
+            name === 'value' &&
+            (node.tagName === 'INPUT' || node.tagName === 'TEXTAREA')) {
+          DOMPropertyOperations.setValueForProperty(
+            node,
+            'data-ie8_value',
+            value
+          );
+        }
         DOMPropertyOperations.setValueForProperty(node, name, value);
       } else {
         DOMPropertyOperations.deleteValueForProperty(node, name);
diff --git a/src/browser/ui/dom/Danger.js b/src/browser/ui/dom/Danger.js
index b217d90035be..99156399a6b3 100644
--- a/src/browser/ui/dom/Danger.js
+++ b/src/browser/ui/dom/Danger.js
@@ -110,10 +110,13 @@ var Danger = {
         emptyFunction // Do nothing special with <script> tags.
       );
 
+      // IE7 fix: hasAttribute isn't available
+      // using typeof renderNode[RESULT_INDEX_ATTR] instead
       for (i = 0; i < renderNodes.length; ++i) {
         var renderNode = renderNodes[i];
         if (renderNode.hasAttribute &&
-            renderNode.hasAttribute(RESULT_INDEX_ATTR)) {
+            renderNode.hasAttribute(RESULT_INDEX_ATTR) ||
+            typeof renderNode[RESULT_INDEX_ATTR] !== 'undefined') {
 
           resultIndex = +renderNode.getAttribute(RESULT_INDEX_ATTR);
           renderNode.removeAttribute(RESULT_INDEX_ATTR);
diff --git a/src/browser/ui/dom/HTMLDOMPropertyConfig.js b/src/browser/ui/dom/HTMLDOMPropertyConfig.js
index 56e334bd0adb..fffc0ea5a3f4 100644
--- a/src/browser/ui/dom/HTMLDOMPropertyConfig.js
+++ b/src/browser/ui/dom/HTMLDOMPropertyConfig.js
@@ -117,6 +117,7 @@ var HTMLDOMPropertyConfig = {
     muted: MUST_USE_PROPERTY | HAS_BOOLEAN_VALUE,
     name: null,
     noValidate: HAS_BOOLEAN_VALUE,
+    open: null,
     pattern: null,
     placeholder: null,
     poster: null,
diff --git a/src/browser/ui/dom/components/ReactDOMInput.js b/src/browser/ui/dom/components/ReactDOMInput.js
index f1718a14c9e2..64d90d9a9a27 100644
--- a/src/browser/ui/dom/components/ReactDOMInput.js
+++ b/src/browser/ui/dom/components/ReactDOMInput.js
@@ -43,6 +43,31 @@ function forceUpdateIfMounted() {
   }
 }
 
+/**
+ * Implements polyfill for querySelectorAll to use in old IE browsers.
+ *
+ * Supports multiple / grouped selectors and the attribute selector with a "for"
+ * attribute.
+ *
+ * @see http://www.codecouch.com/2012/05/adding-document-queryselectorall-support-to-ie-7/
+ */
+function querySelectorAllPolyfill(r, c, i, j, a) {
+  var d=document,
+      s=d.createStyleSheet();
+  a = d.all;
+  c = [];
+  r = r.replace(/\[for\b/gi, '[htmlFor').split(',');
+  for (i = r.length; i--;) {
+    s.addRule(r[i], 'k:v');
+    for (j = a.length; j--;) {
+      a[j].currentStyle.k;
+      c.push(a[j]);
+    }
+    s.removeRule(0);
+  }
+  return c;
+}
+
 /**
  * Implements an <input> native component that allows setting these optional
  * props: `checked`, `value`, `defaultChecked`, and `defaultValue`.
@@ -139,6 +164,10 @@ var ReactDOMInput = ReactCompositeComponent.createClass({
         queryRoot = queryRoot.parentNode;
       }
 
+      // IE7 fix: add querySelectorAll polyfill
+      if (!queryRoot.querySelectorAll) {
+        queryRoot.querySelectorAll = querySelectorAllPolyfill;
+      }
       // If `rootNode.form` was non-null, then we could try `form.elements`,
       // but that sometimes behaves strangely in IE8. We could also try using
       // `form.getElementsByName`, but that will only return direct children
diff --git a/src/browser/ui/dom/setInnerHTML.js b/src/browser/ui/dom/setInnerHTML.js
index e7c5888aaf9d..7a7426cc1d9b 100644
--- a/src/browser/ui/dom/setInnerHTML.js
+++ b/src/browser/ui/dom/setInnerHTML.js
@@ -59,8 +59,9 @@ if (ExecutionEnvironment.canUseDOM) {
       // 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.
+      // IE7 fix: charAt(0) instead of [0]
       if (WHITESPACE_TEST.test(html) ||
-          html[0] === '<' && NONVISIBLE_TEST.test(html)) {
+          html.charAt(0) === '<' && NONVISIBLE_TEST.test(html)) {
         // Recover leading whitespace by temporarily prepending any character.
         // \uFEFF has the potential advantage of being zero-width/invisible.
         node.innerHTML = '\uFEFF' + html;
diff --git a/src/test/ReactPerf.js b/src/test/ReactPerf.js
index e7fdfb301924..0f88ba2fa8eb 100644
--- a/src/test/ReactPerf.js
+++ b/src/test/ReactPerf.js
@@ -47,7 +47,7 @@ var ReactPerf = {
   measure: function(objName, fnName, func) {
     if (__DEV__) {
       var measuredFunc = null;
-      return function() {
+      var wrapper = function() {
         if (ReactPerf.enableMeasure) {
           if (!measuredFunc) {
             measuredFunc = ReactPerf.storedMeasure(objName, fnName, func);
@@ -56,6 +56,8 @@ var ReactPerf = {
         }
         return func.apply(this, arguments);
       };
+      wrapper.displayName = objName + '_' + fnName;
+      return wrapper;
     }
     return func;
   },
