From 1e4bc7872a26ef73cad407fc77a0c670cbd1104b Mon Sep 17 00:00:00 2001 From: hu9o Date: Tue, 10 Nov 2015 15:27:45 +0400 Subject: [PATCH] Account for possibly less than zero scale --- dist/index.js | 2 +- example/bundle.js | 14660 +++++++++++++++++++++----------------------- index.js | 2 + 3 files changed, 6935 insertions(+), 7729 deletions(-) diff --git a/dist/index.js b/dist/index.js index e77461e..e16b2c4 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1 +1 @@ -(function(global,factory){if(typeof define==="function"&&define.amd){define(["exports","module"],factory)}else if(typeof exports!=="undefined"&&typeof module!=="undefined"){factory(exports,module)}else{var mod={exports:{}};factory(mod.exports,mod);global.index=mod.exports}})(this,function(exports,module){"use strict";var _extends=Object.assign||function(target){for(var i=1;i0));var draggableEvents={mobile:{react:{down:"onTouchStart",drag:"onTouchMove",drop:"onTouchEnd",move:"onTouchMove",up:"onTouchUp"},"native":{down:"touchstart",drag:"touchmove",drop:"touchend",move:"touchmove",up:"touchup"}},desktop:{react:{down:"onMouseDown",drag:"onDragOver",drop:"onDrop",move:"onMouseMove",up:"onMouseUp"},"native":{down:"mousedown",drag:"dragStart",drop:"drop",move:"mousemove",up:"mouseup"}}};var deviceEvents=isTouchDevice?draggableEvents.mobile:draggableEvents.desktop;var AvatarEditor=React.createClass({displayName:"AvatarEditor",propTypes:{scale:React.PropTypes.number,image:React.PropTypes.string,border:React.PropTypes.number,width:React.PropTypes.number,height:React.PropTypes.number,color:React.PropTypes.arrayOf(React.PropTypes.number),style:React.PropTypes.object,onDropFile:React.PropTypes.func,onLoadFailure:React.PropTypes.func,onLoadSuccess:React.PropTypes.func,onImageReady:React.PropTypes.func},getDefaultProps:function getDefaultProps(){return{scale:1,border:25,width:200,height:200,color:[0,0,0,.5],style:{},onDropFile:function onDropFile(){},onLoadFailure:function onLoadFailure(){},onLoadSuccess:function onLoadSuccess(){},onImageReady:function onImageReady(){}}},getInitialState:function getInitialState(){return{drag:false,my:null,mx:null,image:{x:0,y:0}}},getDimensions:function getDimensions(){return{width:this.props.width,height:this.props.height,border:this.props.border,canvas:{width:this.props.width+this.props.border*2,height:this.props.height+this.props.border*2}}},getImage:function getImage(type,quality){var dom=document.createElement("canvas");var context=dom.getContext("2d");var dimensions=this.getDimensions();var border=0;dom.width=dimensions.width;dom.height=dimensions.height;context.globalCompositeOperation="destination-over";this.paintImage(context,this.state.image,border);return dom.toDataURL(type,quality)},isDataURL:function isDataURL(str){var regex=/^\s*data:([a-z]+\/[a-z]+(;[a-z\-]+\=[a-z\-]+)?)?(;base64)?,[a-z0-9\!\$\&\'\,\(\)\*\+\,\;\=\-\.\_\~\:\@\/\?\%\s]*\s*$/i;return!!str.match(regex)},loadImage:function loadImage(imageURL){var imageObj=new Image;imageObj.onload=this.handleImageReady.bind(this,imageObj);imageObj.onerror=this.props.onLoadFailure;if(!this.isDataURL(imageURL))imageObj.crossOrigin="anonymous";imageObj.src=imageURL},componentDidMount:function componentDidMount(){var context=React.findDOMNode(this.refs.canvas).getContext("2d");if(this.props.image){this.loadImage(this.props.image)}this.paint(context);document&&document.addEventListener(deviceEvents.native.move,this.handleMouseMove,false);document&&document.addEventListener(deviceEvents.native.up,this.handleMouseUp,false);if(isTouchDevice)React.initializeTouchEvents(true)},componentWillUnmount:function componentWillUnmount(){document&&document.removeEventListener(deviceEvents.native.move,this.handleMouseMove,false);document&&document.removeEventListener(deviceEvents.native.up,this.handleMouseUp,false)},componentDidUpdate:function componentDidUpdate(){var context=React.findDOMNode(this.refs.canvas).getContext("2d");context.clearRect(0,0,this.getDimensions().canvas.width,this.getDimensions().canvas.height);this.paint(context);this.paintImage(context,this.state.image,this.props.border)},handleImageReady:function handleImageReady(image){var imageState=this.getInitialSize(image.width,image.height);imageState.resource=image;imageState.x=0;imageState.y=0;this.props.onLoadSuccess(imageState);this.setState({drag:false,image:imageState},this.props.onImageReady)},getInitialSize:function getInitialSize(width,height){var newHeight,newWidth,dimensions,canvasRatio,imageRatio;dimensions=this.getDimensions();canvasRatio=dimensions.height/dimensions.width;imageRatio=height/width;if(canvasRatio>imageRatio){newHeight=this.getDimensions().height;newWidth=width*(newHeight/height)}else{newWidth=this.getDimensions().width;newHeight=height*(newWidth/width)}return{height:newHeight,width:newWidth}},componentWillReceiveProps:function componentWillReceiveProps(newProps){if(this.props.image!=newProps.image){this.loadImage(newProps.image)}if(this.props.scale!=newProps.scale||this.props.height!=newProps.height||this.props.width!=newProps.width||this.props.border!=newProps.border){this.squeeze(newProps)}},paintImage:function paintImage(context,image,border){if(image.resource){var position=this.calculatePosition(image,border);context.save();context.globalCompositeOperation="destination-over";context.drawImage(image.resource,position.x,position.y,position.width,position.height);context.restore()}},calculatePosition:function calculatePosition(image,border){image=image||this.state.image;var x,y,width,height,dimensions=this.getDimensions();width=image.width*this.props.scale;height=image.height*this.props.scale;var widthDiff=(width-dimensions.width)/2;var heightDiff=(height-dimensions.height)/2;x=image.x*this.props.scale-widthDiff+border;y=image.y*this.props.scale-heightDiff+border;return{x:x,y:y,height:height,width:width}},paint:function paint(context){context.save();context.translate(0,0);context.fillStyle="rgba("+this.props.color.slice(0,4).join(",")+")";var dimensions=this.getDimensions();var borderSize=dimensions.border;var height=dimensions.canvas.height;var width=dimensions.canvas.width;context.fillRect(0,0,width,borderSize);context.fillRect(0,height-borderSize,width,borderSize);context.fillRect(0,borderSize,borderSize,height-borderSize*2);context.fillRect(width-borderSize,borderSize,borderSize,height-borderSize*2);context.restore()},handleMouseDown:function handleMouseDown(){this.setState({drag:true,mx:null,my:null})},handleMouseUp:function handleMouseUp(){if(this.state.drag){this.setState({drag:false})}},handleMouseMove:function handleMouseMove(e){if(false==this.state.drag){return}var imageState=this.state.image;var lastX=imageState.x;var lastY=imageState.y;var mousePositionX=isTouchDevice?event.targetTouches[0].pageX:e.clientX;var mousePositionY=isTouchDevice?event.targetTouches[0].pageY:e.clientY;var newState={mx:mousePositionX,my:mousePositionY,image:imageState};if(this.state.mx&&this.state.my){var xDiff=(this.state.mx-mousePositionX)/this.props.scale;var yDiff=(this.state.my-mousePositionY)/this.props.scale;imageState.y=this.getBoundedY(lastY-yDiff,this.props.scale);imageState.x=this.getBoundedX(lastX-xDiff,this.props.scale)}this.setState(newState)},squeeze:function squeeze(props){var imageState=this.state.image;imageState.y=this.getBoundedY(imageState.y,props.scale);imageState.x=this.getBoundedX(imageState.x,props.scale);this.setState({image:imageState})},getBoundedX:function getBoundedX(x,scale){var image=this.state.image;var dimensions=this.getDimensions();var widthDiff=Math.floor((image.width-dimensions.width/scale)/2);return Math.max(-widthDiff,Math.min(x,widthDiff))},getBoundedY:function getBoundedY(y,scale){var image=this.state.image;var dimensions=this.getDimensions();var heightDiff=Math.floor((image.height-dimensions.height/scale)/2);return Math.max(-heightDiff,Math.min(y,heightDiff))},handleDragOver:function handleDragOver(e){e.preventDefault()},handleDrop:function handleDrop(e){var _this=this;e.stopPropagation();e.preventDefault();if(e.dataTransfer.files.length){this.props.onDropFile(e);var reader=new FileReader;var file=e.dataTransfer.files[0];reader.onload=function(e){return _this.loadImage(e.target.result)};reader.readAsDataURL(file)}},render:function render(){var defaultStyle={cursor:this.state.drag?"grabbing":"grab"};var attributes={width:this.getDimensions().canvas.width,height:this.getDimensions().canvas.height,style:Object.assign(defaultStyle,this.props.style)};attributes[deviceEvents.react.down]=this.handleMouseDown;attributes[deviceEvents.react.drag]=this.handleDragOver;attributes[deviceEvents.react.drop]=this.handleDrop;return React.createElement("canvas",_extends({ref:"canvas"},attributes))}});module.exports=AvatarEditor}); \ No newline at end of file +(function(global,factory){if(typeof define==="function"&&define.amd){define(["exports","module"],factory)}else if(typeof exports!=="undefined"&&typeof module!=="undefined"){factory(exports,module)}else{var mod={exports:{}};factory(mod.exports,mod);global.index=mod.exports}})(this,function(exports,module){"use strict";var _extends=Object.assign||function(target){for(var i=1;i0));var draggableEvents={mobile:{react:{down:"onTouchStart",drag:"onTouchMove",drop:"onTouchEnd",move:"onTouchMove",up:"onTouchUp"},"native":{down:"touchstart",drag:"touchmove",drop:"touchend",move:"touchmove",up:"touchup"}},desktop:{react:{down:"onMouseDown",drag:"onDragOver",drop:"onDrop",move:"onMouseMove",up:"onMouseUp"},"native":{down:"mousedown",drag:"dragStart",drop:"drop",move:"mousemove",up:"mouseup"}}};var deviceEvents=isTouchDevice?draggableEvents.mobile:draggableEvents.desktop;var AvatarEditor=React.createClass({displayName:"AvatarEditor",propTypes:{scale:React.PropTypes.number,image:React.PropTypes.string,border:React.PropTypes.number,width:React.PropTypes.number,height:React.PropTypes.number,color:React.PropTypes.arrayOf(React.PropTypes.number),style:React.PropTypes.object,onDropFile:React.PropTypes.func,onLoadFailure:React.PropTypes.func,onLoadSuccess:React.PropTypes.func,onImageReady:React.PropTypes.func},getDefaultProps:function getDefaultProps(){return{scale:1,border:25,width:200,height:200,color:[0,0,0,.5],style:{},onDropFile:function onDropFile(){},onLoadFailure:function onLoadFailure(){},onLoadSuccess:function onLoadSuccess(){},onImageReady:function onImageReady(){}}},getInitialState:function getInitialState(){return{drag:false,my:null,mx:null,image:{x:0,y:0}}},getDimensions:function getDimensions(){return{width:this.props.width,height:this.props.height,border:this.props.border,canvas:{width:this.props.width+this.props.border*2,height:this.props.height+this.props.border*2}}},getImage:function getImage(type,quality){var dom=document.createElement("canvas");var context=dom.getContext("2d");var dimensions=this.getDimensions();var border=0;dom.width=dimensions.width;dom.height=dimensions.height;context.globalCompositeOperation="destination-over";this.paintImage(context,this.state.image,border);return dom.toDataURL(type,quality)},isDataURL:function isDataURL(str){var regex=/^\s*data:([a-z]+\/[a-z]+(;[a-z\-]+\=[a-z\-]+)?)?(;base64)?,[a-z0-9\!\$\&\'\,\(\)\*\+\,\;\=\-\.\_\~\:\@\/\?\%\s]*\s*$/i;return!!str.match(regex)},loadImage:function loadImage(imageURL){var imageObj=new Image;imageObj.onload=this.handleImageReady.bind(this,imageObj);imageObj.onerror=this.props.onLoadFailure;if(!this.isDataURL(imageURL))imageObj.crossOrigin="anonymous";imageObj.src=imageURL},componentDidMount:function componentDidMount(){var context=ReactDOM.findDOMNode(this.refs.canvas).getContext("2d");if(this.props.image){this.loadImage(this.props.image)}this.paint(context);document&&document.addEventListener(deviceEvents.native.move,this.handleMouseMove,false);document&&document.addEventListener(deviceEvents.native.up,this.handleMouseUp,false);if(isTouchDevice)React.initializeTouchEvents(true)},componentWillUnmount:function componentWillUnmount(){document&&document.removeEventListener(deviceEvents.native.move,this.handleMouseMove,false);document&&document.removeEventListener(deviceEvents.native.up,this.handleMouseUp,false)},componentDidUpdate:function componentDidUpdate(){var context=ReactDOM.findDOMNode(this.refs.canvas).getContext("2d");context.clearRect(0,0,this.getDimensions().canvas.width,this.getDimensions().canvas.height);this.paint(context);this.paintImage(context,this.state.image,this.props.border)},handleImageReady:function handleImageReady(image){var imageState=this.getInitialSize(image.width,image.height);imageState.resource=image;imageState.x=0;imageState.y=0;this.props.onLoadSuccess(imageState);this.setState({drag:false,image:imageState},this.props.onImageReady)},getInitialSize:function getInitialSize(width,height){var newHeight,newWidth,dimensions,canvasRatio,imageRatio;dimensions=this.getDimensions();canvasRatio=dimensions.height/dimensions.width;imageRatio=height/width;if(canvasRatio>imageRatio){newHeight=this.getDimensions().height;newWidth=width*(newHeight/height)}else{newWidth=this.getDimensions().width;newHeight=height*(newWidth/width)}return{height:newHeight,width:newWidth}},componentWillReceiveProps:function componentWillReceiveProps(newProps){if(this.props.image!=newProps.image){this.loadImage(newProps.image)}if(this.props.scale!=newProps.scale||this.props.height!=newProps.height||this.props.width!=newProps.width||this.props.border!=newProps.border){this.squeeze(newProps)}},paintImage:function paintImage(context,image,border){if(image.resource){var position=this.calculatePosition(image,border);context.save();context.globalCompositeOperation="destination-over";context.drawImage(image.resource,position.x,position.y,position.width,position.height);context.restore()}},calculatePosition:function calculatePosition(image,border){image=image||this.state.image;var x,y,width,height,dimensions=this.getDimensions();width=image.width*this.props.scale;height=image.height*this.props.scale;var widthDiff=(width-dimensions.width)/2;var heightDiff=(height-dimensions.height)/2;x=image.x*this.props.scale-widthDiff+border;y=image.y*this.props.scale-heightDiff+border;return{x:x,y:y,height:height,width:width}},paint:function paint(context){context.save();context.translate(0,0);context.fillStyle="rgba("+this.props.color.slice(0,4).join(",")+")";var dimensions=this.getDimensions();var borderSize=dimensions.border;var height=dimensions.canvas.height;var width=dimensions.canvas.width;context.fillRect(0,0,width,borderSize);context.fillRect(0,height-borderSize,width,borderSize);context.fillRect(0,borderSize,borderSize,height-borderSize*2);context.fillRect(width-borderSize,borderSize,borderSize,height-borderSize*2);context.restore()},handleMouseDown:function handleMouseDown(){this.setState({drag:true,mx:null,my:null})},handleMouseUp:function handleMouseUp(){if(this.state.drag){this.setState({drag:false})}},handleMouseMove:function handleMouseMove(e){if(false==this.state.drag){return}var imageState=this.state.image;var lastX=imageState.x;var lastY=imageState.y;var mousePositionX=isTouchDevice?event.targetTouches[0].pageX:e.clientX;var mousePositionY=isTouchDevice?event.targetTouches[0].pageY:e.clientY;var newState={mx:mousePositionX,my:mousePositionY,image:imageState};if(this.state.mx&&this.state.my){var xDiff=(this.state.mx-mousePositionX)/this.props.scale;var yDiff=(this.state.my-mousePositionY)/this.props.scale;imageState.y=this.getBoundedY(lastY-yDiff,this.props.scale);imageState.x=this.getBoundedX(lastX-xDiff,this.props.scale)}this.setState(newState)},squeeze:function squeeze(props){var imageState=this.state.image;imageState.y=this.getBoundedY(imageState.y,props.scale);imageState.x=this.getBoundedX(imageState.x,props.scale);this.setState({image:imageState})},getBoundedX:function getBoundedX(x,scale){var image=this.state.image;var dimensions=this.getDimensions();var widthDiff=Math.floor((image.width-dimensions.width/scale)/2);widthDiff=Math.max(0,widthDiff);return Math.max(-widthDiff,Math.min(x,widthDiff))},getBoundedY:function getBoundedY(y,scale){var image=this.state.image;var dimensions=this.getDimensions();var heightDiff=Math.floor((image.height-dimensions.height/scale)/2);heightDiff=Math.max(0,heightDiff);return Math.max(-heightDiff,Math.min(y,heightDiff))},handleDragOver:function handleDragOver(e){e.preventDefault()},handleDrop:function handleDrop(e){var _this=this;e.stopPropagation();e.preventDefault();if(e.dataTransfer.files.length){this.props.onDropFile(e);var reader=new FileReader;var file=e.dataTransfer.files[0];reader.onload=function(e){return _this.loadImage(e.target.result)};reader.readAsDataURL(file)}},render:function render(){var defaultStyle={cursor:this.state.drag?"grabbing":"grab"};var attributes={width:this.getDimensions().canvas.width,height:this.getDimensions().canvas.height,style:Object.assign(defaultStyle,this.props.style)};attributes[deviceEvents.react.down]=this.handleMouseDown;attributes[deviceEvents.react.drag]=this.handleDragOver;attributes[deviceEvents.react.drop]=this.handleDrop;return React.createElement("canvas",_extends({ref:"canvas"},attributes))}});module.exports=AvatarEditor}); \ No newline at end of file diff --git a/example/bundle.js b/example/bundle.js index dba9d1b..fc9ab4f 100644 --- a/example/bundle.js +++ b/example/bundle.js @@ -1,6 +1,6 @@ (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o0));var draggableEvents={mobile:{react:{down:"onTouchStart",drag:"onTouchMove",drop:"onTouchEnd",move:"onTouchMove",up:"onTouchUp"},"native":{down:"touchstart",drag:"touchmove",drop:"touchend",move:"touchmove",up:"touchup"}},desktop:{react:{down:"onMouseDown",drag:"onDragOver",drop:"onDrop",move:"onMouseMove",up:"onMouseUp"},"native":{down:"mousedown",drag:"dragStart",drop:"drop",move:"mousemove",up:"mouseup"}}};var deviceEvents=isTouchDevice?draggableEvents.mobile:draggableEvents.desktop;var AvatarEditor=React.createClass({displayName:"AvatarEditor",propTypes:{scale:React.PropTypes.number,image:React.PropTypes.string,border:React.PropTypes.number,width:React.PropTypes.number,height:React.PropTypes.number,color:React.PropTypes.arrayOf(React.PropTypes.number),style:React.PropTypes.object,onDropFile:React.PropTypes.func,onLoadFailure:React.PropTypes.func,onLoadSuccess:React.PropTypes.func,onImageReady:React.PropTypes.func},getDefaultProps:function getDefaultProps(){return{scale:1,border:25,width:200,height:200,color:[0,0,0,.5],style:{},onDropFile:function onDropFile(){},onLoadFailure:function onLoadFailure(){},onLoadSuccess:function onLoadSuccess(){},onImageReady:function onImageReady(){}}},getInitialState:function getInitialState(){return{drag:false,my:null,mx:null,image:{x:0,y:0}}},getDimensions:function getDimensions(){return{width:this.props.width,height:this.props.height,border:this.props.border,canvas:{width:this.props.width+this.props.border*2,height:this.props.height+this.props.border*2}}},getImage:function getImage(type,quality){var dom=document.createElement("canvas");var context=dom.getContext("2d");var dimensions=this.getDimensions();var border=0;dom.width=dimensions.width;dom.height=dimensions.height;context.globalCompositeOperation="destination-over";this.paintImage(context,this.state.image,border);return dom.toDataURL(type,quality)},isDataURL:function isDataURL(str){var regex=/^\s*data:([a-z]+\/[a-z]+(;[a-z\-]+\=[a-z\-]+)?)?(;base64)?,[a-z0-9\!\$\&\'\,\(\)\*\+\,\;\=\-\.\_\~\:\@\/\?\%\s]*\s*$/i;return!!str.match(regex)},loadImage:function loadImage(imageURL){var imageObj=new Image;imageObj.onload=this.handleImageReady.bind(this,imageObj);imageObj.onerror=this.props.onLoadFailure;if(!this.isDataURL(imageURL))imageObj.crossOrigin="anonymous";imageObj.src=imageURL},componentDidMount:function componentDidMount(){var context=React.findDOMNode(this.refs.canvas).getContext("2d");if(this.props.image){this.loadImage(this.props.image)}this.paint(context);document&&document.addEventListener(deviceEvents.native.move,this.handleMouseMove,false);document&&document.addEventListener(deviceEvents.native.up,this.handleMouseUp,false);if(isTouchDevice)React.initializeTouchEvents(true)},componentWillUnmount:function componentWillUnmount(){document&&document.removeEventListener(deviceEvents.native.move,this.handleMouseMove,false);document&&document.removeEventListener(deviceEvents.native.up,this.handleMouseUp,false)},componentDidUpdate:function componentDidUpdate(){var context=React.findDOMNode(this.refs.canvas).getContext("2d");context.clearRect(0,0,this.getDimensions().canvas.width,this.getDimensions().canvas.height);this.paint(context);this.paintImage(context,this.state.image,this.props.border)},handleImageReady:function handleImageReady(image){var imageState=this.getInitialSize(image.width,image.height);imageState.resource=image;imageState.x=0;imageState.y=0;this.props.onLoadSuccess(imageState);this.setState({drag:false,image:imageState},this.props.onImageReady)},getInitialSize:function getInitialSize(width,height){var newHeight,newWidth,dimensions,canvasRatio,imageRatio;dimensions=this.getDimensions();canvasRatio=dimensions.height/dimensions.width;imageRatio=height/width;if(canvasRatio>imageRatio){newHeight=this.getDimensions().height;newWidth=width*(newHeight/height)}else{newWidth=this.getDimensions().width;newHeight=height*(newWidth/width)}return{height:newHeight,width:newWidth}},componentWillReceiveProps:function componentWillReceiveProps(newProps){if(this.props.image!=newProps.image){this.loadImage(newProps.image)}if(this.props.scale!=newProps.scale||this.props.height!=newProps.height||this.props.width!=newProps.width||this.props.border!=newProps.border){this.squeeze(newProps)}},paintImage:function paintImage(context,image,border){if(image.resource){var position=this.calculatePosition(image,border);context.save();context.globalCompositeOperation="destination-over";context.drawImage(image.resource,position.x,position.y,position.width,position.height);context.restore()}},calculatePosition:function calculatePosition(image,border){image=image||this.state.image;var x,y,width,height,dimensions=this.getDimensions();width=image.width*this.props.scale;height=image.height*this.props.scale;var widthDiff=(width-dimensions.width)/2;var heightDiff=(height-dimensions.height)/2;x=image.x*this.props.scale-widthDiff+border;y=image.y*this.props.scale-heightDiff+border;return{x:x,y:y,height:height,width:width}},paint:function paint(context){context.save();context.translate(0,0);context.fillStyle="rgba("+this.props.color.slice(0,4).join(",")+")";var dimensions=this.getDimensions();var borderSize=dimensions.border;var height=dimensions.canvas.height;var width=dimensions.canvas.width;context.fillRect(0,0,width,borderSize);context.fillRect(0,height-borderSize,width,borderSize);context.fillRect(0,borderSize,borderSize,height-borderSize*2);context.fillRect(width-borderSize,borderSize,borderSize,height-borderSize*2);context.restore()},handleMouseDown:function handleMouseDown(){this.setState({drag:true,mx:null,my:null})},handleMouseUp:function handleMouseUp(){if(this.state.drag){this.setState({drag:false})}},handleMouseMove:function handleMouseMove(e){if(false==this.state.drag){return}var imageState=this.state.image;var lastX=imageState.x;var lastY=imageState.y;var mousePositionX=isTouchDevice?event.targetTouches[0].pageX:e.clientX;var mousePositionY=isTouchDevice?event.targetTouches[0].pageY:e.clientY;var newState={mx:mousePositionX,my:mousePositionY,image:imageState};if(this.state.mx&&this.state.my){var xDiff=(this.state.mx-mousePositionX)/this.props.scale;var yDiff=(this.state.my-mousePositionY)/this.props.scale;imageState.y=this.getBoundedY(lastY-yDiff,this.props.scale);imageState.x=this.getBoundedX(lastX-xDiff,this.props.scale)}this.setState(newState)},squeeze:function squeeze(props){var imageState=this.state.image;imageState.y=this.getBoundedY(imageState.y,props.scale);imageState.x=this.getBoundedX(imageState.x,props.scale);this.setState({image:imageState})},getBoundedX:function getBoundedX(x,scale){var image=this.state.image;var dimensions=this.getDimensions();var widthDiff=Math.floor((image.width-dimensions.width/scale)/2);return Math.max(-widthDiff,Math.min(x,widthDiff))},getBoundedY:function getBoundedY(y,scale){var image=this.state.image;var dimensions=this.getDimensions();var heightDiff=Math.floor((image.height-dimensions.height/scale)/2);return Math.max(-heightDiff,Math.min(y,heightDiff))},handleDragOver:function handleDragOver(e){e.preventDefault()},handleDrop:function handleDrop(e){var _this=this;e.stopPropagation();e.preventDefault();if(e.dataTransfer.files.length){this.props.onDropFile(e);var reader=new FileReader;var file=e.dataTransfer.files[0];reader.onload=function(e){return _this.loadImage(e.target.result)};reader.readAsDataURL(file)}},render:function render(){var defaultStyle={cursor:this.state.drag?"grabbing":"grab"};var attributes={width:this.getDimensions().canvas.width,height:this.getDimensions().canvas.height,style:Object.assign(defaultStyle,this.props.style)};attributes[deviceEvents.react.down]=this.handleMouseDown;attributes[deviceEvents.react.drag]=this.handleDragOver;attributes[deviceEvents.react.drop]=this.handleDrop;return React.createElement("canvas",_extends({ref:"canvas"},attributes))}});module.exports=AvatarEditor}); -},{"react":157}],2:[function(require,module,exports){ +(function(global,factory){if(typeof define==="function"&&define.amd){define(["exports","module"],factory)}else if(typeof exports!=="undefined"&&typeof module!=="undefined"){factory(exports,module)}else{var mod={exports:{}};factory(mod.exports,mod);global.index=mod.exports}})(this,function(exports,module){"use strict";var _extends=Object.assign||function(target){for(var i=1;i0));var draggableEvents={mobile:{react:{down:"onTouchStart",drag:"onTouchMove",drop:"onTouchEnd",move:"onTouchMove",up:"onTouchUp"},"native":{down:"touchstart",drag:"touchmove",drop:"touchend",move:"touchmove",up:"touchup"}},desktop:{react:{down:"onMouseDown",drag:"onDragOver",drop:"onDrop",move:"onMouseMove",up:"onMouseUp"},"native":{down:"mousedown",drag:"dragStart",drop:"drop",move:"mousemove",up:"mouseup"}}};var deviceEvents=isTouchDevice?draggableEvents.mobile:draggableEvents.desktop;var AvatarEditor=React.createClass({displayName:"AvatarEditor",propTypes:{scale:React.PropTypes.number,image:React.PropTypes.string,border:React.PropTypes.number,width:React.PropTypes.number,height:React.PropTypes.number,color:React.PropTypes.arrayOf(React.PropTypes.number),style:React.PropTypes.object,onDropFile:React.PropTypes.func,onLoadFailure:React.PropTypes.func,onLoadSuccess:React.PropTypes.func,onImageReady:React.PropTypes.func},getDefaultProps:function getDefaultProps(){return{scale:1,border:25,width:200,height:200,color:[0,0,0,.5],style:{},onDropFile:function onDropFile(){},onLoadFailure:function onLoadFailure(){},onLoadSuccess:function onLoadSuccess(){},onImageReady:function onImageReady(){}}},getInitialState:function getInitialState(){return{drag:false,my:null,mx:null,image:{x:0,y:0}}},getDimensions:function getDimensions(){return{width:this.props.width,height:this.props.height,border:this.props.border,canvas:{width:this.props.width+this.props.border*2,height:this.props.height+this.props.border*2}}},getImage:function getImage(type,quality){var dom=document.createElement("canvas");var context=dom.getContext("2d");var dimensions=this.getDimensions();var border=0;dom.width=dimensions.width;dom.height=dimensions.height;context.globalCompositeOperation="destination-over";this.paintImage(context,this.state.image,border);return dom.toDataURL(type,quality)},isDataURL:function isDataURL(str){var regex=/^\s*data:([a-z]+\/[a-z]+(;[a-z\-]+\=[a-z\-]+)?)?(;base64)?,[a-z0-9\!\$\&\'\,\(\)\*\+\,\;\=\-\.\_\~\:\@\/\?\%\s]*\s*$/i;return!!str.match(regex)},loadImage:function loadImage(imageURL){var imageObj=new Image;imageObj.onload=this.handleImageReady.bind(this,imageObj);imageObj.onerror=this.props.onLoadFailure;if(!this.isDataURL(imageURL))imageObj.crossOrigin="anonymous";imageObj.src=imageURL},componentDidMount:function componentDidMount(){var context=ReactDOM.findDOMNode(this.refs.canvas).getContext("2d");if(this.props.image){this.loadImage(this.props.image)}this.paint(context);document&&document.addEventListener(deviceEvents.native.move,this.handleMouseMove,false);document&&document.addEventListener(deviceEvents.native.up,this.handleMouseUp,false);if(isTouchDevice)React.initializeTouchEvents(true)},componentWillUnmount:function componentWillUnmount(){document&&document.removeEventListener(deviceEvents.native.move,this.handleMouseMove,false);document&&document.removeEventListener(deviceEvents.native.up,this.handleMouseUp,false)},componentDidUpdate:function componentDidUpdate(){var context=ReactDOM.findDOMNode(this.refs.canvas).getContext("2d");context.clearRect(0,0,this.getDimensions().canvas.width,this.getDimensions().canvas.height);this.paint(context);this.paintImage(context,this.state.image,this.props.border)},handleImageReady:function handleImageReady(image){var imageState=this.getInitialSize(image.width,image.height);imageState.resource=image;imageState.x=0;imageState.y=0;this.props.onLoadSuccess(imageState);this.setState({drag:false,image:imageState},this.props.onImageReady)},getInitialSize:function getInitialSize(width,height){var newHeight,newWidth,dimensions,canvasRatio,imageRatio;dimensions=this.getDimensions();canvasRatio=dimensions.height/dimensions.width;imageRatio=height/width;if(canvasRatio>imageRatio){newHeight=this.getDimensions().height;newWidth=width*(newHeight/height)}else{newWidth=this.getDimensions().width;newHeight=height*(newWidth/width)}return{height:newHeight,width:newWidth}},componentWillReceiveProps:function componentWillReceiveProps(newProps){if(this.props.image!=newProps.image){this.loadImage(newProps.image)}if(this.props.scale!=newProps.scale||this.props.height!=newProps.height||this.props.width!=newProps.width||this.props.border!=newProps.border){this.squeeze(newProps)}},paintImage:function paintImage(context,image,border){if(image.resource){var position=this.calculatePosition(image,border);context.save();context.globalCompositeOperation="destination-over";context.drawImage(image.resource,position.x,position.y,position.width,position.height);context.restore()}},calculatePosition:function calculatePosition(image,border){image=image||this.state.image;var x,y,width,height,dimensions=this.getDimensions();width=image.width*this.props.scale;height=image.height*this.props.scale;var widthDiff=(width-dimensions.width)/2;var heightDiff=(height-dimensions.height)/2;x=image.x*this.props.scale-widthDiff+border;y=image.y*this.props.scale-heightDiff+border;return{x:x,y:y,height:height,width:width}},paint:function paint(context){context.save();context.translate(0,0);context.fillStyle="rgba("+this.props.color.slice(0,4).join(",")+")";var dimensions=this.getDimensions();var borderSize=dimensions.border;var height=dimensions.canvas.height;var width=dimensions.canvas.width;context.fillRect(0,0,width,borderSize);context.fillRect(0,height-borderSize,width,borderSize);context.fillRect(0,borderSize,borderSize,height-borderSize*2);context.fillRect(width-borderSize,borderSize,borderSize,height-borderSize*2);context.restore()},handleMouseDown:function handleMouseDown(){this.setState({drag:true,mx:null,my:null})},handleMouseUp:function handleMouseUp(){if(this.state.drag){this.setState({drag:false})}},handleMouseMove:function handleMouseMove(e){if(false==this.state.drag){return}var imageState=this.state.image;var lastX=imageState.x;var lastY=imageState.y;var mousePositionX=isTouchDevice?event.targetTouches[0].pageX:e.clientX;var mousePositionY=isTouchDevice?event.targetTouches[0].pageY:e.clientY;var newState={mx:mousePositionX,my:mousePositionY,image:imageState};if(this.state.mx&&this.state.my){var xDiff=(this.state.mx-mousePositionX)/this.props.scale;var yDiff=(this.state.my-mousePositionY)/this.props.scale;imageState.y=this.getBoundedY(lastY-yDiff,this.props.scale);imageState.x=this.getBoundedX(lastX-xDiff,this.props.scale)}this.setState(newState)},squeeze:function squeeze(props){var imageState=this.state.image;imageState.y=this.getBoundedY(imageState.y,props.scale);imageState.x=this.getBoundedX(imageState.x,props.scale);this.setState({image:imageState})},getBoundedX:function getBoundedX(x,scale){var image=this.state.image;var dimensions=this.getDimensions();var widthDiff=Math.floor((image.width-dimensions.width/scale)/2);widthDiff=Math.max(0,widthDiff);return Math.max(-widthDiff,Math.min(x,widthDiff))},getBoundedY:function getBoundedY(y,scale){var image=this.state.image;var dimensions=this.getDimensions();var heightDiff=Math.floor((image.height-dimensions.height/scale)/2);heightDiff=Math.max(0,heightDiff);return Math.max(-heightDiff,Math.min(y,heightDiff))},handleDragOver:function handleDragOver(e){e.preventDefault()},handleDrop:function handleDrop(e){var _this=this;e.stopPropagation();e.preventDefault();if(e.dataTransfer.files.length){this.props.onDropFile(e);var reader=new FileReader;var file=e.dataTransfer.files[0];reader.onload=function(e){return _this.loadImage(e.target.result)};reader.readAsDataURL(file)}},render:function render(){var defaultStyle={cursor:this.state.drag?"grabbing":"grab"};var attributes={width:this.getDimensions().canvas.width,height:this.getDimensions().canvas.height,style:Object.assign(defaultStyle,this.props.style)};attributes[deviceEvents.react.down]=this.handleMouseDown;attributes[deviceEvents.react.drag]=this.handleDragOver;attributes[deviceEvents.react.drop]=this.handleDrop;return React.createElement("canvas",_extends({ref:"canvas"},attributes))}});module.exports=AvatarEditor}); +},{"react":159,"react-dom":3}],2:[function(require,module,exports){ var React = require('react'); var Editor = require('../dist/index.js'); @@ -53,7 +53,12 @@ var App = React.createClass({displayName: "App", }); React.render(React.createElement(App, null), document.getElementById('app')); -},{"../dist/index.js":1,"react":157}],3:[function(require,module,exports){ +},{"../dist/index.js":1,"react":159}],3:[function(require,module,exports){ +'use strict'; + +module.exports = require('react/lib/ReactDOM'); + +},{"react/lib/ReactDOM":38}],4:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -62,25 +67,35 @@ React.render(React.createElement(App, null), document.getElementById('app')); * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * - * @providesModule AutoFocusMixin + * @providesModule AutoFocusUtils * @typechecks static-only */ 'use strict'; -var focusNode = require("./focusNode"); +var ReactMount = require('./ReactMount'); + +var findDOMNode = require('./findDOMNode'); +var focusNode = require('fbjs/lib/focusNode'); -var AutoFocusMixin = { - componentDidMount: function() { +var Mixin = { + componentDidMount: function () { if (this.props.autoFocus) { - focusNode(this.getDOMNode()); + focusNode(findDOMNode(this)); } } }; -module.exports = AutoFocusMixin; +var AutoFocusUtils = { + Mixin: Mixin, + + focusDOMComponent: function () { + focusNode(ReactMount.getNode(this._rootNodeID)); + } +}; -},{"./focusNode":121}],4:[function(require,module,exports){ +module.exports = AutoFocusUtils; +},{"./ReactMount":68,"./findDOMNode":111,"fbjs/lib/focusNode":141}],5:[function(require,module,exports){ /** * Copyright 2013-2015 Facebook, Inc. * All rights reserved. @@ -95,22 +110,19 @@ module.exports = AutoFocusMixin; 'use strict'; -var EventConstants = require("./EventConstants"); -var EventPropagators = require("./EventPropagators"); -var ExecutionEnvironment = require("./ExecutionEnvironment"); -var FallbackCompositionState = require("./FallbackCompositionState"); -var SyntheticCompositionEvent = require("./SyntheticCompositionEvent"); -var SyntheticInputEvent = require("./SyntheticInputEvent"); +var EventConstants = require('./EventConstants'); +var EventPropagators = require('./EventPropagators'); +var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment'); +var FallbackCompositionState = require('./FallbackCompositionState'); +var SyntheticCompositionEvent = require('./SyntheticCompositionEvent'); +var SyntheticInputEvent = require('./SyntheticInputEvent'); -var keyOf = require("./keyOf"); +var keyOf = require('fbjs/lib/keyOf'); var END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space var START_KEYCODE = 229; -var canUseCompositionEvent = ( - ExecutionEnvironment.canUseDOM && - 'CompositionEvent' in window -); +var canUseCompositionEvent = ExecutionEnvironment.canUseDOM && 'CompositionEvent' in window; var documentMode = null; if (ExecutionEnvironment.canUseDOM && 'documentMode' in document) { @@ -120,22 +132,12 @@ if (ExecutionEnvironment.canUseDOM && 'documentMode' in document) { // Webkit offers a very useful `textInput` event that can be used to // directly represent `beforeInput`. The IE `textinput` event is not as // useful, so we don't use it. -var canUseTextInputEvent = ( - ExecutionEnvironment.canUseDOM && - 'TextEvent' in window && - !documentMode && - !isPresto() -); +var canUseTextInputEvent = ExecutionEnvironment.canUseDOM && 'TextEvent' in window && !documentMode && !isPresto(); // In IE9+, we have access to composition events, but the data supplied // by the native compositionend event may be incorrect. Japanese ideographic // spaces, for instance (\u3000) are not recorded correctly. -var useFallbackCompositionData = ( - ExecutionEnvironment.canUseDOM && - ( - (!canUseCompositionEvent || documentMode && documentMode > 8 && documentMode <= 11) - ) -); +var useFallbackCompositionData = ExecutionEnvironment.canUseDOM && (!canUseCompositionEvent || documentMode && documentMode > 8 && documentMode <= 11); /** * Opera <= 12 includes TextEvent in window, but does not fire @@ -143,11 +145,7 @@ var useFallbackCompositionData = ( */ function isPresto() { var opera = window.opera; - return ( - typeof opera === 'object' && - typeof opera.version === 'function' && - parseInt(opera.version(), 10) <= 12 - ); + return typeof opera === 'object' && typeof opera.version === 'function' && parseInt(opera.version(), 10) <= 12; } var SPACEBAR_CODE = 32; @@ -159,57 +157,31 @@ var topLevelTypes = EventConstants.topLevelTypes; var eventTypes = { beforeInput: { phasedRegistrationNames: { - bubbled: keyOf({onBeforeInput: null}), - captured: keyOf({onBeforeInputCapture: null}) + bubbled: keyOf({ onBeforeInput: null }), + captured: keyOf({ onBeforeInputCapture: null }) }, - dependencies: [ - topLevelTypes.topCompositionEnd, - topLevelTypes.topKeyPress, - topLevelTypes.topTextInput, - topLevelTypes.topPaste - ] + dependencies: [topLevelTypes.topCompositionEnd, topLevelTypes.topKeyPress, topLevelTypes.topTextInput, topLevelTypes.topPaste] }, compositionEnd: { phasedRegistrationNames: { - bubbled: keyOf({onCompositionEnd: null}), - captured: keyOf({onCompositionEndCapture: null}) + bubbled: keyOf({ onCompositionEnd: null }), + captured: keyOf({ onCompositionEndCapture: null }) }, - dependencies: [ - topLevelTypes.topBlur, - topLevelTypes.topCompositionEnd, - topLevelTypes.topKeyDown, - topLevelTypes.topKeyPress, - topLevelTypes.topKeyUp, - topLevelTypes.topMouseDown - ] + dependencies: [topLevelTypes.topBlur, topLevelTypes.topCompositionEnd, topLevelTypes.topKeyDown, topLevelTypes.topKeyPress, topLevelTypes.topKeyUp, topLevelTypes.topMouseDown] }, compositionStart: { phasedRegistrationNames: { - bubbled: keyOf({onCompositionStart: null}), - captured: keyOf({onCompositionStartCapture: null}) + bubbled: keyOf({ onCompositionStart: null }), + captured: keyOf({ onCompositionStartCapture: null }) }, - dependencies: [ - topLevelTypes.topBlur, - topLevelTypes.topCompositionStart, - topLevelTypes.topKeyDown, - topLevelTypes.topKeyPress, - topLevelTypes.topKeyUp, - topLevelTypes.topMouseDown - ] + dependencies: [topLevelTypes.topBlur, topLevelTypes.topCompositionStart, topLevelTypes.topKeyDown, topLevelTypes.topKeyPress, topLevelTypes.topKeyUp, topLevelTypes.topMouseDown] }, compositionUpdate: { phasedRegistrationNames: { - bubbled: keyOf({onCompositionUpdate: null}), - captured: keyOf({onCompositionUpdateCapture: null}) + bubbled: keyOf({ onCompositionUpdate: null }), + captured: keyOf({ onCompositionUpdateCapture: null }) }, - dependencies: [ - topLevelTypes.topBlur, - topLevelTypes.topCompositionUpdate, - topLevelTypes.topKeyDown, - topLevelTypes.topKeyPress, - topLevelTypes.topKeyUp, - topLevelTypes.topMouseDown - ] + dependencies: [topLevelTypes.topBlur, topLevelTypes.topCompositionUpdate, topLevelTypes.topKeyDown, topLevelTypes.topKeyPress, topLevelTypes.topKeyUp, topLevelTypes.topMouseDown] } }; @@ -222,14 +194,11 @@ var hasSpaceKeypress = false; * (cut, copy, select-all, etc.) even though no character is inserted. */ function isKeypressCommand(nativeEvent) { - return ( - (nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) && - // ctrlKey && altKey is equivalent to AltGr, and is not a command. - !(nativeEvent.ctrlKey && nativeEvent.altKey) - ); + return (nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) && + // ctrlKey && altKey is equivalent to AltGr, and is not a command. + !(nativeEvent.ctrlKey && nativeEvent.altKey); } - /** * Translate native top level events into event types. * @@ -256,10 +225,7 @@ function getCompositionEventType(topLevelType) { * @return {boolean} */ function isFallbackCompositionStart(topLevelType, nativeEvent) { - return ( - topLevelType === topLevelTypes.topKeyDown && - nativeEvent.keyCode === START_KEYCODE - ); + return topLevelType === topLevelTypes.topKeyDown && nativeEvent.keyCode === START_KEYCODE; } /** @@ -273,11 +239,11 @@ function isFallbackCompositionEnd(topLevelType, nativeEvent) { switch (topLevelType) { case topLevelTypes.topKeyUp: // Command keys insert or clear IME input. - return (END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1); + return END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1; case topLevelTypes.topKeyDown: // Expect IME keyCode on each keydown. If we get any other // code we must have exited earlier. - return (nativeEvent.keyCode !== START_KEYCODE); + return nativeEvent.keyCode !== START_KEYCODE; case topLevelTypes.topKeyPress: case topLevelTypes.topMouseDown: case topLevelTypes.topBlur: @@ -315,12 +281,7 @@ var currentComposition = null; * @param {object} nativeEvent Native browser event. * @return {?object} A SyntheticCompositionEvent. */ -function extractCompositionEvent( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent -) { +function extractCompositionEvent(topLevelType, topLevelTarget, topLevelTargetID, nativeEvent, nativeEventTarget) { var eventType; var fallbackData; @@ -350,11 +311,7 @@ function extractCompositionEvent( } } - var event = SyntheticCompositionEvent.getPooled( - eventType, - topLevelTargetID, - nativeEvent - ); + var event = SyntheticCompositionEvent.getPooled(eventType, topLevelTargetID, nativeEvent, nativeEventTarget); if (fallbackData) { // Inject data generated from fallback path into the synthetic event. @@ -434,10 +391,7 @@ function getFallbackBeforeInputChars(topLevelType, nativeEvent) { // If we are currently composing (IME) and using a fallback to do so, // try to extract the composed characters from the fallback object. if (currentComposition) { - if ( - topLevelType === topLevelTypes.topCompositionEnd || - isFallbackCompositionEnd(topLevelType, nativeEvent) - ) { + if (topLevelType === topLevelTypes.topCompositionEnd || isFallbackCompositionEnd(topLevelType, nativeEvent)) { var chars = currentComposition.getData(); FallbackCompositionState.release(currentComposition); currentComposition = null; @@ -489,12 +443,7 @@ function getFallbackBeforeInputChars(topLevelType, nativeEvent) { * @param {object} nativeEvent Native browser event. * @return {?object} A SyntheticInputEvent. */ -function extractBeforeInputEvent( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent -) { +function extractBeforeInputEvent(topLevelType, topLevelTarget, topLevelTargetID, nativeEvent, nativeEventTarget) { var chars; if (canUseTextInputEvent) { @@ -509,11 +458,7 @@ function extractBeforeInputEvent( return null; } - var event = SyntheticInputEvent.getPooled( - eventTypes.beforeInput, - topLevelTargetID, - nativeEvent - ); + var event = SyntheticInputEvent.getPooled(eventTypes.beforeInput, topLevelTargetID, nativeEvent, nativeEventTarget); event.data = chars; EventPropagators.accumulateTwoPhaseDispatches(event); @@ -550,32 +495,13 @@ var BeforeInputEventPlugin = { * @return {*} An accumulation of synthetic events. * @see {EventPluginHub.extractEvents} */ - extractEvents: function( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent - ) { - return [ - extractCompositionEvent( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent - ), - extractBeforeInputEvent( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent - ) - ]; + extractEvents: function (topLevelType, topLevelTarget, topLevelTargetID, nativeEvent, nativeEventTarget) { + return [extractCompositionEvent(topLevelType, topLevelTarget, topLevelTargetID, nativeEvent, nativeEventTarget), extractBeforeInputEvent(topLevelType, topLevelTarget, topLevelTargetID, nativeEvent, nativeEventTarget)]; } }; module.exports = BeforeInputEventPlugin; - -},{"./EventConstants":16,"./EventPropagators":21,"./ExecutionEnvironment":22,"./FallbackCompositionState":23,"./SyntheticCompositionEvent":95,"./SyntheticInputEvent":99,"./keyOf":143}],5:[function(require,module,exports){ +},{"./EventConstants":17,"./EventPropagators":21,"./FallbackCompositionState":22,"./SyntheticCompositionEvent":93,"./SyntheticInputEvent":97,"fbjs/lib/ExecutionEnvironment":133,"fbjs/lib/keyOf":151}],6:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -593,26 +519,31 @@ module.exports = BeforeInputEventPlugin; * CSS properties which accept numbers but are not in units of "px". */ var isUnitlessNumber = { + animationIterationCount: true, boxFlex: true, boxFlexGroup: true, + boxOrdinalGroup: true, columnCount: true, flex: true, flexGrow: true, flexPositive: true, flexShrink: true, flexNegative: true, + flexOrder: true, fontWeight: true, lineClamp: true, lineHeight: true, opacity: true, order: true, orphans: true, + tabSize: true, widows: true, zIndex: true, zoom: true, // SVG-related properties fillOpacity: true, + stopOpacity: true, strokeDashoffset: true, strokeOpacity: true, strokeWidth: true @@ -636,8 +567,8 @@ var prefixes = ['Webkit', 'ms', 'Moz', 'O']; // Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an // infinite loop, because it iterates over the newly added props too. -Object.keys(isUnitlessNumber).forEach(function(prop) { - prefixes.forEach(function(prefix) { +Object.keys(isUnitlessNumber).forEach(function (prop) { + prefixes.forEach(function (prefix) { isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop]; }); }); @@ -653,10 +584,16 @@ Object.keys(isUnitlessNumber).forEach(function(prop) { */ var shorthandPropertyExpansions = { background: { + backgroundAttachment: true, + backgroundColor: true, backgroundImage: true, - backgroundPosition: true, - backgroundRepeat: true, - backgroundColor: true + backgroundPositionX: true, + backgroundPositionY: true, + backgroundRepeat: true + }, + backgroundPosition: { + backgroundPositionX: true, + backgroundPositionY: true }, border: { borderWidth: true, @@ -690,6 +627,11 @@ var shorthandPropertyExpansions = { fontSize: true, lineHeight: true, fontFamily: true + }, + outline: { + outlineWidth: true, + outlineStyle: true, + outlineColor: true } }; @@ -699,8 +641,7 @@ var CSSProperty = { }; module.exports = CSSProperty; - -},{}],6:[function(require,module,exports){ +},{}],7:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2015, Facebook, Inc. @@ -716,28 +657,37 @@ module.exports = CSSProperty; 'use strict'; -var CSSProperty = require("./CSSProperty"); -var ExecutionEnvironment = require("./ExecutionEnvironment"); +var CSSProperty = require('./CSSProperty'); +var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment'); +var ReactPerf = require('./ReactPerf'); -var camelizeStyleName = require("./camelizeStyleName"); -var dangerousStyleValue = require("./dangerousStyleValue"); -var hyphenateStyleName = require("./hyphenateStyleName"); -var memoizeStringOnly = require("./memoizeStringOnly"); -var warning = require("./warning"); +var camelizeStyleName = require('fbjs/lib/camelizeStyleName'); +var dangerousStyleValue = require('./dangerousStyleValue'); +var hyphenateStyleName = require('fbjs/lib/hyphenateStyleName'); +var memoizeStringOnly = require('fbjs/lib/memoizeStringOnly'); +var warning = require('fbjs/lib/warning'); -var processStyleName = memoizeStringOnly(function(styleName) { +var processStyleName = memoizeStringOnly(function (styleName) { return hyphenateStyleName(styleName); }); +var hasShorthandPropertyBug = false; var styleFloatAccessor = 'cssFloat'; if (ExecutionEnvironment.canUseDOM) { + var tempStyle = document.createElement('div').style; + try { + // IE8 throws "Invalid argument." if resetting shorthand style properties. + tempStyle.font = ''; + } catch (e) { + hasShorthandPropertyBug = true; + } // IE8 only supports accessing cssFloat (standard) as styleFloat if (document.documentElement.style.cssFloat === undefined) { styleFloatAccessor = 'styleFloat'; } } -if ("production" !== process.env.NODE_ENV) { +if (process.env.NODE_ENV !== 'production') { // 'msTransform' is correct, but the other prefixes should be capitalized var badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/; @@ -747,54 +697,38 @@ if ("production" !== process.env.NODE_ENV) { var warnedStyleNames = {}; var warnedStyleValues = {}; - var warnHyphenatedStyleName = function(name) { + var warnHyphenatedStyleName = function (name) { if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) { return; } warnedStyleNames[name] = true; - ("production" !== process.env.NODE_ENV ? warning( - false, - 'Unsupported style property %s. Did you mean %s?', - name, - camelizeStyleName(name) - ) : null); + process.env.NODE_ENV !== 'production' ? warning(false, 'Unsupported style property %s. Did you mean %s?', name, camelizeStyleName(name)) : undefined; }; - var warnBadVendoredStyleName = function(name) { + var warnBadVendoredStyleName = function (name) { if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) { return; } warnedStyleNames[name] = true; - ("production" !== process.env.NODE_ENV ? warning( - false, - 'Unsupported vendor-prefixed style property %s. Did you mean %s?', - name, - name.charAt(0).toUpperCase() + name.slice(1) - ) : null); + process.env.NODE_ENV !== 'production' ? warning(false, 'Unsupported vendor-prefixed style property %s. Did you mean %s?', name, name.charAt(0).toUpperCase() + name.slice(1)) : undefined; }; - var warnStyleValueWithSemicolon = function(name, value) { + var warnStyleValueWithSemicolon = function (name, value) { if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) { return; } warnedStyleValues[value] = true; - ("production" !== process.env.NODE_ENV ? warning( - false, - 'Style property values shouldn\'t contain a semicolon. ' + - 'Try "%s: %s" instead.', - name, - value.replace(badStyleValueWithSemicolonPattern, '') - ) : null); + process.env.NODE_ENV !== 'production' ? warning(false, 'Style property values shouldn\'t contain a semicolon. ' + 'Try "%s: %s" instead.', name, value.replace(badStyleValueWithSemicolonPattern, '')) : undefined; }; /** * @param {string} name * @param {*} value */ - var warnValidStyle = function(name, value) { + var warnValidStyle = function (name, value) { if (name.indexOf('-') > -1) { warnHyphenatedStyleName(name); } else if (badVendoredStyleNamePattern.test(name)) { @@ -822,14 +756,14 @@ var CSSPropertyOperations = { * @param {object} styles * @return {?string} */ - createMarkupForStyles: function(styles) { + createMarkupForStyles: function (styles) { var serialized = ''; for (var styleName in styles) { if (!styles.hasOwnProperty(styleName)) { continue; } var styleValue = styles[styleName]; - if ("production" !== process.env.NODE_ENV) { + if (process.env.NODE_ENV !== 'production') { warnValidStyle(styleName, styleValue); } if (styleValue != null) { @@ -847,13 +781,13 @@ var CSSPropertyOperations = { * @param {DOMElement} node * @param {object} styles */ - setValueForStyles: function(node, styles) { + setValueForStyles: function (node, styles) { var style = node.style; for (var styleName in styles) { if (!styles.hasOwnProperty(styleName)) { continue; } - if ("production" !== process.env.NODE_ENV) { + if (process.env.NODE_ENV !== 'production') { warnValidStyle(styleName, styles[styleName]); } var styleValue = dangerousStyleValue(styleName, styles[styleName]); @@ -863,7 +797,7 @@ var CSSPropertyOperations = { if (styleValue) { style[styleName] = styleValue; } else { - var expansion = CSSProperty.shorthandPropertyExpansions[styleName]; + var expansion = hasShorthandPropertyBug && CSSProperty.shorthandPropertyExpansions[styleName]; if (expansion) { // Shorthand property that IE8 won't like unsetting, so unset each // component to placate it @@ -879,10 +813,13 @@ var CSSPropertyOperations = { }; -module.exports = CSSPropertyOperations; +ReactPerf.measureMethods(CSSPropertyOperations, 'CSSPropertyOperations', { + setValueForStyles: 'setValueForStyles' +}); +module.exports = CSSPropertyOperations; }).call(this,require('_process')) -},{"./CSSProperty":5,"./ExecutionEnvironment":22,"./camelizeStyleName":110,"./dangerousStyleValue":115,"./hyphenateStyleName":135,"./memoizeStringOnly":145,"./warning":156,"_process":158}],7:[function(require,module,exports){ +},{"./CSSProperty":6,"./ReactPerf":74,"./dangerousStyleValue":108,"_process":160,"fbjs/lib/ExecutionEnvironment":133,"fbjs/lib/camelizeStyleName":135,"fbjs/lib/hyphenateStyleName":146,"fbjs/lib/memoizeStringOnly":153,"fbjs/lib/warning":158}],8:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2015, Facebook, Inc. @@ -897,10 +834,10 @@ module.exports = CSSPropertyOperations; 'use strict'; -var PooledClass = require("./PooledClass"); +var PooledClass = require('./PooledClass'); -var assign = require("./Object.assign"); -var invariant = require("./invariant"); +var assign = require('./Object.assign'); +var invariant = require('fbjs/lib/invariant'); /** * A specialized pseudo-event module to help keep track of components waiting to @@ -927,7 +864,7 @@ assign(CallbackQueue.prototype, { * @param {?object} context Context to call `callback` with. * @internal */ - enqueue: function(callback, context) { + enqueue: function (callback, context) { this._callbacks = this._callbacks || []; this._contexts = this._contexts || []; this._callbacks.push(callback); @@ -940,17 +877,14 @@ assign(CallbackQueue.prototype, { * * @internal */ - notifyAll: function() { + notifyAll: function () { var callbacks = this._callbacks; var contexts = this._contexts; if (callbacks) { - ("production" !== process.env.NODE_ENV ? invariant( - callbacks.length === contexts.length, - 'Mismatched list of contexts in callback queue' - ) : invariant(callbacks.length === contexts.length)); + !(callbacks.length === contexts.length) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Mismatched list of contexts in callback queue') : invariant(false) : undefined; this._callbacks = null; this._contexts = null; - for (var i = 0, l = callbacks.length; i < l; i++) { + for (var i = 0; i < callbacks.length; i++) { callbacks[i].call(contexts[i]); } callbacks.length = 0; @@ -963,7 +897,7 @@ assign(CallbackQueue.prototype, { * * @internal */ - reset: function() { + reset: function () { this._callbacks = null; this._contexts = null; }, @@ -971,7 +905,7 @@ assign(CallbackQueue.prototype, { /** * `PooledClass` looks for this. */ - destructor: function() { + destructor: function () { this.reset(); } @@ -980,9 +914,8 @@ assign(CallbackQueue.prototype, { PooledClass.addPoolingTo(CallbackQueue); module.exports = CallbackQueue; - }).call(this,require('_process')) -},{"./Object.assign":28,"./PooledClass":29,"./invariant":137,"_process":158}],8:[function(require,module,exports){ +},{"./Object.assign":25,"./PooledClass":26,"_process":160,"fbjs/lib/invariant":147}],9:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -996,35 +929,27 @@ module.exports = CallbackQueue; 'use strict'; -var EventConstants = require("./EventConstants"); -var EventPluginHub = require("./EventPluginHub"); -var EventPropagators = require("./EventPropagators"); -var ExecutionEnvironment = require("./ExecutionEnvironment"); -var ReactUpdates = require("./ReactUpdates"); -var SyntheticEvent = require("./SyntheticEvent"); +var EventConstants = require('./EventConstants'); +var EventPluginHub = require('./EventPluginHub'); +var EventPropagators = require('./EventPropagators'); +var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment'); +var ReactUpdates = require('./ReactUpdates'); +var SyntheticEvent = require('./SyntheticEvent'); -var isEventSupported = require("./isEventSupported"); -var isTextInputElement = require("./isTextInputElement"); -var keyOf = require("./keyOf"); +var getEventTarget = require('./getEventTarget'); +var isEventSupported = require('./isEventSupported'); +var isTextInputElement = require('./isTextInputElement'); +var keyOf = require('fbjs/lib/keyOf'); var topLevelTypes = EventConstants.topLevelTypes; var eventTypes = { change: { phasedRegistrationNames: { - bubbled: keyOf({onChange: null}), - captured: keyOf({onChangeCapture: null}) + bubbled: keyOf({ onChange: null }), + captured: keyOf({ onChangeCapture: null }) }, - dependencies: [ - topLevelTypes.topBlur, - topLevelTypes.topChange, - topLevelTypes.topClick, - topLevelTypes.topFocus, - topLevelTypes.topInput, - topLevelTypes.topKeyDown, - topLevelTypes.topKeyUp, - topLevelTypes.topSelectionChange - ] + dependencies: [topLevelTypes.topBlur, topLevelTypes.topChange, topLevelTypes.topClick, topLevelTypes.topFocus, topLevelTypes.topInput, topLevelTypes.topKeyDown, topLevelTypes.topKeyUp, topLevelTypes.topSelectionChange] } }; @@ -1040,26 +965,18 @@ var activeElementValueProp = null; * SECTION: handle `change` event */ function shouldUseChangeEvent(elem) { - return ( - elem.nodeName === 'SELECT' || - (elem.nodeName === 'INPUT' && elem.type === 'file') - ); + var nodeName = elem.nodeName && elem.nodeName.toLowerCase(); + return nodeName === 'select' || nodeName === 'input' && elem.type === 'file'; } var doesChangeEventBubble = false; if (ExecutionEnvironment.canUseDOM) { // See `handleChange` comment below - doesChangeEventBubble = isEventSupported('change') && ( - (!('documentMode' in document) || document.documentMode > 8) - ); + doesChangeEventBubble = isEventSupported('change') && (!('documentMode' in document) || document.documentMode > 8); } function manualDispatchChangeEvent(nativeEvent) { - var event = SyntheticEvent.getPooled( - eventTypes.change, - activeElementID, - nativeEvent - ); + var event = SyntheticEvent.getPooled(eventTypes.change, activeElementID, nativeEvent, getEventTarget(nativeEvent)); EventPropagators.accumulateTwoPhaseDispatches(event); // If change and propertychange bubbled, we'd just bind to it like all the @@ -1078,7 +995,7 @@ function manualDispatchChangeEvent(nativeEvent) { function runEventInBatch(event) { EventPluginHub.enqueueEvents(event); - EventPluginHub.processEventQueue(); + EventPluginHub.processEventQueue(false); } function startWatchingForChangeEventIE8(target, targetID) { @@ -1096,18 +1013,12 @@ function stopWatchingForChangeEventIE8() { activeElementID = null; } -function getTargetIDForChangeEvent( - topLevelType, - topLevelTarget, - topLevelTargetID) { +function getTargetIDForChangeEvent(topLevelType, topLevelTarget, topLevelTargetID) { if (topLevelType === topLevelTypes.topChange) { return topLevelTargetID; } } -function handleEventsForChangeEventIE8( - topLevelType, - topLevelTarget, - topLevelTargetID) { +function handleEventsForChangeEventIE8(topLevelType, topLevelTarget, topLevelTargetID) { if (topLevelType === topLevelTypes.topFocus) { // stopWatching() should be a noop here but we call it just in case we // missed a blur event somehow. @@ -1118,7 +1029,6 @@ function handleEventsForChangeEventIE8( } } - /** * SECTION: handle `input` event */ @@ -1126,20 +1036,18 @@ var isInputEventSupported = false; if (ExecutionEnvironment.canUseDOM) { // IE9 claims to support the input event but fails to trigger it when // deleting text, so we ignore its input events - isInputEventSupported = isEventSupported('input') && ( - (!('documentMode' in document) || document.documentMode > 9) - ); + isInputEventSupported = isEventSupported('input') && (!('documentMode' in document) || document.documentMode > 9); } /** * (For old IE.) Replacement getter/setter for the `value` property that gets * set on the active element. */ -var newValueProp = { - get: function() { +var newValueProp = { + get: function () { return activeElementValueProp.get.call(this); }, - set: function(val) { + set: function (val) { // Cast to a string so we can do equality checks. activeElementValue = '' + val; activeElementValueProp.set.call(this, val); @@ -1155,11 +1063,10 @@ function startWatchingForValueChange(target, targetID) { activeElement = target; activeElementID = targetID; activeElementValue = target.value; - activeElementValueProp = Object.getOwnPropertyDescriptor( - target.constructor.prototype, - 'value' - ); + activeElementValueProp = Object.getOwnPropertyDescriptor(target.constructor.prototype, 'value'); + // Not guarded in a canDefineProperty check: IE8 supports defineProperty only + // on DOM elements Object.defineProperty(activeElement, 'value', newValueProp); activeElement.attachEvent('onpropertychange', handlePropertyChange); } @@ -1203,10 +1110,7 @@ function handlePropertyChange(nativeEvent) { /** * If a `change` event should be fired, returns the target's ID. */ -function getTargetIDForInputEvent( - topLevelType, - topLevelTarget, - topLevelTargetID) { +function getTargetIDForInputEvent(topLevelType, topLevelTarget, topLevelTargetID) { if (topLevelType === topLevelTypes.topInput) { // In modern browsers (i.e., not IE8 or IE9), the input event is exactly // what we want so fall through here and trigger an abstract event @@ -1215,10 +1119,7 @@ function getTargetIDForInputEvent( } // For IE8 and IE9. -function handleEventsForInputEventIE( - topLevelType, - topLevelTarget, - topLevelTargetID) { +function handleEventsForInputEventIE(topLevelType, topLevelTarget, topLevelTargetID) { if (topLevelType === topLevelTypes.topFocus) { // In IE8, we can capture almost all .value changes by adding a // propertychange handler and looking for events with propertyName @@ -1241,13 +1142,8 @@ function handleEventsForInputEventIE( } // For IE8 and IE9. -function getTargetIDForInputEventIE( - topLevelType, - topLevelTarget, - topLevelTargetID) { - if (topLevelType === topLevelTypes.topSelectionChange || - topLevelType === topLevelTypes.topKeyUp || - topLevelType === topLevelTypes.topKeyDown) { +function getTargetIDForInputEventIE(topLevelType, topLevelTarget, topLevelTargetID) { + if (topLevelType === topLevelTypes.topSelectionChange || topLevelType === topLevelTypes.topKeyUp || topLevelType === topLevelTypes.topKeyDown) { // On the selectionchange event, the target is just document which isn't // helpful for us so just check activeElement instead. // @@ -1265,7 +1161,6 @@ function getTargetIDForInputEventIE( } } - /** * SECTION: handle `click` event */ @@ -1273,16 +1168,10 @@ function shouldUseClickEvent(elem) { // Use the `click` event to detect changes to checkbox and radio inputs. // This approach works across all browsers, whereas `change` does not fire // until `blur` in IE8. - return ( - elem.nodeName === 'INPUT' && - (elem.type === 'checkbox' || elem.type === 'radio') - ); + return elem.nodeName && elem.nodeName.toLowerCase() === 'input' && (elem.type === 'checkbox' || elem.type === 'radio'); } -function getTargetIDForClickEvent( - topLevelType, - topLevelTarget, - topLevelTargetID) { +function getTargetIDForClickEvent(topLevelType, topLevelTarget, topLevelTargetID) { if (topLevelType === topLevelTypes.topClick) { return topLevelTargetID; } @@ -1310,11 +1199,7 @@ var ChangeEventPlugin = { * @return {*} An accumulation of synthetic events. * @see {EventPluginHub.extractEvents} */ - extractEvents: function( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent) { + extractEvents: function (topLevelType, topLevelTarget, topLevelTargetID, nativeEvent, nativeEventTarget) { var getTargetIDFunc, handleEventFunc; if (shouldUseChangeEvent(topLevelTarget)) { @@ -1335,36 +1220,24 @@ var ChangeEventPlugin = { } if (getTargetIDFunc) { - var targetID = getTargetIDFunc( - topLevelType, - topLevelTarget, - topLevelTargetID - ); + var targetID = getTargetIDFunc(topLevelType, topLevelTarget, topLevelTargetID); if (targetID) { - var event = SyntheticEvent.getPooled( - eventTypes.change, - targetID, - nativeEvent - ); + var event = SyntheticEvent.getPooled(eventTypes.change, targetID, nativeEvent, nativeEventTarget); + event.type = 'change'; EventPropagators.accumulateTwoPhaseDispatches(event); return event; } } if (handleEventFunc) { - handleEventFunc( - topLevelType, - topLevelTarget, - topLevelTargetID - ); + handleEventFunc(topLevelType, topLevelTarget, topLevelTargetID); } } }; module.exports = ChangeEventPlugin; - -},{"./EventConstants":16,"./EventPluginHub":18,"./EventPropagators":21,"./ExecutionEnvironment":22,"./ReactUpdates":89,"./SyntheticEvent":97,"./isEventSupported":138,"./isTextInputElement":140,"./keyOf":143}],9:[function(require,module,exports){ +},{"./EventConstants":17,"./EventPluginHub":18,"./EventPropagators":21,"./ReactUpdates":86,"./SyntheticEvent":95,"./getEventTarget":117,"./isEventSupported":122,"./isTextInputElement":123,"fbjs/lib/ExecutionEnvironment":133,"fbjs/lib/keyOf":151}],10:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -1382,14 +1255,13 @@ module.exports = ChangeEventPlugin; var nextReactRootIndex = 0; var ClientReactRootIndex = { - createReactRootIndex: function() { + createReactRootIndex: function () { return nextReactRootIndex++; } }; module.exports = ClientReactRootIndex; - -},{}],10:[function(require,module,exports){ +},{}],11:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2015, Facebook, Inc. @@ -1405,11 +1277,13 @@ module.exports = ClientReactRootIndex; 'use strict'; -var Danger = require("./Danger"); -var ReactMultiChildUpdateTypes = require("./ReactMultiChildUpdateTypes"); +var Danger = require('./Danger'); +var ReactMultiChildUpdateTypes = require('./ReactMultiChildUpdateTypes'); +var ReactPerf = require('./ReactPerf'); -var setTextContent = require("./setTextContent"); -var invariant = require("./invariant"); +var setInnerHTML = require('./setInnerHTML'); +var setTextContent = require('./setTextContent'); +var invariant = require('fbjs/lib/invariant'); /** * Inserts `childNode` as a child of `parentNode` at the `index`. @@ -1424,10 +1298,12 @@ function insertChildAt(parentNode, childNode, index) { // rely exclusively on `insertBefore(node, null)` instead of also using // `appendChild(node)`. However, using `undefined` is not allowed by all // browsers so we must replace it with `null`. - parentNode.insertBefore( - childNode, - parentNode.childNodes[index] || null - ); + + // fix render order error in safari + // IE8 will throw error when index out of list size. + var beforeChild = index >= parentNode.childNodes.length ? null : parentNode.childNodes.item(index); + + parentNode.insertBefore(childNode, beforeChild); } /** @@ -1447,7 +1323,7 @@ var DOMChildrenOperations = { * @param {array} markupList List of markup strings. * @internal */ - processUpdates: function(updates, markupList) { + processUpdates: function (updates, markupList) { var update; // Mapping from parent IDs to initial child orderings. var initialChildren = null; @@ -1456,23 +1332,12 @@ var DOMChildrenOperations = { for (var i = 0; i < updates.length; i++) { update = updates[i]; - if (update.type === ReactMultiChildUpdateTypes.MOVE_EXISTING || - update.type === ReactMultiChildUpdateTypes.REMOVE_NODE) { + if (update.type === ReactMultiChildUpdateTypes.MOVE_EXISTING || update.type === ReactMultiChildUpdateTypes.REMOVE_NODE) { var updatedIndex = update.fromIndex; var updatedChild = update.parentNode.childNodes[updatedIndex]; var parentID = update.parentID; - ("production" !== process.env.NODE_ENV ? invariant( - updatedChild, - 'processUpdates(): Unable to find child %s of element. This ' + - 'probably means the DOM was unexpectedly mutated (e.g., by the ' + - 'browser), usually due to forgetting a when using tables, ' + - 'nesting tags like
,

, or , or using non-SVG elements ' + - 'in an parent. Try inspecting the child nodes of the element ' + - 'with React ID `%s`.', - updatedIndex, - parentID - ) : invariant(updatedChild)); + !updatedChild ? process.env.NODE_ENV !== 'production' ? invariant(false, 'processUpdates(): Unable to find child %s of element. This ' + 'probably means the DOM was unexpectedly mutated (e.g., by the ' + 'browser), usually due to forgetting a when using tables, ' + 'nesting tags like
,

, or , or using non-SVG elements ' + 'in an parent. Try inspecting the child nodes of the element ' + 'with React ID `%s`.', updatedIndex, parentID) : invariant(false) : undefined; initialChildren = initialChildren || {}; initialChildren[parentID] = initialChildren[parentID] || []; @@ -1483,7 +1348,13 @@ var DOMChildrenOperations = { } } - var renderedMarkup = Danger.dangerouslyRenderMarkup(markupList); + var renderedMarkup; + // markupList is either a list of markup or just a list of elements + if (markupList.length && typeof markupList[0] === 'string') { + renderedMarkup = Danger.dangerouslyRenderMarkup(markupList); + } else { + renderedMarkup = markupList; + } // Remove updated children first so that `toIndex` is consistent. if (updatedChildren) { @@ -1496,24 +1367,16 @@ var DOMChildrenOperations = { update = updates[k]; switch (update.type) { case ReactMultiChildUpdateTypes.INSERT_MARKUP: - insertChildAt( - update.parentNode, - renderedMarkup[update.markupIndex], - update.toIndex - ); + insertChildAt(update.parentNode, renderedMarkup[update.markupIndex], update.toIndex); break; case ReactMultiChildUpdateTypes.MOVE_EXISTING: - insertChildAt( - update.parentNode, - initialChildren[update.parentID][update.fromIndex], - update.toIndex - ); + insertChildAt(update.parentNode, initialChildren[update.parentID][update.fromIndex], update.toIndex); + break; + case ReactMultiChildUpdateTypes.SET_MARKUP: + setInnerHTML(update.parentNode, update.content); break; case ReactMultiChildUpdateTypes.TEXT_CONTENT: - setTextContent( - update.parentNode, - update.textContent - ); + setTextContent(update.parentNode, update.content); break; case ReactMultiChildUpdateTypes.REMOVE_NODE: // Already removed by the for-loop above. @@ -1524,10 +1387,13 @@ var DOMChildrenOperations = { }; -module.exports = DOMChildrenOperations; +ReactPerf.measureMethods(DOMChildrenOperations, 'DOMChildrenOperations', { + updateTextContent: 'updateTextContent' +}); +module.exports = DOMChildrenOperations; }).call(this,require('_process')) -},{"./Danger":13,"./ReactMultiChildUpdateTypes":74,"./invariant":137,"./setTextContent":151,"_process":158}],11:[function(require,module,exports){ +},{"./Danger":14,"./ReactMultiChildUpdateTypes":70,"./ReactPerf":74,"./setInnerHTML":127,"./setTextContent":128,"_process":160,"fbjs/lib/invariant":147}],12:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2015, Facebook, Inc. @@ -1541,11 +1407,9 @@ module.exports = DOMChildrenOperations; * @typechecks static-only */ -/*jslint bitwise: true */ - 'use strict'; -var invariant = require("./invariant"); +var invariant = require('fbjs/lib/invariant'); function checkMask(value, bitmask) { return (value & bitmask) === bitmask; @@ -1581,6 +1445,9 @@ var DOMPropertyInjection = { * attribute name. Attribute names not specified use the **lowercase** * normalized name. * + * DOMAttributeNamespaces: object mapping React attribute name to the DOM + * attribute namespace URL. (Attribute names not specified use no namespace.) + * * DOMPropertyNames: similar to DOMAttributeNames but for DOM properties. * Property names not specified use the normalized name. * @@ -1589,92 +1456,68 @@ var DOMPropertyInjection = { * * @param {object} domPropertyConfig the config as described above. */ - injectDOMPropertyConfig: function(domPropertyConfig) { + injectDOMPropertyConfig: function (domPropertyConfig) { + var Injection = DOMPropertyInjection; var Properties = domPropertyConfig.Properties || {}; + var DOMAttributeNamespaces = domPropertyConfig.DOMAttributeNamespaces || {}; var DOMAttributeNames = domPropertyConfig.DOMAttributeNames || {}; var DOMPropertyNames = domPropertyConfig.DOMPropertyNames || {}; var DOMMutationMethods = domPropertyConfig.DOMMutationMethods || {}; if (domPropertyConfig.isCustomAttribute) { - DOMProperty._isCustomAttributeFunctions.push( - domPropertyConfig.isCustomAttribute - ); + DOMProperty._isCustomAttributeFunctions.push(domPropertyConfig.isCustomAttribute); } for (var propName in Properties) { - ("production" !== process.env.NODE_ENV ? invariant( - !DOMProperty.isStandardName.hasOwnProperty(propName), - 'injectDOMPropertyConfig(...): You\'re trying to inject DOM property ' + - '\'%s\' which has already been injected. You may be accidentally ' + - 'injecting the same DOM property config twice, or you may be ' + - 'injecting two configs that have conflicting property names.', - propName - ) : invariant(!DOMProperty.isStandardName.hasOwnProperty(propName))); - - DOMProperty.isStandardName[propName] = true; + !!DOMProperty.properties.hasOwnProperty(propName) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'injectDOMPropertyConfig(...): You\'re trying to inject DOM property ' + '\'%s\' which has already been injected. You may be accidentally ' + 'injecting the same DOM property config twice, or you may be ' + 'injecting two configs that have conflicting property names.', propName) : invariant(false) : undefined; var lowerCased = propName.toLowerCase(); - DOMProperty.getPossibleStandardName[lowerCased] = propName; + var propConfig = Properties[propName]; + + var propertyInfo = { + attributeName: lowerCased, + attributeNamespace: null, + propertyName: propName, + mutationMethod: null, + + mustUseAttribute: checkMask(propConfig, Injection.MUST_USE_ATTRIBUTE), + mustUseProperty: checkMask(propConfig, Injection.MUST_USE_PROPERTY), + hasSideEffects: checkMask(propConfig, Injection.HAS_SIDE_EFFECTS), + hasBooleanValue: checkMask(propConfig, Injection.HAS_BOOLEAN_VALUE), + hasNumericValue: checkMask(propConfig, Injection.HAS_NUMERIC_VALUE), + hasPositiveNumericValue: checkMask(propConfig, Injection.HAS_POSITIVE_NUMERIC_VALUE), + hasOverloadedBooleanValue: checkMask(propConfig, Injection.HAS_OVERLOADED_BOOLEAN_VALUE) + }; + + !(!propertyInfo.mustUseAttribute || !propertyInfo.mustUseProperty) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'DOMProperty: Cannot require using both attribute and property: %s', propName) : invariant(false) : undefined; + !(propertyInfo.mustUseProperty || !propertyInfo.hasSideEffects) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'DOMProperty: Properties that have side effects must use property: %s', propName) : invariant(false) : undefined; + !(propertyInfo.hasBooleanValue + propertyInfo.hasNumericValue + propertyInfo.hasOverloadedBooleanValue <= 1) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'DOMProperty: Value can be one of boolean, overloaded boolean, or ' + 'numeric value, but not a combination: %s', propName) : invariant(false) : undefined; + + if (process.env.NODE_ENV !== 'production') { + DOMProperty.getPossibleStandardName[lowerCased] = propName; + } if (DOMAttributeNames.hasOwnProperty(propName)) { var attributeName = DOMAttributeNames[propName]; - DOMProperty.getPossibleStandardName[attributeName] = propName; - DOMProperty.getAttributeName[propName] = attributeName; - } else { - DOMProperty.getAttributeName[propName] = lowerCased; + propertyInfo.attributeName = attributeName; + if (process.env.NODE_ENV !== 'production') { + DOMProperty.getPossibleStandardName[attributeName] = propName; + } + } + + if (DOMAttributeNamespaces.hasOwnProperty(propName)) { + propertyInfo.attributeNamespace = DOMAttributeNamespaces[propName]; } - DOMProperty.getPropertyName[propName] = - DOMPropertyNames.hasOwnProperty(propName) ? - DOMPropertyNames[propName] : - propName; + if (DOMPropertyNames.hasOwnProperty(propName)) { + propertyInfo.propertyName = DOMPropertyNames[propName]; + } if (DOMMutationMethods.hasOwnProperty(propName)) { - DOMProperty.getMutationMethod[propName] = DOMMutationMethods[propName]; - } else { - DOMProperty.getMutationMethod[propName] = null; + propertyInfo.mutationMethod = DOMMutationMethods[propName]; } - var propConfig = Properties[propName]; - DOMProperty.mustUseAttribute[propName] = - checkMask(propConfig, DOMPropertyInjection.MUST_USE_ATTRIBUTE); - DOMProperty.mustUseProperty[propName] = - checkMask(propConfig, DOMPropertyInjection.MUST_USE_PROPERTY); - DOMProperty.hasSideEffects[propName] = - checkMask(propConfig, DOMPropertyInjection.HAS_SIDE_EFFECTS); - DOMProperty.hasBooleanValue[propName] = - checkMask(propConfig, DOMPropertyInjection.HAS_BOOLEAN_VALUE); - DOMProperty.hasNumericValue[propName] = - checkMask(propConfig, DOMPropertyInjection.HAS_NUMERIC_VALUE); - DOMProperty.hasPositiveNumericValue[propName] = - checkMask(propConfig, DOMPropertyInjection.HAS_POSITIVE_NUMERIC_VALUE); - DOMProperty.hasOverloadedBooleanValue[propName] = - checkMask(propConfig, DOMPropertyInjection.HAS_OVERLOADED_BOOLEAN_VALUE); - - ("production" !== process.env.NODE_ENV ? invariant( - !DOMProperty.mustUseAttribute[propName] || - !DOMProperty.mustUseProperty[propName], - 'DOMProperty: Cannot require using both attribute and property: %s', - propName - ) : invariant(!DOMProperty.mustUseAttribute[propName] || - !DOMProperty.mustUseProperty[propName])); - ("production" !== process.env.NODE_ENV ? invariant( - DOMProperty.mustUseProperty[propName] || - !DOMProperty.hasSideEffects[propName], - 'DOMProperty: Properties that have side effects must use property: %s', - propName - ) : invariant(DOMProperty.mustUseProperty[propName] || - !DOMProperty.hasSideEffects[propName])); - ("production" !== process.env.NODE_ENV ? invariant( - !!DOMProperty.hasBooleanValue[propName] + - !!DOMProperty.hasNumericValue[propName] + - !!DOMProperty.hasOverloadedBooleanValue[propName] <= 1, - 'DOMProperty: Value can be one of boolean, overloaded boolean, or ' + - 'numeric value, but not a combination: %s', - propName - ) : invariant(!!DOMProperty.hasBooleanValue[propName] + - !!DOMProperty.hasNumericValue[propName] + - !!DOMProperty.hasOverloadedBooleanValue[propName] <= 1)); + DOMProperty.properties[propName] = propertyInfo; } } }; @@ -1698,87 +1541,49 @@ var DOMProperty = { ID_ATTRIBUTE_NAME: 'data-reactid', /** - * Checks whether a property name is a standard property. - * @type {Object} + * Map from property "standard name" to an object with info about how to set + * the property in the DOM. Each object contains: + * + * attributeName: + * Used when rendering markup or with `*Attribute()`. + * attributeNamespace + * propertyName: + * Used on DOM node instances. (This includes properties that mutate due to + * external factors.) + * mutationMethod: + * If non-null, used instead of the property or `setAttribute()` after + * initial render. + * mustUseAttribute: + * Whether the property must be accessed and mutated using `*Attribute()`. + * (This includes anything that fails ` in `.) + * mustUseProperty: + * Whether the property must be accessed and mutated as an object property. + * hasSideEffects: + * Whether or not setting a value causes side effects such as triggering + * resources to be loaded or text selection changes. If true, we read from + * the DOM before updating to ensure that the value is only set if it has + * changed. + * hasBooleanValue: + * Whether the property should be removed when set to a falsey value. + * hasNumericValue: + * Whether the property must be numeric or parse as a numeric and should be + * removed when set to a falsey value. + * hasPositiveNumericValue: + * Whether the property must be positive numeric or parse as a positive + * numeric and should be removed when set to a falsey value. + * hasOverloadedBooleanValue: + * Whether the property can be used as a flag as well as with a value. + * Removed when strictly equal to false; present without a value when + * strictly equal to true; present with a value otherwise. */ - isStandardName: {}, + properties: {}, /** * Mapping from lowercase property names to the properly cased version, used - * to warn in the case of missing properties. - * @type {Object} - */ - getPossibleStandardName: {}, - - /** - * Mapping from normalized names to attribute names that differ. Attribute - * names are used when rendering markup or with `*Attribute()`. - * @type {Object} - */ - getAttributeName: {}, - - /** - * Mapping from normalized names to properties on DOM node instances. - * (This includes properties that mutate due to external factors.) - * @type {Object} - */ - getPropertyName: {}, - - /** - * Mapping from normalized names to mutation methods. This will only exist if - * mutation cannot be set simply by the property or `setAttribute()`. - * @type {Object} - */ - getMutationMethod: {}, - - /** - * Whether the property must be accessed and mutated as an object property. - * @type {Object} - */ - mustUseAttribute: {}, - - /** - * Whether the property must be accessed and mutated using `*Attribute()`. - * (This includes anything that fails ` in `.) - * @type {Object} - */ - mustUseProperty: {}, - - /** - * Whether or not setting a value causes side effects such as triggering - * resources to be loaded or text selection changes. We must ensure that - * the value is only set if it has changed. - * @type {Object} - */ - hasSideEffects: {}, - - /** - * Whether the property should be removed when set to a falsey value. - * @type {Object} - */ - hasBooleanValue: {}, - - /** - * Whether the property must be numeric or parse as a - * numeric and should be removed when set to a falsey value. - * @type {Object} - */ - hasNumericValue: {}, - - /** - * Whether the property must be positive numeric or parse as a positive - * numeric and should be removed when set to a falsey value. - * @type {Object} - */ - hasPositiveNumericValue: {}, - - /** - * Whether the property can be used as a flag as well as with a value. Removed - * when strictly equal to false; present without a value when strictly equal - * to true; present with a value otherwise. + * to warn in the case of missing properties. Available only in __DEV__. * @type {Object} */ - hasOverloadedBooleanValue: {}, + getPossibleStandardName: process.env.NODE_ENV !== 'production' ? {} : null, /** * All of the isCustomAttribute() functions that have been injected. @@ -1789,7 +1594,7 @@ var DOMProperty = { * Checks whether a property name is a custom attribute. * @method */ - isCustomAttribute: function(attributeName) { + isCustomAttribute: function (attributeName) { for (var i = 0; i < DOMProperty._isCustomAttributeFunctions.length; i++) { var isCustomAttributeFn = DOMProperty._isCustomAttributeFunctions[i]; if (isCustomAttributeFn(attributeName)) { @@ -1807,7 +1612,7 @@ var DOMProperty = { * TODO: Is it better to grab all the possible properties when creating an * element to avoid having to create the same element twice? */ - getDefaultValueForProperty: function(nodeName, prop) { + getDefaultValueForProperty: function (nodeName, prop) { var nodeDefaults = defaultValueCache[nodeName]; var testElement; if (!nodeDefaults) { @@ -1824,9 +1629,8 @@ var DOMProperty = { }; module.exports = DOMProperty; - }).call(this,require('_process')) -},{"./invariant":137,"_process":158}],12:[function(require,module,exports){ +},{"_process":160,"fbjs/lib/invariant":147}],13:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2015, Facebook, Inc. @@ -1842,20 +1646,38 @@ module.exports = DOMProperty; 'use strict'; -var DOMProperty = require("./DOMProperty"); +var DOMProperty = require('./DOMProperty'); +var ReactPerf = require('./ReactPerf'); + +var quoteAttributeValueForBrowser = require('./quoteAttributeValueForBrowser'); +var warning = require('fbjs/lib/warning'); -var quoteAttributeValueForBrowser = require("./quoteAttributeValueForBrowser"); -var warning = require("./warning"); +// Simplified subset +var VALID_ATTRIBUTE_NAME_REGEX = /^[a-zA-Z_][\w\.\-]*$/; +var illegalAttributeNameCache = {}; +var validatedAttributeNameCache = {}; + +function isAttributeNameSafe(attributeName) { + if (validatedAttributeNameCache.hasOwnProperty(attributeName)) { + return true; + } + if (illegalAttributeNameCache.hasOwnProperty(attributeName)) { + return false; + } + if (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName)) { + validatedAttributeNameCache[attributeName] = true; + return true; + } + illegalAttributeNameCache[attributeName] = true; + process.env.NODE_ENV !== 'production' ? warning(false, 'Invalid attribute name: `%s`', attributeName) : undefined; + return false; +} -function shouldIgnoreValue(name, value) { - return value == null || - (DOMProperty.hasBooleanValue[name] && !value) || - (DOMProperty.hasNumericValue[name] && isNaN(value)) || - (DOMProperty.hasPositiveNumericValue[name] && (value < 1)) || - (DOMProperty.hasOverloadedBooleanValue[name] && value === false); +function shouldIgnoreValue(propertyInfo, value) { + return value == null || propertyInfo.hasBooleanValue && !value || propertyInfo.hasNumericValue && isNaN(value) || propertyInfo.hasPositiveNumericValue && value < 1 || propertyInfo.hasOverloadedBooleanValue && value === false; } -if ("production" !== process.env.NODE_ENV) { +if (process.env.NODE_ENV !== 'production') { var reactProps = { children: true, dangerouslySetInnerHTML: true, @@ -1864,9 +1686,8 @@ if ("production" !== process.env.NODE_ENV) { }; var warnedProperties = {}; - var warnUnknownProperty = function(name) { - if (reactProps.hasOwnProperty(name) && reactProps[name] || - warnedProperties.hasOwnProperty(name) && warnedProperties[name]) { + var warnUnknownProperty = function (name) { + if (reactProps.hasOwnProperty(name) && reactProps[name] || warnedProperties.hasOwnProperty(name) && warnedProperties[name]) { return; } @@ -1874,23 +1695,11 @@ if ("production" !== process.env.NODE_ENV) { var lowerCasedName = name.toLowerCase(); // data-* attributes should be lowercase; suggest the lowercase version - var standardName = ( - DOMProperty.isCustomAttribute(lowerCasedName) ? - lowerCasedName : - DOMProperty.getPossibleStandardName.hasOwnProperty(lowerCasedName) ? - DOMProperty.getPossibleStandardName[lowerCasedName] : - null - ); + var standardName = DOMProperty.isCustomAttribute(lowerCasedName) ? lowerCasedName : DOMProperty.getPossibleStandardName.hasOwnProperty(lowerCasedName) ? DOMProperty.getPossibleStandardName[lowerCasedName] : null; // For now, only warn when we have a suggested correction. This prevents // logging too much when using transferPropsTo. - ("production" !== process.env.NODE_ENV ? warning( - standardName == null, - 'Unknown DOM property %s. Did you mean %s?', - name, - standardName - ) : null); - + process.env.NODE_ENV !== 'production' ? warning(standardName == null, 'Unknown DOM property %s. Did you mean %s?', name, standardName) : undefined; }; } @@ -1905,9 +1714,12 @@ var DOMPropertyOperations = { * @param {string} id Unescaped ID. * @return {string} Markup string. */ - createMarkupForID: function(id) { - return DOMProperty.ID_ATTRIBUTE_NAME + '=' + - quoteAttributeValueForBrowser(id); + createMarkupForID: function (id) { + return DOMProperty.ID_ATTRIBUTE_NAME + '=' + quoteAttributeValueForBrowser(id); + }, + + setAttributeForID: function (node, id) { + node.setAttribute(DOMProperty.ID_ATTRIBUTE_NAME, id); }, /** @@ -1917,16 +1729,15 @@ var DOMPropertyOperations = { * @param {*} value * @return {?string} Markup string, or null if the property was invalid. */ - createMarkupForProperty: function(name, value) { - if (DOMProperty.isStandardName.hasOwnProperty(name) && - DOMProperty.isStandardName[name]) { - if (shouldIgnoreValue(name, value)) { + createMarkupForProperty: function (name, value) { + var propertyInfo = DOMProperty.properties.hasOwnProperty(name) ? DOMProperty.properties[name] : null; + if (propertyInfo) { + if (shouldIgnoreValue(propertyInfo, value)) { return ''; } - var attributeName = DOMProperty.getAttributeName[name]; - if (DOMProperty.hasBooleanValue[name] || - (DOMProperty.hasOverloadedBooleanValue[name] && value === true)) { - return attributeName; + var attributeName = propertyInfo.attributeName; + if (propertyInfo.hasBooleanValue || propertyInfo.hasOverloadedBooleanValue && value === true) { + return attributeName + '=""'; } return attributeName + '=' + quoteAttributeValueForBrowser(value); } else if (DOMProperty.isCustomAttribute(name)) { @@ -1934,12 +1745,26 @@ var DOMPropertyOperations = { return ''; } return name + '=' + quoteAttributeValueForBrowser(value); - } else if ("production" !== process.env.NODE_ENV) { + } else if (process.env.NODE_ENV !== 'production') { warnUnknownProperty(name); } return null; }, + /** + * Creates markup for a custom property. + * + * @param {string} name + * @param {*} value + * @return {string} Markup string, or empty string if the property was invalid. + */ + createMarkupForCustomAttribute: function (name, value) { + if (!isAttributeNameSafe(name) || value == null) { + return ''; + } + return name + '=' + quoteAttributeValueForBrowser(value); + }, + /** * Sets the value for a property on a node. * @@ -1947,78 +1772,93 @@ var DOMPropertyOperations = { * @param {string} name * @param {*} value */ - setValueForProperty: function(node, name, value) { - if (DOMProperty.isStandardName.hasOwnProperty(name) && - DOMProperty.isStandardName[name]) { - var mutationMethod = DOMProperty.getMutationMethod[name]; + setValueForProperty: function (node, name, value) { + var propertyInfo = DOMProperty.properties.hasOwnProperty(name) ? DOMProperty.properties[name] : null; + if (propertyInfo) { + var mutationMethod = propertyInfo.mutationMethod; if (mutationMethod) { mutationMethod(node, value); - } else if (shouldIgnoreValue(name, value)) { + } else if (shouldIgnoreValue(propertyInfo, value)) { this.deleteValueForProperty(node, name); - } else if (DOMProperty.mustUseAttribute[name]) { + } else if (propertyInfo.mustUseAttribute) { + var attributeName = propertyInfo.attributeName; + var namespace = propertyInfo.attributeNamespace; // `setAttribute` with objects becomes only `[object]` in IE8/9, // ('' + value) makes it output the correct toString()-value. - node.setAttribute(DOMProperty.getAttributeName[name], '' + value); + if (namespace) { + node.setAttributeNS(namespace, attributeName, '' + value); + } else if (propertyInfo.hasBooleanValue || propertyInfo.hasOverloadedBooleanValue && value === true) { + node.setAttribute(attributeName, ''); + } else { + node.setAttribute(attributeName, '' + value); + } } else { - var propName = DOMProperty.getPropertyName[name]; + var propName = propertyInfo.propertyName; // Must explicitly cast values for HAS_SIDE_EFFECTS-properties to the // property type before comparing; only `value` does and is string. - if (!DOMProperty.hasSideEffects[name] || - ('' + node[propName]) !== ('' + value)) { + if (!propertyInfo.hasSideEffects || '' + node[propName] !== '' + value) { // Contrary to `setAttribute`, object properties are properly // `toString`ed by IE8/9. node[propName] = value; } } } else if (DOMProperty.isCustomAttribute(name)) { - if (value == null) { - node.removeAttribute(name); - } else { - node.setAttribute(name, '' + value); - } - } else if ("production" !== process.env.NODE_ENV) { + DOMPropertyOperations.setValueForAttribute(node, name, value); + } else if (process.env.NODE_ENV !== 'production') { warnUnknownProperty(name); } }, + setValueForAttribute: function (node, name, value) { + if (!isAttributeNameSafe(name)) { + return; + } + if (value == null) { + node.removeAttribute(name); + } else { + node.setAttribute(name, '' + value); + } + }, + /** * Deletes the value for a property on a node. * * @param {DOMElement} node * @param {string} name */ - deleteValueForProperty: function(node, name) { - if (DOMProperty.isStandardName.hasOwnProperty(name) && - DOMProperty.isStandardName[name]) { - var mutationMethod = DOMProperty.getMutationMethod[name]; + deleteValueForProperty: function (node, name) { + var propertyInfo = DOMProperty.properties.hasOwnProperty(name) ? DOMProperty.properties[name] : null; + if (propertyInfo) { + var mutationMethod = propertyInfo.mutationMethod; if (mutationMethod) { mutationMethod(node, undefined); - } else if (DOMProperty.mustUseAttribute[name]) { - node.removeAttribute(DOMProperty.getAttributeName[name]); + } else if (propertyInfo.mustUseAttribute) { + node.removeAttribute(propertyInfo.attributeName); } else { - var propName = DOMProperty.getPropertyName[name]; - var defaultValue = DOMProperty.getDefaultValueForProperty( - node.nodeName, - propName - ); - if (!DOMProperty.hasSideEffects[name] || - ('' + node[propName]) !== defaultValue) { + var propName = propertyInfo.propertyName; + var defaultValue = DOMProperty.getDefaultValueForProperty(node.nodeName, propName); + if (!propertyInfo.hasSideEffects || '' + node[propName] !== defaultValue) { node[propName] = defaultValue; } } } else if (DOMProperty.isCustomAttribute(name)) { node.removeAttribute(name); - } else if ("production" !== process.env.NODE_ENV) { + } else if (process.env.NODE_ENV !== 'production') { warnUnknownProperty(name); } } }; -module.exports = DOMPropertyOperations; +ReactPerf.measureMethods(DOMPropertyOperations, 'DOMPropertyOperations', { + setValueForProperty: 'setValueForProperty', + setValueForAttribute: 'setValueForAttribute', + deleteValueForProperty: 'deleteValueForProperty' +}); +module.exports = DOMPropertyOperations; }).call(this,require('_process')) -},{"./DOMProperty":11,"./quoteAttributeValueForBrowser":149,"./warning":156,"_process":158}],13:[function(require,module,exports){ +},{"./DOMProperty":12,"./ReactPerf":74,"./quoteAttributeValueForBrowser":125,"_process":160,"fbjs/lib/warning":158}],14:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2015, Facebook, Inc. @@ -2032,16 +1872,14 @@ module.exports = DOMPropertyOperations; * @typechecks static-only */ -/*jslint evil: true, sub: true */ - 'use strict'; -var ExecutionEnvironment = require("./ExecutionEnvironment"); +var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment'); -var createNodesFromMarkup = require("./createNodesFromMarkup"); -var emptyFunction = require("./emptyFunction"); -var getMarkupWrap = require("./getMarkupWrap"); -var invariant = require("./invariant"); +var createNodesFromMarkup = require('fbjs/lib/createNodesFromMarkup'); +var emptyFunction = require('fbjs/lib/emptyFunction'); +var getMarkupWrap = require('fbjs/lib/getMarkupWrap'); +var invariant = require('fbjs/lib/invariant'); var OPEN_TAG_NAME_EXP = /^(<[^ \/>]+)/; var RESULT_INDEX_ATTR = 'data-danger-index'; @@ -2072,22 +1910,13 @@ var Danger = { * @return {array} List of rendered nodes. * @internal */ - dangerouslyRenderMarkup: function(markupList) { - ("production" !== process.env.NODE_ENV ? invariant( - ExecutionEnvironment.canUseDOM, - 'dangerouslyRenderMarkup(...): Cannot render markup in a worker ' + - 'thread. Make sure `window` and `document` are available globally ' + - 'before requiring React when unit testing or use ' + - 'React.renderToString for server rendering.' - ) : invariant(ExecutionEnvironment.canUseDOM)); + dangerouslyRenderMarkup: function (markupList) { + !ExecutionEnvironment.canUseDOM ? process.env.NODE_ENV !== 'production' ? invariant(false, 'dangerouslyRenderMarkup(...): Cannot render markup in a worker ' + 'thread. Make sure `window` and `document` are available globally ' + 'before requiring React when unit testing or use ' + 'ReactDOMServer.renderToString for server rendering.') : invariant(false) : undefined; var nodeName; var markupByNodeName = {}; // Group markup by `nodeName` if a wrap is necessary, else by '*'. for (var i = 0; i < markupList.length; i++) { - ("production" !== process.env.NODE_ENV ? invariant( - markupList[i], - 'dangerouslyRenderMarkup(...): Missing markup.' - ) : invariant(markupList[i])); + !markupList[i] ? process.env.NODE_ENV !== 'production' ? invariant(false, 'dangerouslyRenderMarkup(...): Missing markup.') : invariant(false) : undefined; nodeName = getNodeName(markupList[i]); nodeName = getMarkupWrap(nodeName) ? nodeName : '*'; markupByNodeName[nodeName] = markupByNodeName[nodeName] || []; @@ -2112,61 +1941,41 @@ var Danger = { // Push the requested markup with an additional RESULT_INDEX_ATTR // attribute. If the markup does not start with a < character, it // will be discarded below (with an appropriate console.error). - markupListByNodeName[resultIndex] = markup.replace( - OPEN_TAG_NAME_EXP, - // This index will be parsed back out below. - '$1 ' + RESULT_INDEX_ATTR + '="' + resultIndex + '" ' - ); + markupListByNodeName[resultIndex] = markup.replace(OPEN_TAG_NAME_EXP, + // This index will be parsed back out below. + '$1 ' + RESULT_INDEX_ATTR + '="' + resultIndex + '" '); } } // Render each group of markup with similar wrapping `nodeName`. - var renderNodes = createNodesFromMarkup( - markupListByNodeName.join(''), - emptyFunction // Do nothing special with

; - * } - * - * @param {object} newContext New context to merge into the existing context - * @param {function} scopedCallback Callback to run with the new context - * @return {ReactComponent|array} - */ - withContext: function(newContext, scopedCallback) { - if ("production" !== process.env.NODE_ENV) { - ("production" !== process.env.NODE_ENV ? warning( - didWarn, - 'withContext is deprecated and will be removed in a future version. ' + - 'Use a wrapper component with getChildContext instead.' - ) : null); - - didWarn = true; - } - - var result; - var previousContext = ReactContext.current; - ReactContext.current = assign({}, previousContext, newContext); - try { - result = scopedCallback(); - } finally { - ReactContext.current = previousContext; - } - return result; - } - -}; - -module.exports = ReactContext; - }).call(this,require('_process')) -},{"./Object.assign":28,"./emptyObject":117,"./warning":156,"_process":158}],41:[function(require,module,exports){ +},{"./Object.assign":25,"./ReactComponentEnvironment":35,"./ReactCurrentOwner":37,"./ReactElement":55,"./ReactInstanceMap":65,"./ReactPerf":74,"./ReactPropTypeLocationNames":75,"./ReactPropTypeLocations":76,"./ReactReconciler":79,"./ReactUpdateQueue":85,"./shouldUpdateReactComponent":129,"_process":160,"fbjs/lib/emptyObject":140,"fbjs/lib/invariant":147,"fbjs/lib/warning":158}],37:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -7283,8 +6157,6 @@ module.exports = ReactContext; * * The current owner is the component who should own any components that are * currently being constructed. - * - * The depth indicate how many composite components are above this render level. */ var ReactCurrentOwner = { @@ -7297,8 +6169,7 @@ var ReactCurrentOwner = { }; module.exports = ReactCurrentOwner; - -},{}],42:[function(require,module,exports){ +},{}],38:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2015, Facebook, Inc. @@ -7309,175 +6180,91 @@ module.exports = ReactCurrentOwner; * of patent rights can be found in the PATENTS file in the same directory. * * @providesModule ReactDOM - * @typechecks static-only */ +/* globals __REACT_DEVTOOLS_GLOBAL_HOOK__*/ + 'use strict'; -var ReactElement = require("./ReactElement"); -var ReactElementValidator = require("./ReactElementValidator"); +var ReactCurrentOwner = require('./ReactCurrentOwner'); +var ReactDOMTextComponent = require('./ReactDOMTextComponent'); +var ReactDefaultInjection = require('./ReactDefaultInjection'); +var ReactInstanceHandles = require('./ReactInstanceHandles'); +var ReactMount = require('./ReactMount'); +var ReactPerf = require('./ReactPerf'); +var ReactReconciler = require('./ReactReconciler'); +var ReactUpdates = require('./ReactUpdates'); +var ReactVersion = require('./ReactVersion'); -var mapObject = require("./mapObject"); +var findDOMNode = require('./findDOMNode'); +var renderSubtreeIntoContainer = require('./renderSubtreeIntoContainer'); +var warning = require('fbjs/lib/warning'); -/** - * Create a factory that creates HTML tag elements. - * - * @param {string} tag Tag name (e.g. `div`). - * @private - */ -function createDOMFactory(tag) { - if ("production" !== process.env.NODE_ENV) { - return ReactElementValidator.createFactory(tag); - } - return ReactElement.createFactory(tag); +ReactDefaultInjection.inject(); + +var render = ReactPerf.measure('React', 'render', ReactMount.render); + +var React = { + findDOMNode: findDOMNode, + render: render, + unmountComponentAtNode: ReactMount.unmountComponentAtNode, + version: ReactVersion, + + /* eslint-disable camelcase */ + unstable_batchedUpdates: ReactUpdates.batchedUpdates, + unstable_renderSubtreeIntoContainer: renderSubtreeIntoContainer +}; + +// Inject the runtime into a devtools global hook regardless of browser. +// Allows for debugging when the hook is injected on the page. +/* eslint-enable camelcase */ +if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' && typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.inject === 'function') { + __REACT_DEVTOOLS_GLOBAL_HOOK__.inject({ + CurrentOwner: ReactCurrentOwner, + InstanceHandles: ReactInstanceHandles, + Mount: ReactMount, + Reconciler: ReactReconciler, + TextComponent: ReactDOMTextComponent + }); } -/** - * Creates a mapping from supported HTML tags to `ReactDOMComponent` classes. - * This is also accessible via `React.DOM`. - * - * @public - */ -var ReactDOM = mapObject({ - a: 'a', - abbr: 'abbr', - address: 'address', - area: 'area', - article: 'article', - aside: 'aside', - audio: 'audio', - b: 'b', - base: 'base', - bdi: 'bdi', - bdo: 'bdo', - big: 'big', - blockquote: 'blockquote', - body: 'body', - br: 'br', - button: 'button', - canvas: 'canvas', - caption: 'caption', - cite: 'cite', - code: 'code', - col: 'col', - colgroup: 'colgroup', - data: 'data', - datalist: 'datalist', - dd: 'dd', - del: 'del', - details: 'details', - dfn: 'dfn', - dialog: 'dialog', - div: 'div', - dl: 'dl', - dt: 'dt', - em: 'em', - embed: 'embed', - fieldset: 'fieldset', - figcaption: 'figcaption', - figure: 'figure', - footer: 'footer', - form: 'form', - h1: 'h1', - h2: 'h2', - h3: 'h3', - h4: 'h4', - h5: 'h5', - h6: 'h6', - head: 'head', - header: 'header', - hr: 'hr', - html: 'html', - i: 'i', - iframe: 'iframe', - img: 'img', - input: 'input', - ins: 'ins', - kbd: 'kbd', - keygen: 'keygen', - label: 'label', - legend: 'legend', - li: 'li', - link: 'link', - main: 'main', - map: 'map', - mark: 'mark', - menu: 'menu', - menuitem: 'menuitem', - meta: 'meta', - meter: 'meter', - nav: 'nav', - noscript: 'noscript', - object: 'object', - ol: 'ol', - optgroup: 'optgroup', - option: 'option', - output: 'output', - p: 'p', - param: 'param', - picture: 'picture', - pre: 'pre', - progress: 'progress', - q: 'q', - rp: 'rp', - rt: 'rt', - ruby: 'ruby', - s: 's', - samp: 'samp', - script: 'script', - section: 'section', - select: 'select', - small: 'small', - source: 'source', - span: 'span', - strong: 'strong', - style: 'style', - sub: 'sub', - summary: 'summary', - sup: 'sup', - table: 'table', - tbody: 'tbody', - td: 'td', - textarea: 'textarea', - tfoot: 'tfoot', - th: 'th', - thead: 'thead', - time: 'time', - title: 'title', - tr: 'tr', - track: 'track', - u: 'u', - ul: 'ul', - 'var': 'var', - video: 'video', - wbr: 'wbr', +if (process.env.NODE_ENV !== 'production') { + var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment'); + if (ExecutionEnvironment.canUseDOM && window.top === window.self) { - // SVG - circle: 'circle', - clipPath: 'clipPath', - defs: 'defs', - ellipse: 'ellipse', - g: 'g', - line: 'line', - linearGradient: 'linearGradient', - mask: 'mask', - path: 'path', - pattern: 'pattern', - polygon: 'polygon', - polyline: 'polyline', - radialGradient: 'radialGradient', - rect: 'rect', - stop: 'stop', - svg: 'svg', - text: 'text', - tspan: 'tspan' + // First check if devtools is not installed + if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') { + // If we're in Chrome or Firefox, provide a download link if not installed. + if (navigator.userAgent.indexOf('Chrome') > -1 && navigator.userAgent.indexOf('Edge') === -1 || navigator.userAgent.indexOf('Firefox') > -1) { + console.debug('Download the React DevTools for a better development experience: ' + 'https://fb.me/react-devtools'); + } + } -}, createDOMFactory); + // If we're in IE8, check to see if we are in compatibility mode and provide + // information on preventing compatibility mode + var ieCompatibilityMode = document.documentMode && document.documentMode < 8; + + process.env.NODE_ENV !== 'production' ? warning(!ieCompatibilityMode, 'Internet Explorer is running in compatibility mode; please add the ' + 'following tag to your HTML to prevent this from happening: ' + '') : undefined; + + var expectedFeatures = [ + // shims + Array.isArray, Array.prototype.every, Array.prototype.forEach, Array.prototype.indexOf, Array.prototype.map, Date.now, Function.prototype.bind, Object.keys, String.prototype.split, String.prototype.trim, -module.exports = ReactDOM; + // shams + Object.create, Object.freeze]; + + for (var i = 0; i < expectedFeatures.length; i++) { + if (!expectedFeatures[i]) { + console.error('One or more ES5 shim/shams expected by React are not available: ' + 'https://fb.me/react-warning-polyfills'); + break; + } + } + } +} +module.exports = React; }).call(this,require('_process')) -},{"./ReactElement":59,"./ReactElementValidator":60,"./mapObject":144,"_process":158}],43:[function(require,module,exports){ +},{"./ReactCurrentOwner":37,"./ReactDOMTextComponent":49,"./ReactDefaultInjection":52,"./ReactInstanceHandles":64,"./ReactMount":68,"./ReactPerf":74,"./ReactReconciler":79,"./ReactUpdates":86,"./ReactVersion":87,"./findDOMNode":111,"./renderSubtreeIntoContainer":126,"_process":160,"fbjs/lib/ExecutionEnvironment":133,"fbjs/lib/warning":158}],39:[function(require,module,exports){ /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. @@ -7491,57 +6278,44 @@ module.exports = ReactDOM; 'use strict'; -var AutoFocusMixin = require("./AutoFocusMixin"); -var ReactBrowserComponentMixin = require("./ReactBrowserComponentMixin"); -var ReactClass = require("./ReactClass"); -var ReactElement = require("./ReactElement"); - -var keyMirror = require("./keyMirror"); - -var button = ReactElement.createFactory('button'); - -var mouseListenerNames = keyMirror({ +var mouseListenerNames = { onClick: true, onDoubleClick: true, onMouseDown: true, onMouseMove: true, onMouseUp: true, + onClickCapture: true, onDoubleClickCapture: true, onMouseDownCapture: true, onMouseMoveCapture: true, onMouseUpCapture: true -}); +}; /** * Implements a