From c12b1f0289b2898716f54b931a14353065544122 Mon Sep 17 00:00:00 2001 From: Raynos Date: Fri, 18 Apr 2014 20:38:16 -0700 Subject: [PATCH 1/6] dom-property-config: move constants to own file This prepares the DefaultDOMPropertyConfig.js file to be broken out by breaing it's tight coupling to DOMProperty.js This will reduce complexity and size of `dom-property-config` module --- src/browser/ui/dom/DOMProperty.js | 17 ++++++++++------- .../ui/dom/DOMPropertyInjectionConstants.js | 11 +++++++++++ src/browser/ui/dom/DefaultDOMPropertyConfig.js | 16 ++++++++-------- 3 files changed, 29 insertions(+), 15 deletions(-) create mode 100644 src/browser/ui/dom/DOMPropertyInjectionConstants.js diff --git a/src/browser/ui/dom/DOMProperty.js b/src/browser/ui/dom/DOMProperty.js index 8d3d6626d0c..39d0f5a5a83 100644 --- a/src/browser/ui/dom/DOMProperty.js +++ b/src/browser/ui/dom/DOMProperty.js @@ -22,19 +22,22 @@ "use strict"; var invariant = require('invariant'); +var DOMPropertyInjectionConstants = require('DOMPropertyInjectionConstants'); var DOMPropertyInjection = { /** * Mapping from normalized, camelcased property names to a configuration that * specifies how the associated DOM property should be accessed or rendered. */ - MUST_USE_ATTRIBUTE: 0x1, - MUST_USE_PROPERTY: 0x2, - HAS_SIDE_EFFECTS: 0x4, - HAS_BOOLEAN_VALUE: 0x8, - HAS_NUMERIC_VALUE: 0x10, - HAS_POSITIVE_NUMERIC_VALUE: 0x20 | 0x10, - HAS_OVERLOADED_BOOLEAN_VALUE: 0x40, + MUST_USE_ATTRIBUTE: DOMPropertyInjectionConstants.MUST_USE_ATTRIBUTE, + MUST_USE_PROPERTY: DOMPropertyInjectionConstants.MUST_USE_PROPERTY, + HAS_SIDE_EFFECTS: DOMPropertyInjectionConstants.HAS_SIDE_EFFECTS, + HAS_BOOLEAN_VALUE: DOMPropertyInjectionConstants.HAS_BOOLEAN_VALUE, + HAS_NUMERIC_VALUE: DOMPropertyInjectionConstants.HAS_NUMERIC_VALUE, + HAS_POSITIVE_NUMERIC_VALUE: + DOMPropertyInjectionConstants.HAS_POSITIVE_NUMERIC_VALUE, + HAS_OVERLOADED_BOOLEAN_VALUE: + DOMPropertyInjectionConstants.HAS_OVERLOADED_BOOLEAN_VALUE, /** * Inject some specialized knowledge about the DOM. This takes a config object diff --git a/src/browser/ui/dom/DOMPropertyInjectionConstants.js b/src/browser/ui/dom/DOMPropertyInjectionConstants.js new file mode 100644 index 00000000000..b946287aea1 --- /dev/null +++ b/src/browser/ui/dom/DOMPropertyInjectionConstants.js @@ -0,0 +1,11 @@ +var DOMPropertyInjectionConstants = { + MUST_USE_ATTRIBUTE: 0x1, + MUST_USE_PROPERTY: 0x2, + HAS_SIDE_EFFECTS: 0x4, + HAS_BOOLEAN_VALUE: 0x8, + HAS_NUMERIC_VALUE: 0x10, + HAS_POSITIVE_NUMERIC_VALUE: 0x20 | 0x10, + HAS_OVERLOADED_BOOLEAN_VALUE: 0x40, +}; + +module.exports = DOMPropertyInjectionConstants; diff --git a/src/browser/ui/dom/DefaultDOMPropertyConfig.js b/src/browser/ui/dom/DefaultDOMPropertyConfig.js index 1e04bc7a03b..c02e1f4bbf8 100644 --- a/src/browser/ui/dom/DefaultDOMPropertyConfig.js +++ b/src/browser/ui/dom/DefaultDOMPropertyConfig.js @@ -20,17 +20,17 @@ "use strict"; -var DOMProperty = require('DOMProperty'); +var DOMPropertyInjectionConstants = require('DOMPropertyInjectionConstants'); -var MUST_USE_ATTRIBUTE = DOMProperty.injection.MUST_USE_ATTRIBUTE; -var MUST_USE_PROPERTY = DOMProperty.injection.MUST_USE_PROPERTY; -var HAS_BOOLEAN_VALUE = DOMProperty.injection.HAS_BOOLEAN_VALUE; -var HAS_SIDE_EFFECTS = DOMProperty.injection.HAS_SIDE_EFFECTS; -var HAS_NUMERIC_VALUE = DOMProperty.injection.HAS_NUMERIC_VALUE; +var MUST_USE_ATTRIBUTE = DOMPropertyInjectionConstants.MUST_USE_ATTRIBUTE; +var MUST_USE_PROPERTY = DOMPropertyInjectionConstants.MUST_USE_PROPERTY; +var HAS_BOOLEAN_VALUE = DOMPropertyInjectionConstants.HAS_BOOLEAN_VALUE; +var HAS_SIDE_EFFECTS = DOMPropertyInjectionConstants.HAS_SIDE_EFFECTS; +var HAS_NUMERIC_VALUE = DOMPropertyInjectionConstants.HAS_NUMERIC_VALUE; var HAS_POSITIVE_NUMERIC_VALUE = - DOMProperty.injection.HAS_POSITIVE_NUMERIC_VALUE; + DOMPropertyInjectionConstants.HAS_POSITIVE_NUMERIC_VALUE; var HAS_OVERLOADED_BOOLEAN_VALUE = - DOMProperty.injection.HAS_OVERLOADED_BOOLEAN_VALUE; + DOMPropertyInjectionConstants.HAS_OVERLOADED_BOOLEAN_VALUE; var DefaultDOMPropertyConfig = { isCustomAttribute: RegExp.prototype.test.bind( From 3db0d36a11fca12acf21f9e24a27d0c158c40597 Mon Sep 17 00:00:00 2001 From: Raynos Date: Fri, 18 Apr 2014 20:40:48 -0700 Subject: [PATCH 2/6] export Constants used in this file This will allow users of this module to understand what the flags mean without needing to know about the flags file --- src/browser/ui/dom/DefaultDOMPropertyConfig.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/browser/ui/dom/DefaultDOMPropertyConfig.js b/src/browser/ui/dom/DefaultDOMPropertyConfig.js index c02e1f4bbf8..057ab2867d2 100644 --- a/src/browser/ui/dom/DefaultDOMPropertyConfig.js +++ b/src/browser/ui/dom/DefaultDOMPropertyConfig.js @@ -198,7 +198,8 @@ var DefaultDOMPropertyConfig = { spellCheck: 'spellcheck', srcDoc: 'srcdoc', srcSet: 'srcset' - } + }, + Constants: DOMPropertyInjectionConstants }; module.exports = DefaultDOMPropertyConfig; From 908fa394c9b91c5bdcbb4c6c4236d3d31c35be13 Mon Sep 17 00:00:00 2001 From: Raynos Date: Fri, 18 Apr 2014 21:42:40 -0700 Subject: [PATCH 3/6] dom-property-config Set header in new file Must set the correct header including the providesModule directive --- .../ui/dom/DOMPropertyInjectionConstants.js | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/browser/ui/dom/DOMPropertyInjectionConstants.js b/src/browser/ui/dom/DOMPropertyInjectionConstants.js index b946287aea1..0c0646aad8e 100644 --- a/src/browser/ui/dom/DOMPropertyInjectionConstants.js +++ b/src/browser/ui/dom/DOMPropertyInjectionConstants.js @@ -1,3 +1,23 @@ +/** + * Copyright 2013-2014 Facebook, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @providesModule DOMPropertyInjectionConstants + */ + +/*jslint bitwise: true*/ + var DOMPropertyInjectionConstants = { MUST_USE_ATTRIBUTE: 0x1, MUST_USE_PROPERTY: 0x2, From 8f7562f3a93ded3098a26e68ddb494fa4b55cf5c Mon Sep 17 00:00:00 2001 From: Raynos Date: Fri, 18 Apr 2014 21:46:45 -0700 Subject: [PATCH 4/6] dom-property-config: Package description for dom-property-config Written a README.md & package.json for the new module --- npm-react/dom-property-config/README.md | 131 ++++++++++++++++++ .../dom-property-config.js | 1 + npm-react/dom-property-config/package.json | 29 ++++ 3 files changed, 161 insertions(+) create mode 100644 npm-react/dom-property-config/README.md create mode 100644 npm-react/dom-property-config/dom-property-config.js create mode 100644 npm-react/dom-property-config/package.json diff --git a/npm-react/dom-property-config/README.md b/npm-react/dom-property-config/README.md new file mode 100644 index 00000000000..f1fdab58bcd --- /dev/null +++ b/npm-react/dom-property-config/README.md @@ -0,0 +1,131 @@ +# dom-property-config + +A set of dom property rendering instructions + +`dom-property-config` contains the meta information on how to + correctly and performantly update any given property for a + DOM element. + +## Example (property serializer) + +You can use the `DOMAttributeNames` information to know how + to serialize DOM element properties to attributes correctly + +```js +var DOMAttributeNames = require('dom-property-config').DOMAttributeNames + +function elementSerializer(virtualElement) { + var attrs = [] + + Object.keys(virtualElement.properties).forEach(function (key) { + key = DOMAttributeNames[key] || key + + attrs.push(key + '=' + '"' + virtualElement.properties[key] + '"') + }) + + return '<' + virtualElement.tagName + + attrs.length ? ' ' + attrs.join(' ') : '' + + '' +} +``` + +## Example (property updater) + +You can use `Properties` information to know how to correctly + mutate DOM properties on a live dom node + +```js +var Constants = require('dom-property-config').Constants +var Properties = require('dom-property-config').Properties + +function updateElement(element, virtualElement) { + Object.keys(virtualElement.properties).forEach(function (key) { + var strategy = Properties[key] + + if (strategy & Constants.MUST_USE_ATTRIBUTE) { + element.setAttribute(key, virtualElement.properties[key]) + } else if (strategy & Constants.MUST_USE_PROPERTY) { + element[key] = virtualElement.properties[key] + } + }) +} +``` + +## Docs + +### `var Properties = config.Properties` + +The `Properties` object contains key value pairs that describe + the updating strategy that should be used to update the + named property on a DOM element. + +The `key` is a virtual property name, not to be confused with + a DOM element property name. There is a mapping of virtual + property names to DOM element property names in + `config.DOMPropertyNames` + +The `value` is either `null` which means it's not writable or + some binary OR combination of `MUST_USE_PROPERTY`, + `MUST_USE_ATTRIBUTE`, `HAS_BOOLEAN_VALUE`, `HAS_SIDE_EFFECTS`, + `HAS_NUMERIC_VALUE`, `HAS_POSITIVE_NUMERIC_VALUE`, + `HAS_OVERLOADED_BOOLEAN_VALUE` + +You can use this object of key values to determine what kind + of DOM updating strategy you want to implement. + +### `var Constants = config.Constants` + +`Constants` contains the values of: + + - `MUST_USE_ATTRIBUTE` + - `MUST_USE_PROPERTY` + - `HAS_BOOLEAN_VALUE` + - `HAS_SIDE_EFFECTS` + - `HAS_NUMERIC_VALUE` + - `HAS_POSITIVE_NUMERIC_VALUE` + - `HAS_OVERLOADED_BOOLEAN_VALUE` + +`MUST_USE_ATTRIBUTE` means you should use `elem.setAttribute` to + update this property safely. + +`MUST_USE_PROPERTY` means you should use `elem[key] = value` to + update this property safely. + +`HAS_BOOLEAN_VALUE` means you know this property is a boolean. + this allows you to avoid serializing into `value=false`. + +`HAS_SIDE_EFFECTS` means it is not safe to set this property. + you should special case this property in your algorithm + +`HAS_NUMERIC_VALUE` means you know this property is a number. + this allows you to avoid serializing into `value=NaN` + +`HAS_POSITIVE_NUMERIC_VALUE` means you know this property is + a positive number. this allows you to avoid serializing into + `value=-1` + +`HAS_OVERLOADED_BOOLEAN_VALUE` means you know this property is + both a string and a boolean. this means you should not + serialize this property if it's `false` + +### `var DOMAttributeNames = config.DOMAttributeNames` + +The `DOMAttributeNames` object contains key value that describe + how to turn properties into attributes. + +The `key` is a virtual property name and the `value` is the + relevant DOM element attribute name. + +You can use this object to decided how to serialize your DOM + properties into a string of HTML attributes + +## Installation + +`npm install dom-property-config` + +## Contributors + + - React maintainers + - Raynos + +## Apache Licenced diff --git a/npm-react/dom-property-config/dom-property-config.js b/npm-react/dom-property-config/dom-property-config.js new file mode 100644 index 00000000000..766e78b66cb --- /dev/null +++ b/npm-react/dom-property-config/dom-property-config.js @@ -0,0 +1 @@ +module.exports = require('./lib/DefaultDOMPropertyConfig.js'); diff --git a/npm-react/dom-property-config/package.json b/npm-react/dom-property-config/package.json new file mode 100644 index 00000000000..f70fc1e8918 --- /dev/null +++ b/npm-react/dom-property-config/package.json @@ -0,0 +1,29 @@ +{ + "name": "dom-property-config", + "description": "A set of dom property rendering instructions", + "version": "", + "keywords": [ + "react", "config", "attributes", "properties", "property", "attribute" + ], + "homepage": "https://github.com/facebook/react/tree/master/npm-react/dom-property-config", + "bugs": "https://github.com/facebook/react/issues?labels=react-core", + "licenses": [ + { + "type": "Apache-2.0", + "url": "http://www.apache.org/licenses/LICENSE-2.0" + } + ], + "files": [ + "README.md", + "dom-property-config.js", + "lib/" + ], + "main": "dom-property-config.js", + "repository": { + "type": "git", + "url": "https://github.com/facebook/react" + }, + "engines": { + "node": ">=0.10.0" + } +} From 097a48b5c07926590bdda4b3f54794895756052e Mon Sep 17 00:00:00 2001 From: Raynos Date: Fri, 18 Apr 2014 22:00:27 -0700 Subject: [PATCH 5/6] dom-property-config: Add a grunt target to build module Added a grunt target to build the dom-property-config module. --- Gruntfile.js | 7 +++ grunt/tasks/npm-dom-property-config.js | 77 ++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 grunt/tasks/npm-dom-property-config.js diff --git a/Gruntfile.js b/Gruntfile.js index 648f116c052..be49e4f9032 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -10,6 +10,7 @@ var sauceTunnelTask = require('./grunt/tasks/sauce-tunnel'); var npmTask = require('./grunt/tasks/npm'); var releaseTasks = require('./grunt/tasks/release'); var npmReactTasks = require('./grunt/tasks/npm-react'); +var npmDomPropertyConfigTasks = require('./grunt/tasks/npm-dom-property-config'); var npmReactToolsTasks = require('./grunt/tasks/npm-react-tools'); var versionCheckTask = require('./grunt/tasks/version-check'); @@ -67,6 +68,10 @@ module.exports = function(grunt) { grunt.registerTask('npm-react:release', npmReactTasks.buildRelease); grunt.registerTask('npm-react:pack', npmReactTasks.packRelease); grunt.registerTask('npm-react-tools:pack', npmReactToolsTasks.pack); + grunt.registerTask('npm-dom-property-config:release', + npmDomPropertyConfigTasks.buildRelease) + grunt.registerTask('npm-dom-property-config:pack', + npmDomPropertyConfigTasks.packRelease) grunt.registerTask('version-check', versionCheckTask); @@ -208,6 +213,8 @@ module.exports = function(grunt) { 'browserify:addonsMin', 'npm-react:release', 'npm-react:pack', + 'npm-dom-property-config:release', + 'npm-dom-property-config:pack', 'npm-react-tools:pack', 'copy:react_docs', 'compare_size' diff --git a/grunt/tasks/npm-dom-property-config.js b/grunt/tasks/npm-dom-property-config.js new file mode 100644 index 00000000000..9efe957c036 --- /dev/null +++ b/grunt/tasks/npm-dom-property-config.js @@ -0,0 +1,77 @@ +'use strict'; + +var fs = require('fs'); +var grunt = require('grunt'); + +function npmGruntModule(opts) { + function buildRelease() { + // delete build/npm-dom-property-config for fresh start + grunt.file.exists(opts.dest) && grunt.file.delete(opts.dest); + + // mkdir -p build/npm-dom-property-config/lib + grunt.file.mkdir(opts.lib); + + // Copy npm-react/dom-property-config/**/* to build/npm-dom-property-config + var mappings = [].concat( + grunt.file.expandMapping('**/*', opts.dest, {cwd: opts.src}) + ); + mappings.forEach(function(mapping) { + var src = mapping.src[0]; + var dest = mapping.dest; + if (grunt.file.isDir(src)) { + grunt.file.mkdir(dest); + } else { + grunt.file.copy(src, dest); + } + }); + + opts.files.forEach(function (fileName) { + grunt.file.copy( + opts.modSrc + fileName, + opts.lib + fileName + ) + }) + + // modify build/react-core/package.json to set version ## + var pkg = grunt.file.readJSON(opts.dest + 'package.json'); + pkg.version = grunt.config.data.pkg.version; + grunt.file.write(opts.dest + 'package.json', JSON.stringify(pkg, null, 2)); + } + + function packRelease() { + /*jshint validthis:true */ + var done = this.async(); + var spawnCmd = { + cmd: 'npm', + args: ['pack', opts.folderName], + opts: { + cwd: 'build/' + } + }; + grunt.util.spawn(spawnCmd, function() { + var src = 'build/' + opts.name + '-' + + grunt.config.data.pkg.version + '.tgz'; + var dest = 'build/' + opts.name + '.tgz'; + fs.rename(src, dest, done); + }); + } + + + return { + buildRelease: buildRelease, + packRelease: packRelease + }; +} + +module.exports = npmGruntModule({ + folderName: 'npm-dom-property-config', + name: 'dom-property-config', + src: 'npm-react/dom-property-config/', + dest: 'build/npm-dom-property-config/', + modSrc: 'build/modules/', + lib: 'build/npm-dom-property-config/lib/', + files: [ + 'DefaultDOMPropertyConfig.js', + 'DOMPropertyInjectionConstants.js' + ] +}); From adaea3aa8ea98b7edebb9066c79f1687aaa94bdd Mon Sep 17 00:00:00 2001 From: Raynos Date: Sat, 19 Apr 2014 01:05:05 -0700 Subject: [PATCH 6/6] document how to contribute --- npm-react/dom-property-config/README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/npm-react/dom-property-config/README.md b/npm-react/dom-property-config/README.md index f1fdab58bcd..31f16266690 100644 --- a/npm-react/dom-property-config/README.md +++ b/npm-react/dom-property-config/README.md @@ -123,6 +123,20 @@ You can use this object to decided how to serialize your DOM `npm install dom-property-config` +## Contributing + +To work on this module please check out and clone the + [react](https://github.com/facebook/react) source code. + +The implementation of this module can be found in + + - [DefaultDomPropertyConfig](https://github.com/facebook/react/blob/master/src/browser/ui/dom/DefaultDOMPropertyConfig.js) + - [DOMPropertyInjectionConstants](https://github.com/facebook/react/blob/master/src/browser/ui/dom/DOMPropertyInjectionConstants.js) + +The source code in this directly is auto generated and you + should branch and work on the files in the `react` src + directory directly. + ## Contributors - React maintainers