Skip to content

[POC] Replace concatenated IDs with monotonic IDs #991

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/core/ReactComponentBrowserEnvironment.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ var ReactComponentBrowserEnvironment = {
);

if (shouldReuseMarkup) {
console.log(markup);
if (ReactMarkupChecksum.canReuseMarkup(
markup,
getReactRootElementInContainer(container))) {
Expand Down
52 changes: 49 additions & 3 deletions src/core/ReactMount.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,43 @@ function getReactRootID(container) {
return rootElement && ReactMount.getID(rootElement);
}

var nextMountID = {};
var mountIDtoReactID = {};
var reactIDtoMountID = {};

function toBase62(value) {
var table = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
if (value < 62) {
return table.charAt(value);
} else {
var index = value % 62;
return toBase62((value - index) / 62) + table.charAt(index);
}
}

function resetMountIDs() {
nextMountID = {};
mountIDtoReactID = {};
reactIDtoMountID = {};
}

function createMountID(id) {
var rootID = ReactInstanceHandles.getReactRootIDFromNodeID(id).substr(1);

nextMountID[rootID] = nextMountID[rootID] || 0;

var mountID = rootID + ':' + toBase62(nextMountID[rootID]++);
mountIDtoReactID[mountID] = id;
reactIDtoMountID[id] = mountID;
return mountID;
}

function purgeMountID(id) {
var mountID = reactIDtoMountID[id];
//delete mountIDtoReactID[mountID];
//delete reactIDtoMountID[id];
}

/**
* Accessing node[ATTR_NAME] or calling getAttribute(ATTR_NAME) on a form
* element can return its control whose name or ID equals ATTR_NAME. All
Expand Down Expand Up @@ -94,7 +131,11 @@ function internalGetID(node) {
// If node is something like a window, document, or text node, none of
// which support attributes or a .getAttribute method, gracefully return
// the empty string, as if the attribute were missing.
return node && node.getAttribute && node.getAttribute(ATTR_NAME) || '';
var id = node && node.getAttribute && node.getAttribute(ATTR_NAME);
if (id && !(id in mountIDtoReactID)) {
throw 'err ' + id;
}
return mountIDtoReactID[id] || '';
}

/**
Expand All @@ -106,9 +147,9 @@ function internalGetID(node) {
function setID(node, id) {
var oldID = internalGetID(node);
if (oldID !== id) {
delete nodeCache[oldID];
purgeID(oldID);
}
node.setAttribute(ATTR_NAME, id);
node.setAttribute(ATTR_NAME, createMountID(id));
nodeCache[id] = node;
}

Expand Down Expand Up @@ -159,6 +200,7 @@ function isValid(node, id) {
* @param {string} id The ID to forget.
*/
function purgeID(id) {
purgeMountID(id);
delete nodeCache[id];
}

Expand Down Expand Up @@ -617,6 +659,10 @@ var ReactMount = {
* React ID utilities.
*/

createMountID: createMountID,

resetMountIDs: resetMountIDs,

getReactRootID: getReactRootID,

getID: getID,
Expand Down
2 changes: 1 addition & 1 deletion src/core/__tests__/ReactDOMComponent-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ describe('ReactDOMComponent', function() {

var NodeStub = function(initialProps) {
this.props = initialProps || {};
this._rootNodeID = 'test';
this._rootNodeID = '.0';
};
mixInto(NodeStub, ReactDOMComponent.Mixin);

Expand Down
34 changes: 17 additions & 17 deletions src/core/__tests__/ReactEventEmitter-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,21 +33,17 @@ require('mock-modules')
var keyOf = require('keyOf');
var mocks = require('mocks');

var ReactMount = require('ReactMount');
var idToNode = {};
var getID = ReactMount.getID;
var setID = function(el, id) {
ReactMount.setID(el, id);
idToNode[id] = el;
};
var oldGetNode = ReactMount.getNode;

var ReactMount;
var EventPluginHub;
var ReactEventEmitter;
var ReactTestUtils;
var TapEventPlugin;
var EventListener;

var getID;
var setID;
var tapMoveThreshold;
var idCallOrder = [];
var recordID = function(id) {
Expand Down Expand Up @@ -75,12 +71,9 @@ var ON_CHANGE_KEY = keyOf({onChange: null});
* feed them into `ReactEventEmitter` (through `ReactTestUtils`), the event
* handlers may receive a DOM node to inspect.
*/
var CHILD = document.createElement('div');
var PARENT = document.createElement('div');
var GRANDPARENT = document.createElement('div');
setID(CHILD, '.reactRoot.[0].[0].[0]');
setID(PARENT, '.reactRoot.[0].[0]');
setID(GRANDPARENT, '.reactRoot.[0]');
var CHILD;
var PARENT;
var GRANDPARENT;

function registerSimpleTestHandler() {
ReactEventEmitter.putListener(getID(CHILD), ON_CLICK_KEY, LISTENER);
Expand Down Expand Up @@ -108,10 +101,17 @@ describe('ReactEventEmitter', function() {
EventPluginHub.injection.injectEventPluginsByName({
TapEventPlugin: TapEventPlugin
});
});

afterEach(function() {
ReactMount.getNode = oldGetNode;
getID = ReactMount.getID;
setID = function(el, id) {
ReactMount.setID(el, id);
idToNode[id] = el;
};
CHILD = document.createElement('div');
PARENT = document.createElement('div');
GRANDPARENT = document.createElement('div');
setID(CHILD, '.reactRoot.[0].[0].[0]');
setID(PARENT, '.reactRoot.[0].[0]');
setID(GRANDPARENT, '.reactRoot.[0]');
});

it('should store a listener correctly', function() {
Expand Down
3 changes: 2 additions & 1 deletion src/dom/DOMPropertyOperations.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

"use strict";

var ReactMount = require('ReactMount');
var DOMProperty = require('DOMProperty');

var escapeTextForBrowser = require('escapeTextForBrowser');
Expand Down Expand Up @@ -79,7 +80,7 @@ var DOMPropertyOperations = {
*/
createMarkupForID: function(id) {
return processAttributeNameAndPrefix(DOMProperty.ID_ATTRIBUTE_NAME) +
escapeTextForBrowser(id) + '"';
escapeTextForBrowser(ReactMount.createMountID(id)) + '"';
},

/**
Expand Down