diff --git a/.editorconfig b/.editorconfig deleted file mode 100644 index 6aa275d3af..0000000000 --- a/.editorconfig +++ /dev/null @@ -1,9 +0,0 @@ -# http://editorconfig.org -root = true - -[*] -charset = utf-8 -end_of_line = lf -indent_size = 2 -indent_style = space -trim_trailing_whitespace = true diff --git a/.github/ISSUE_TEMPLATE/issues-have-been-disabled.md b/.github/ISSUE_TEMPLATE/issues-have-been-disabled.md new file mode 100644 index 0000000000..196cf396ef --- /dev/null +++ b/.github/ISSUE_TEMPLATE/issues-have-been-disabled.md @@ -0,0 +1,15 @@ +--- +name: Issues have been disabled +about: Please report new issues at github.com/facebook/react +title: NEW ISSUES ARE NOT MONITORED +labels: '' +assignees: '' + +--- + +This repository has been merged into the main React repo (github.com/facebook/react) + +Please open issues there: +https://github.com/facebook/react/issues/new + +New issues opened in this repository will be ignored. diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 0008167f1b..0000000000 --- a/.gitignore +++ /dev/null @@ -1,18 +0,0 @@ -# osx noise -.DS_Store -profile - -# xcode noise -build/* -*.mode1 -*.mode1v3 -*.mode2v3 -*.perspective -*.perspectivev3 -*.pbxuser -*.xcworkspace -xcuserdata - -# svn & cvs -.svn -CVS diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 7ef4a9f022..0000000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "blink"] - path = blink - url = https://github.com/sebmarkbage/blink-devtools.git diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index 5b2021a008..0000000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,63 +0,0 @@ -# Contributing to React - -React is one of Facebook's first open source projects that is both under very active development and is also being used to ship code to everybody on facebook.com. We're still working out the kinks to make contributing to this project as easy and transparent as possible, but we're not quite there yet. Hopefully this document makes the process for contributing clear and preempts some questions you may have. - -## Our Development Process - -Some of the core team will be working directly on GitHub. These changes will be public from the beginning. Other changesets will come via a bridge with Facebook's internal source control. This is a necessity as it allows engineers at Facebook outside of the core team to move fast and contribute from an environment they are comfortable in. - -### `master` is unsafe - -We will do our best to keep `master` in good shape, with tests passing at all times. But in order to move fast, we will make API changes that your application might not be compatible with. We will do our best to communicate these changes and always version appropriately so you can lock into a specific version if need be. - -### Pull Requests - -The core team will be monitoring for pull requests. When we get one, we'll run some Facebook-specific integration tests on it first. From here, we'll need to get another person to sign off on the changes and then merge the pull request. For API changes we may need to fix internal uses, which could cause some delay. We'll do our best to provide updates and feedback throughout the process. - -*Before* submitting a pull request, please make sure the following is done… - -1. Fork the repo and create your branch from `master`. -2. If you've added code that should be tested, add tests! -3. If you've changed APIs, update the documentation. -4. Ensure the test suite passes (`grunt test`). -5. Make sure your code lints (`grunt lint`) - we've done our best to make sure these rules match our internal linting guidelines. -6. If you haven't already, complete the CLA. - -### Contributor License Agreement ("CLA") - -In order to accept your pull request, we need you to submit a CLA. You only need to do this once, so if you've done this for another Facebook open source project, you're good to go. If you are submitting a pull request for the first time, just let us know that you have completed the CLA and we can cross-check with your GitHub username. - -Complete your CLA here: - -## Bugs - -### Where to Find Known Issues - -We will be using GitHub Issues for our public bugs. We will keep a close eye on this and try to make it clear when we have an internal fix in progress. Before filing a new task, try to make sure your problem doesn't already exist. - -### Reporting New Issues - -The best way to get your bug fixed is to provide a reduced test case. jsFiddle, jsBin, and other sites provide a way to give live examples. Those are especially helpful though may not work for `JSX`-based code. - -### Security Bugs - -Facebook has a [bounty program](https://www.facebook.com/whitehat/) for the safe disclosure of security bugs. With that in mind, please do not file public issues and go through the process outlined on that page. - -## How to Get in Touch - -* IRC - [#reactjs on freenode](http://webchat.freenode.net/?channels=reactjs) -* Mailing list - [reactjs on Google Groups](http://groups.google.com/group/reactjs) - -## Coding Style - -* Use semicolons; -* Commas last, -* 2 spaces for indentation (no tabs) -* Prefer `'` over `"` -* `"use strict";` -* 80 character line length -* "Attractive" - -## License - -By contributing to React, you agree that your contributions will be licensed under the [Apache License Version 2.0 (APLv2)](LICENSE). diff --git a/PATENTS b/PATENTS deleted file mode 100644 index 63d1496411..0000000000 --- a/PATENTS +++ /dev/null @@ -1,23 +0,0 @@ -Additional Grant of Patent Rights - -“Software” means the react-devtools software distributed by Facebook, Inc. - -Facebook hereby grants you a perpetual, worldwide, royalty-free, non-exclusive, -irrevocable (subject to the termination provision below) license under any -rights in any patent claims owned by Facebook, to make, have made, use, sell, -offer to sell, import, and otherwise transfer the Software. For avoidance of -doubt, no license is granted under Facebook’s rights in any patent claims that -are infringed by (i) modifications to the Software made by you or a third party, -or (ii) the Software in combination with any software or other technology -provided by you or a third party. - -The license granted hereunder will terminate, automatically and without notice, -for anyone that makes any claim (including by filing any lawsuit, assertion or -other action) alleging (a) direct, indirect, or contributory infringement or -inducement to infringe any patent: (i) by Facebook or any of its subsidiaries or -affiliates, whether or not such claim is related to the Software, (ii) by any -party if such claim arises in whole or in part from any software, product or -service of Facebook or any of its subsidiaries or affiliates, whether or not -such claim is related to the Software, or (iii) by any party relating to the -Software; or (b) that any right in any patent claim of Facebook is invalid or -unenforceable. diff --git a/README.md b/README.md index 09d0ae31fb..a9168c3ed1 100644 --- a/README.md +++ b/README.md @@ -1,114 +1,14 @@ -# React Developer Tools +#### This project has migrated to [github.com/facebook/react](https://github.com/facebook/react) -React Developer Tools is a Chrome extension that allows you to inspect the React -component hierarchy in the Chrome Developer Tools (formerly WebKit Web -Inspector). +The source code for the v3 of the extension can be found in the [`v3` branch](https://github.com/facebook/react-devtools/tree/v3). -## Installation +To build the v3 browser extension from source: +```sh +git checkout v3 -### Easy +# Install dependencies and build the unpacked extension +yarn install +yarn build:extension -[Install the extension from Chrome Web Store](https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi) - -If you inspect an element or launch the developer tools on a React page, you -should see an extra tab called **React** in the inspector. - -### Hard - -Clone the GitHub repository. - -``` -git clone git@github.com:facebook/react-devtools.git -``` - -Clone the blink submodule. - -``` -git submodule update --init -``` - -Open the URL [chrome://extensions/](chrome://extensions/) in your browser. - -Check the box for **Developer Mode** - -Click the button **Load unpacked extension...** - -Select the folder where you downloaded the repository. - -The extension is now installed. - -### The React Tab Doesn't Show Up? - -The current version of React Developer Tools is not compatible with all build -systems. It tries to load the React runtime by either detecting a global called -`React`, or by calling `require('React')` or `require('react')` in the global -scope. Your page needs to support this to be compatible with the Developer -Tools. - -You can test this on the [React website](http://facebook.github.io/react/) -or by inspecting [Facebook](https://www.facebook.com/). - -### The React Tab Is Blank? - -Due to a [bug in Chrome](https://code.google.com/p/chromium/issues/detail?id=319328), -devtools extensions are unable to use `localStorage` if the "Block third-party -cookies and site data" option is checked in the Chrome content settings. Until -this bug is fixed, please make sure this preference is unchecked. - -## Usage - -You should have a new tab called **React** in your Chrome DevTools. This shows -you the root React components that was rendered on the page, as well as the -subcomponents that they ended up rendering. - -By selecting one of the components in the tree you can inspect and edit its -current props and state in the panel on the right. In the breadcrumbs you can -inspect the selected Component, the Component that created it, the Component -that created that one, and so on. - -### ProTips - -If you inspect a React element on the page using the regular **Elements** tab, -then switch over to the **React** tab, that element will be automatically -selected in the React tree. - -Similarly, if you have a breakpoint within the render phase of a Component, that -will be automatically selected in the **React** tab. This allows you to step -through the rendering tree and see how one Component affects another one. - -By breaking on errors, you can easily find which component threw an error during -rendering, and what props lead to it. - -## Contribute - -### Test Environment - -Open the Chrome DevTools on any React page by inspecting an element. - -In a different tab goto [chrome://inspect/](chrome://inspect/). Open the last -section called **Others**. This contain your DevTools instance. Click the -**inspect** link next to it. That should open up another DevTools instance, -which is inspecting the first one, including the React extension. Inception. - -If you don't have a simple React page available you can use the built-in test -page. Open the URL [chrome://extensions/](chrome://extensions/) again. Look for -the unique **ID** of the extension. E.g: - -``` -chrome-extension://fmkadmapgofadopljbjfkapdkoienihi/tests/page.html -``` - -### Project Structure - -The purpose of this project is to trail the DevTools of the Chromium project. -Therefore the project is structured similarly. For example this project -doesn't use a module system. Each file is inserted using a script tag in the -global scope of the page. Files are isolated by global namespaces. - -Please read the [Structure document](STRUCTURE.md) for more information about -the folder structure of the project. - -### More… - -There's only so much we can cram in here. To read more about the community and -guidelines for submitting pull requests, please read the [Contributing document](CONTRIBUTING.md). +# Follow the on-screen instructions to complete installation +``` \ No newline at end of file diff --git a/STRUCTURE.md b/STRUCTURE.md deleted file mode 100644 index a701b6975e..0000000000 --- a/STRUCTURE.md +++ /dev/null @@ -1,44 +0,0 @@ -# Project Structure - -###/ - -The root folder contains the main files used by the Chrome extension. -`main.html` bootstraps the extension. - -###/blink - -This Git submodule contains a copy of the DevTools from the Blink project. - -This folder should never diverge from the upstream version. That way we can -keep a consistent look and reuse a lot of UI elements from the built-in Chrome -Developer Tools. - -Only a small subset of these files are currently in use. The holes are patched -using files from the views folder. - -###/views - -The views folder contains views that are specific to the React Developer Tools. - -`WebInspectorPatch.js` monkey patches all the WebInspector components that hook -into internals that we don't have access to from a Chrome extension. - -###/agents - -These are stubs APIs to access the pseudo DOM representation of React components -and JavaScript runtime objects. The ReactInspectorAgent is the client that -communicates cross-process to the inspected page. Since this is done -cross-process, these APIs are all asynchronous. - -###/injected - -These files gets evaluated the context of the inspected page. They're -essentially the host that the agents communicate with. - -The format of these files is a single function that gets passed it's -dependencies by ReactInspectorAgent. - -###/tests - -This folder contains a sample React page. It's intended as a relatively stable -page intended to make sure all features works as expected. diff --git a/agents/DOMAgent.js b/agents/DOMAgent.js deleted file mode 100644 index 3c09c925db..0000000000 --- a/agents/DOMAgent.js +++ /dev/null @@ -1,184 +0,0 @@ -/** - * Copyright (c) 2013-2014, Facebook, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * * Neither the name Facebook nor the names of its contributors may be used to - * endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * This simulates the native DOMAgent. It exposes React component as if they - * where XML DOMNodes so that the Web Inspector can render them in a tree form. - */ - -var DOMAgent = { - - getDocument: function(callback) { - ReactInspectorAgent.call('DOM.getDocument', - function(result, error) { - callback(error, result); - } - ); - }, - - requestChildNodes: function(nodeId, depth, callback) { - ReactInspectorAgent.call('DOM.getChildNodes', - nodeId, - depth, - function(result, error) { - if (error) { - callback(error); - return; - } - InspectorBackend.notifyDOM('setChildNodes', [nodeId, result]); - callback(null); - } - ); - }, - - getAttributes: function(nodeId, callback) { - // Not yet needed - }, - - getEventListenersForNode: function(id, objectGroupId, callback) { - ReactInspectorAgent.call('DOM.getEventListenersForNode', id, objectGroupId, - function(result, error) { - callback(error, result); - } - ); - }, - - // From and to JS runtime instances - - requestNode: function(objectId, callback) { - // TODO - }, - - resolveNode: function(nodeId, objectGroup, callback) { - ReactInspectorAgent.call('DOM.resolveNode', nodeId, objectGroup, - function(result, error) { - callback(error, result); - } - ); - }, - - pushNodeByPathToFrontend: function(path, callback) { - ReactInspectorAgent.call('DOM.getNodeForPath', path, - function(result, error) { - if (error) { - callback(error); - return; - } - var changeLog = result.changeLog; - for (var i = 0; i < changeLog.length; i++) { - var change = changeLog[i]; - InspectorBackend.notifyDOM(change.method, change.args); - } - callback(null, result.node ? result.node.nodeId : 0); - } - ); - }, - - // ??? - - setInspectModeEnabled: function() {}, - - // Search - performSearch: function(query, callback) {}, - getSearchResults: function(searchId, index, index2, callback) {}, - querySelector: function(nodeId, selectors, callback) {}, - querySelectorAll: function(nodeId, selectors, callback){}, - - // Undo - markUndoableState: function() {}, - undo: function() {}, - redo: function() {}, - - // Highlight on screen - highlightNode: function(config, nodeId) { - if (nodeId === 'react_root_element') { - return; - } - - if (nodeId) { - ReactInspectorAgent.call('DOM.highlightNode', nodeId, config, function() { }); - } - }, - - hideHighlight: function() { - ReactInspectorAgent.call('DOM.hideHighlight', function() { }); - }, - - // Editing - setNodeName: function(id, name, callback) { callback('Not implemented'); }, - setNodeValue: function(id, value, callback) { - ReactInspectorAgent.call('DOM.setNodeValue', id, value, - function(result, error) { - callback(error); - } - ); - }, - setAttributesAsText: function(id, text, name, callback) { - ReactInspectorAgent.call('DOM.setAttributesAsText', id, text, name, - function(result, error) { - callback(error); - } - ); - }, - setAttributeValue: function(id, name, value, callback) { /* not used */ }, - removeAttribute: function(id, name, callback) { /* not used */ }, - getOuterHTML: function(id, callback) { /* disabled */ }, - setOuterHTML: function(id, html, callback) { /* disabled */ }, - removeNode: function(id, callback) { - callback('Not implemented'); - }, - moveTo: function(id, targetNodeId, anchorNodeId, callback) { - callback('Not implemented'); - }, - - _pollForChanges: function() { - ReactInspectorAgent.call('DOM.getChanges', function(result, error) { - if (error) { - DOMAgent._polling = false; - return; // Stop polling - } - if (result) { - for (var i = 0; i < result.length; i++) { - var change = result[i]; - InspectorBackend.notifyDOM(change.method, change.args); - } - } - setTimeout(DOMAgent._pollForChanges, 300); - }); - }, - - initialize: function() { - if (DOMAgent._polling) return; - if (!InspectorBackend._domDispatcher) return; // Don't start polling yet - DOMAgent._polling = true; - setTimeout(DOMAgent._pollForChanges, 300); - } - -}; diff --git a/agents/InspectorBackend.js b/agents/InspectorBackend.js deleted file mode 100644 index 6810c35f0d..0000000000 --- a/agents/InspectorBackend.js +++ /dev/null @@ -1,50 +0,0 @@ -/** - * Copyright (c) 2013-2014, Facebook, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * * Neither the name Facebook nor the names of its contributors may be used to - * endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * This is where all events coming from the host environment gets registered. - */ - -var InspectorBackend = { - - _domDispatcher: null, - - notifyDOM: function(methodName, args) { - if (!this._domDispatcher) return; - this._domDispatcher[methodName].apply(this._domDispatcher, args); - }, - - registerDOMDispatcher: function(domDispatcher) { - if (this._domDispatcher) { new Error('Expected there to be only one.'); } - this._domDispatcher = domDispatcher; - DOMAgent.initialize(); - } - -}; diff --git a/agents/ReactInspectorAgent.js b/agents/ReactInspectorAgent.js deleted file mode 100644 index c9b5e1b3a0..0000000000 --- a/agents/ReactInspectorAgent.js +++ /dev/null @@ -1,185 +0,0 @@ -/** - * Copyright (c) 2013-2014, Facebook, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * * Neither the name Facebook nor the names of its contributors may be used to - * endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * This is the bridge that talks to the ReactInspectorRuntime. This executes - * in any of the web inspector pages, and injects the runtime into the inspected - * page context. - */ - -var ReactInspectorAgent; - -(function() { - -var RUNTIME_NAMESPACE = '__REACT_INSPECTOR_RUNTIME__' + ReactInspectorVersion; - -var queuedCallbacks = null; - -function runtimeLoaded(result, isException) { - var callbacks = queuedCallbacks; - queuedCallbacks = null; - for (var i = 0; i < callbacks.length; i++) { - callbacks[i](isException); - } - InspectorBackend.notifyDOM('documentUpdated'); - DOMAgent.initialize(); -} - -function loadRuntime() { - var moduleScripts = {}; - var moduleDependencies = {}; - var pending = 0; - - function fetch(fileName, options) { - var xhr = new XMLHttpRequest(); - pending++; - xhr.onload = function() { - if (options.onLoad) { - options.onLoad.call(null, xhr); - } - pending--; - if (pending == 0){ - complete(); - } - } - var runtimeURL = chrome.extension.getURL(fileName); - xhr.open('GET', runtimeURL, true); - xhr.send(); - } - - function fetchScript(name, fileName, dependency) { - moduleDependencies[name] = dependency; - fetch(fileName, { - onLoad: function(xhr) { - moduleScripts[name] = xhr.responseText; - } - }); - } - - function fetchContents(name, fileName) { - fetch(fileName, { - onLoad: function(xhr) { - chrome.devtools.inspectedWindow.eval("this." + name + " = " + - JSON.stringify(xhr.responseText) + ";"); - } - }); - } - - function complete() { - var script = RUNTIME_NAMESPACE + ' = { React: ' + moduleScripts['React'] + '() };\n\n'; - for (var name in moduleDependencies) { - if (name === 'React') continue; - var dependencies = (moduleDependencies[name] || []).map(function(dep) { - return RUNTIME_NAMESPACE + '.' + dep; - }); - dependencies.push('this', '"' + RUNTIME_NAMESPACE + '"'); - script += RUNTIME_NAMESPACE + '.' + name + ' = ' + moduleScripts[name] + - '(' + dependencies + ')\n\n'; - } - // Uncomment this to get debugging support of the devtools internals. - // script += '//@ sourceURL=InjectedRuntime.js'; - chrome.devtools.inspectedWindow.eval(script, runtimeLoaded); - } - - fetchScript('React', '/injected/ReactHost.js'); - fetchScript('_injectedScriptHost', '/injected/InjectedScriptHost.js'); - fetchScript('_injectedScript', '/blink/Source/core/inspector/InjectedScriptSource.js', ['_injectedScriptHost']); - fetchScript('Runtime', '/injected/RuntimeHost.js', ['React', '_injectedScript']); - fetchScript('Overlay', '/injected/Overlay.js', []); - fetchScript('DOM', '/injected/DOMHost.js', ['React', 'Overlay', '_injectedScript']); - fetchContents('__InspectorOverlayPage_html', '/blink/Source/core/inspector/InspectorOverlayPage.html'); -} - -ReactInspectorAgent = { - - initialize: function(callback) { - // Reset any existing runtime on the page - ReactInspectorAgent.call('DOM.reset', function(result, error) { - callback(error); - }); - }, - - whenReady: function(callback) { - if (queuedCallbacks) { - queuedCallbacks.push(callback); - return; - } - ReactInspectorAgent.eval('isReady', function(result, error) { - callback(error); - }); - }, - - call: function(methodName, callback) { - var methodSignature = methodName + '('; - for (var i = 1; i < arguments.length - 1; i++) { - if (i > 1) methodSignature += ','; - methodSignature += JSON.stringify(arguments[i]); - } - methodSignature += ')'; - ReactInspectorAgent.eval(methodSignature, arguments[arguments.length - 1]); - }, - - eval: function(methodSignature, callback) { - function retry(error) { - if (error) { - // If we still fail, let's error out - callback(null, error); - } else { - // If we successfully reloaded the runtime, let's try again - ReactInspectorAgent.eval(methodSignature, callback); - } - } - - if (queuedCallbacks) { - queuedCallbacks.push(retry); - return; - } - - chrome.devtools.inspectedWindow.eval( - RUNTIME_NAMESPACE + '.' + methodSignature, - function(result, error) { - if (error && error.value.indexOf(RUNTIME_NAMESPACE) !== -1) { - // Runtime is missing, let's reload it - if (queuedCallbacks) { - queuedCallbacks.push(retry); - } else { - queuedCallbacks = [retry]; - loadRuntime(); - } - } else { - callback(result, error); - } - } - ); - } - -}; - -})(); \ No newline at end of file diff --git a/agents/ReactInspectorVersion.js b/agents/ReactInspectorVersion.js deleted file mode 100644 index 7820563dee..0000000000 --- a/agents/ReactInspectorVersion.js +++ /dev/null @@ -1,31 +0,0 @@ -/** - * Copyright (c) 2013-2015, Facebook, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * * Neither the name Facebook nor the names of its contributors may be used to - * endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -var ReactInspectorVersion = '0_13_0'; diff --git a/agents/RuntimeAgent.js b/agents/RuntimeAgent.js deleted file mode 100644 index d59108bd6b..0000000000 --- a/agents/RuntimeAgent.js +++ /dev/null @@ -1,77 +0,0 @@ -/** - * Copyright (c) 2013-2014, Facebook, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * * Neither the name Facebook nor the names of its contributors may be used to - * endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * This simulates the native RuntimeAgent that exposes JavaScript objects on - * the inspected page. - */ - -var RuntimeAgent = { - - releaseObject: function(objectId) { - ReactInspectorAgent.call('Runtime.releaseObject', objectId, function(){}); - }, - - releaseObjectGroup: function(objectGroup) { - ReactInspectorAgent.call('Runtime.releaseObjectGroup', objectGroup, function(){}); - }, - - evaluate: function(expression, extension, exposeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole, contextId, returnByValue, generatePreview, callback) { - ReactInspectorAgent.call('Runtime.evaluate', expression, contextId, exposeCommandLineAPI, returnByValue, generatePreview, function(response, error) { - callback(error, response.result, response.wasThrown); - }); - }, - - callFunctionOn: function(objectId, functionDeclaration, args, doNotPauseOnExceptionsAndMuteConsole, returnByValue, generatePreview, callback) { - ReactInspectorAgent.call('Runtime.callFunctionOn', objectId, functionDeclaration, args, returnByValue, function(response, error) { - callback(error, response.result, response.wasThrown); - }); - }, - - getProperties: function(objectId, ownProperties, accessorPropertiesOnly, callback) { - ReactInspectorAgent.call('Runtime.getProperties', objectId, ownProperties, accessorPropertiesOnly, function(result, error) { - callback(error, result, null); - }); - } - -}; - -RuntimeAgent.evaluate.invoke = function(params, callback) { - RuntimeAgent.evaluate( - params.expression, - params.extension, - params.exposeCommandLineAPI, - params.doNotPauseOnExceptionsAndMuteConsole, - params.contextId, - params.returnByValue, - params.generatePreview, - callback - ); -}; diff --git a/blink b/blink deleted file mode 160000 index 120a03721f..0000000000 --- a/blink +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 120a03721f07ecab689e5aa2444ed26094e5ede0 diff --git a/device/Environment.js b/device/Environment.js deleted file mode 100644 index ba04c37918..0000000000 --- a/device/Environment.js +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Copyright (c) 2013-2014, Facebook, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * * Neither the name Facebook nor the names of its contributors may be used to - * endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -// We're in a stand-alone inspector without the ability to inject scripts -// per origin, so we fetch it from either the query string or localStorage. - -if (typeof chrome === 'undefined' || !chrome.devtools) { - eval(localStorage.DEVTOOLS_INJECTED_SCRIPT)(Date.now()); -} diff --git a/device/RegisterExtension.js b/device/RegisterExtension.js deleted file mode 100644 index d5147ce46a..0000000000 --- a/device/RegisterExtension.js +++ /dev/null @@ -1,61 +0,0 @@ -/** - * Copyright (c) 2013-2014, Facebook, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * * Neither the name Facebook nor the names of its contributors may be used to - * endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -window.addEventListener('load', function() { - var xhr = new XMLHttpRequest(); - xhr.onload = function() { - var manifest = JSON.parse(xhr.responseText); - - var remoteDevToolsExtensionId = 'nebafbonknjidlgddlboljbnhmfflfgh'; - - var extensionInfo = { - devtools_page: manifest.devtools_page, - name: manifest.name - }; - - chrome.runtime.sendMessage( - remoteDevToolsExtensionId, - { registerDevToolsExtension: extensionInfo }, - function(response) { - if (response) { - localStorage.DEVTOOLS_INJECTED_SCRIPT = response.injectedScript; - } else { - // This gets executed in /device/Environment.js so just make it a - // a function that logs the error. - var lastError = JSON.stringify(chrome.runtime.lastError); - localStorage.DEVTOOLS_INJECTED_SCRIPT = - 'function(){ console.error("' + lastError + '"); }'; - } - } - ); - }; - xhr.open('GET', '/manifest.json', true); - xhr.send(); -}, false); diff --git a/icons/icon128.png b/icons/icon128.png deleted file mode 100644 index 8acf6c7a21..0000000000 Binary files a/icons/icon128.png and /dev/null differ diff --git a/icons/icon16.png b/icons/icon16.png deleted file mode 100644 index 31c9ae1f98..0000000000 Binary files a/icons/icon16.png and /dev/null differ diff --git a/icons/icon19.png b/icons/icon19.png deleted file mode 100644 index 4d89167ae8..0000000000 Binary files a/icons/icon19.png and /dev/null differ diff --git a/icons/icon38.png b/icons/icon38.png deleted file mode 100644 index 60e72ef669..0000000000 Binary files a/icons/icon38.png and /dev/null differ diff --git a/icons/icon48.png b/icons/icon48.png deleted file mode 100644 index 63e4b2aeff..0000000000 Binary files a/icons/icon48.png and /dev/null differ diff --git a/injected/DOMHost.js b/injected/DOMHost.js deleted file mode 100644 index 2c179a51c8..0000000000 --- a/injected/DOMHost.js +++ /dev/null @@ -1,810 +0,0 @@ -/** - * This module gets executed on the host page and exposes a serialized pseudo - * DOM from the React component tree. - */ -/** - * Copyright (c) 2013-2015, Facebook, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * * Neither the name Facebook nor the names of its contributors may be used to - * endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -(function(ReactHost, OverlayPage, InjectedScript) { - -var DOCUMENT_NODE = 9; -var ELEMENT_NODE = 1; -var TEXT_NODE = 3; - -var instanceIDCounter = 0; -// This is assumed to be a native WeakMap or equivalent that works on frozen -// objects as keys. -var instanceIDMap = new WeakMap(); - -var instanceCache = {}; -var descriptorCache = {}; -var rootCache = {}; - -var updatedInstances = {}; -var newRoots = {}; -var deletedRoots = {}; -var inspectedNodeOrInstance = null; -var lastBreakpointInstance = null; - -// base URL - -function getBaseURL() { - if (typeof window === 'undefined' || !window.location) { - return 'react://'; - } - return window.location.toString(); -} - -// Pseudo DOM Description - -var foundInstance = null; // Used to extract a deep search for an instance - -function bindNode(instance) { - if (!instanceIDMap.has(instance)) { - var id = (instanceIDCounter++) + ''; - instanceIDMap.set(instance, id); - instanceCache[id] = instance; - } - return instanceIDMap.get(instance); -} - -function isBound(instance) { - return instanceIDMap.has(instance); -} - -function getID(instance) { - if (!instanceIDMap.has(instance)) { - throw new Error('This instance should already be bound.') - } - return instanceIDMap.get(instance); -} - -function unbindNode(instance) { - var id = instanceIDMap.get(instance); - if (id) { - delete instanceCache[id]; - delete instanceCache[id + '_text']; // incase this had text content - delete descriptorCache[id]; - delete updatedInstances[id]; - if (id in newRoots) { - delete newRoots[id]; - } else if (id in rootCache) { - deletedRoots[id] = 1; - delete rootCache[id]; - } - instanceIDMap.delete(instance); - } -} - -function getAttributes(instance) { - var attrs = []; - var props = instance.props || - (instance._currentElement && instance._currentElement.props); - if (!props) return attrs; - for (var prop in props) { - if (!props.hasOwnProperty(prop) || - prop === 'key' || - prop === 'children' || - prop === '__owner__' || - prop === '{owner}' || - prop.substr(0,2) == '__') { - continue; - } - var value = props[prop]; - if (typeof value === 'function' || typeof value === 'undefined') { - // Skip event listeners and undefined - continue; - } - if (value === null) { - value = 'null'; - } - attrs.push(prop, typeof value === 'object' ? '\u2026' : String(value)); - } - return attrs; -} - -function getTextNode(text, id) { - var descriptor = { - nodeId: id, - nodeType: TEXT_NODE, - nodeValue: String(text), - childNodeCount: 0 - }; - descriptorCache[id] = descriptor; - return descriptor; -} - -function isWrappedNativeComponent(instance) { - return instance._renderedComponent.hasOwnProperty('_renderedChildren') && - instance._currentElement && - typeof instance._currentElement.type === 'string'; -} - -function getChildren(instance, depth, diveTo) { - var children = null; - if (ReactHost.hasTextContent(instance)) { - var textId = bindNode(instance) + '_text'; - instanceCache[textId] = instance; - var content = ReactHost.getTextContent(instance); - children = [getTextNode(content, textId)]; - } else if (instance._renderedComponent) { - if (isWrappedNativeComponent(instance)) { - // This is a workaround that by passes the internal DOM component and gets - // to it's children directly. The internal node isn't relevant and should - // never be exposed. Even for debugging. - children = getChildren(instance._renderedComponent, depth, diveTo); - } else { - children = [getDOMNode(instance._renderedComponent, depth, diveTo)]; - } - } else if (instance._renderedChildren) { - children = getDOMNodes(instance._renderedChildren, depth, diveTo); - } else { - children = []; - } - return children; -} - -function getChildCount(instance) { - if (ReactHost.hasTextContent(instance)) { - return 1; - } else if (instance._renderedComponent) { - if (isWrappedNativeComponent(instance)) { - // This is a workaround that by passes the internal DOM component and gets - // to it's children directly. The internal node isn't relevant and should - // never be exposed. Even for debugging. - return getChildCount(instance._renderedComponent); - } else { - return 1; - } - } else if (instance._renderedChildren) { - var count = 0; - for (var key in instance._renderedChildren) { - if (instance._renderedChildren[key]) { - count++; - } - } - return count; - } else { - return 0; - } -} - -function getDOMNode(instance, depth, diveTo) { - if (diveTo) { - if (ReactHost.isInstance(instance, diveTo)) { - foundInstance = instance; - depth = 0; - } else if (!ReactHost.isAncestorOf(instance, diveTo)) { - depth = 0; - } - } - - // TODO: Better duck checking, of what is a text component - if (ReactHost.isTextComponent(instance)) { - if (typeof instance._stringText === 'string') { - // React 0.13 - return getTextNode(instance._stringText, bindNode(instance)); - } else if (typeof instance.props === "string") { - // React 0.11 - 0.12 - return getTextNode(instance.props, bindNode(instance)); - } else { - // React 0.10 - return getTextNode(instance.props.text, bindNode(instance)); - } - } - - var id = bindNode(instance); - var publicInstance = instance.getPublicInstance ? instance.getPublicInstance() - : instance; - var tagName = publicInstance.tagName && publicInstance.tagName.toLowerCase(); - // For several reasons, there's only one React class in Om. So we - // check for getDisplayName on the instance itself (if available). - var instanceName = publicInstance.getDisplayName && - publicInstance.getDisplayName(); - var name = instanceName || tagName || publicInstance.constructor.displayName - || publicInstance.constructor.name - || 'Unknown'; - var children = null; - - if (depth != 0 || ReactHost.hasTextContent(instance)) { - // For simple string children, we include them immediately - children = getChildren(instance, depth - 1, diveTo); - } - - // TODO: Owner is going away. Not sure what to do about this. - // Perhaps add a DEV-only version. - var owner = instance._owner || - (instance._currentElement && instance._currentElement._owner) || - (instance.props && instance.props.__owner__); - var ownerId = null; - if (owner) { - ownerId = bindNode(owner); - } - - var descriptor = { - nodeId: id, - ownerId: ownerId, - nodeType: ELEMENT_NODE, - nodeName: name, - localName: name, - attributes: getAttributes(instance), - stateful: !!instance.state, - childNodeCount: children == null ? getChildCount(instance) : children.length, - children: children - }; - if (!(id in descriptorCache)) { - descriptorCache[id] = descriptor; - } - return descriptor; -} - -function getDOMNodes(instances, depth, diveTo) { - var childInstances = []; - for (var key in instances) { - var instance = instances[key]; - if (!instance) { - continue; - } - childInstances.push(instance); - } - childInstances.sort(function(a, b) { return a._mountIndex - b._mountIndex; }); - var childNodes = childInstances.map(function(instance) { - return getDOMNode(instance, depth, diveTo); - }); - return childNodes; -} - -var DOMHost = {}; - -DOMHost.getDocument = function() { - var rootNodes = getDOMNodes(ReactHost.instancesByRootID, 0); - for (var i = 0; i < rootNodes.length; i++) { - var childDescriptor = rootNodes[i]; - rootCache[childDescriptor.nodeId] = childDescriptor; - } - - var root = { - nodeId: 'react_root_element', - nodeType: ELEMENT_NODE, - nodeName: 'Top Level', - localName: 'Top Level', - attributes: [], - childNodeCount: rootNodes.length, - children: rootNodes - }; - - return { - baseURL: getBaseURL(), - nodeId: 'react_root_document', - nodeType: DOCUMENT_NODE, - nodeName: 'document', - localName: 'document', - attributes: [], - childNodeCount: 1, - children: [root] - }; -}; - -DOMHost.getChildNodes = function(parentId, depth) { - var instance = instanceCache[parentId]; - var children = getChildren(instance, depth || 0); - // Update the cache, TODO: recursively - descriptorCache[parentId].children = children; - return children; -}; - -DOMHost.getNodeForPath = function(path) { - // https://github.com/mirrors/blink/blob/b9bce8c/Source/core/inspector/InspectorDOMAgent.cpp#L1942-L1971 - var changeLog = []; - var ancestorWithMissingChildren = null; - var node = DOMHost.getDocument(); - var pathTokens = path.split(','); - if (!pathTokens) { - return {changeLog: changeLog, node: null}; - } - for (var i = 0; i < pathTokens.length; i += 2) { - var childNumber = +pathTokens[i]; - var childName = pathTokens[i + 1]; - if (isNaN(childNumber) || childNumber >= node.children.length) { - return {changeLog: changeLog, node: null}; - } - child = node.children[childNumber]; - if (!child || child.nodeName != childName) { - return {changeLog: changeLog, node: null}; - } - node = child; - if (!node.children) { - node.children = getChildren(instanceCache[node.nodeId], 0); - if (!ancestorWithMissingChildren) { - ancestorWithMissingChildren = node; - changeLog.push({ - method: 'setChildNodes', - args: [node.nodeId, node.children] - }); - } - } - } - return {changeLog: changeLog, node: node}; -}; - -DOMHost.resolveNode = function(id, objectGroup) { - var instance = instanceCache[id]; - if (!instance) return null; - var publicInstance = instance.getPublicInstance ? instance.getPublicInstance() - : instance; - var descriptor = InjectedScript.wrapObject( - publicInstance, objectGroup, true, true - ); - return descriptor; -}; - -var getSelectedInstance; -if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' && - typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.getSelectedInstance === 'function') { - getSelectedInstance = __REACT_DEVTOOLS_GLOBAL_HOOK__.getSelectedInstance; -} else { - getSelectedInstance = function() { - return $0; - }; -} - -DOMHost.inspectSelectedNode = function() { - inspectedNodeOrInstance = getSelectedInstance(); -}; - -DOMHost.highlightNode = function(id, config) { - var descriptor = descriptorCache[id]; - var instance = instanceCache[id]; - var publicInstance = instance.getPublicInstance ? - instance.getPublicInstance() : - instance; - OverlayPage.highlightComponentInstance( - publicInstance, - (descriptor && descriptor.nodeName) || '', - config - ); -}; - -DOMHost.hideHighlight = function() { - OverlayPage.hideHighlight(); -}; - -DOMHost.getEventListenersForNode = function(id, objectGroup) { - var instance = instanceCache[id]; - if (!instance) return []; - var listeners = ReactHost.getEventListeners(instance); - return listeners.map(function(listener) { - var descriptor = InjectedScript.wrapObject( - listener.handler, objectGroup, true, true - ); - var sourceName = null; - if (listener.owner) { - var publicInstance = listener.owner.getPublicInstance ? - listener.owner.getPublicInstance() : - listener.owner; - sourceName = publicInstance.constructor.displayName || - publicInstance.constructor.name || 'Unknown'; - if (listener.methodName) { - sourceName += '::' + listener.methodName; - } - } - return { - nodeId: id, - type: listener.name, - handlerBody: '' + listener.handler, - handler: descriptor, - sourceName: sourceName - /* - TODO: Get sourceName to be the file name and lineNumber to be the line - where this function is defined. - location: { - lineNumber: 10 - }, - useCapture: true, - isAttribute: true, - */ - }; - }); -}; - -function parseValue(stringValue, currentType) { - switch (currentType) { - case 'boolean': - if (stringValue === 'true'){ - return true; - } else if (stringValue === 'false') { - return false; - } - throw new Error('Unsupported value'); - case 'number': - return Number(stringValue); - case 'string': - return String(stringValue); - default: - throw new Error('Unsupported type'); - } -} - -DOMHost.setNodeValue = function(id, value) { - var instance = instanceCache[id]; - var currentValue; - if (ReactHost.isTextComponent(instance)) { - if (typeof instance._stringText === "string") { - // React 0.13 - instance.receiveComponent( - parseValue(value, typeof instance._currentElement) - ); - Subscriber.componentWillUpdate(instance); - return; - } else if (typeof instance.props === "string") { - // React 0.11 - 0.12 - instance.props = parseValue(value, typeof instance.props); - } else if (ReactHost.isTextComponent(instance)) { - // React 0.10+ - instance.props.text = parseValue(value, typeof instance.props.text); - } - } else { - instance.props.children = parseValue(value, typeof instance.props.children); - } - if (instance.forceUpdate) { - instance.forceUpdate(); - } else if (instance.getPublicInstance && - instance.getPublicInstance().forceUpdate) { - instance.getPublicInstance().forceUpdate(); - } -}; - -DOMHost.setAttributesAsText = function(id, text, name) { - var instance = instanceCache[id]; - var props = instance.props || - (instance._currentElement && instance._currentElement.props); - if (!props) { - return; - } - var currentValue = props[name]; - if (text == '') { - delete props[name]; - } else { - var match = (/\s*([^=\s]+)\s*=\s*\"(.*)\"\s*/).exec(text); - if (!match) throw new Error('Unsupported string'); - var newName = match[1]; - var newValue = parseValue(match[2], typeof currentValue); - if (name !== newName) { - delete props[name]; - } - props[newName] = newValue; - } - if (instance.forceUpdate) { - instance.forceUpdate(); - } else if (instance.getPublicInstance && - instance.getPublicInstance().forceUpdate) { - instance.getPublicInstance().forceUpdate(); - } -}; - -// Change tracking - -function appendAttributeChanges(id, descriptor, instance, changeLog) { - var oldAttributes = {}; - if (descriptor.attributes) { - for (var i = 0; i < descriptor.attributes.length; i+=2) { - oldAttributes[descriptor.attributes[i]] = descriptor.attributes[i + 1]; - } - } - var newAttributes = getAttributes(instance); - for (var i = 0; i < newAttributes.length; i+=2) { - var name = newAttributes[i]; - var value = newAttributes[i + 1]; - if (oldAttributes[name] !== value) { - changeLog.push({ - method: 'attributeModified', - args: [id, name, value] - }); - } - delete oldAttributes[name]; - } - for (var removedName in oldAttributes) { - changeLog.push({ - method: 'attributeRemoved', - args: [id, removedName] - }); - } - // Update cache - descriptor.attributes = newAttributes; -} - -function appendChildChanges(id, descriptor, instance, changeLog) { - if (descriptor.nodeType === TEXT_NODE) { - var newDescriptor = getDOMNode(instance); - changeLog.push({ - method: 'characterDataModified', - args: [id, newDescriptor.nodeValue] - }); - return; - } - - if (!descriptor.children) { - // We never sent the children, so we don't need to update them, the count - // is enough. - var newCount = getChildCount(instance); - if (descriptor.childNodeCount !== newCount) { - changeLog.push({ - method: 'childNodeCountUpdated', - args: [id, newCount] - }); - // Update cache - descriptor.childNodeCount = newCount; - } - return; - } - - var oldChildren = {}; - for (var i = 0; i < descriptor.children.length; i++) { - var prevChild = descriptor.children[i]; - oldChildren[prevChild.nodeId] = prevChild; - prevChild._index = i; - } - - var newChildren = getChildren(instance, 0); - - // `nextIndex` will increment for each child in `nextChildren`, but - // `lastIndex` will be the last index visited in `prevChildren`. - var lastIndex = 0; - var nextIndex = 0; - var previousId = null; - for (var i = 0; i < newChildren.length; i++) { - var nextChild = newChildren[i]; - var prevChild = oldChildren[nextChild.nodeId]; - if (prevChild) { - delete oldChildren[nextChild.nodeId]; - - if (prevChild._index < lastIndex) { - // Moved - changeLog.push({ - method: 'childNodeRemoved', - args: [id, nextChild.nodeId] - }, { - method: 'childNodeInserted', - args: [id, previousId, nextChild] - }); - } - lastIndex = Math.max(prevChild._index, lastIndex); - - // We update text nodes from the parent instead of having the component - // update itself. Why? I forget. - if (nextChild.nodeType === TEXT_NODE && - nextChild.nodeValue !== prevChild.nodeValue) { - changeLog.push({ - method: 'characterDataModified', - args: [nextChild.nodeId, nextChild.nodeValue] - }); - } - } else { - // Inserted - changeLog.push({ - method: 'childNodeInserted', - args: [id, previousId, nextChild] - }); - } - previousId = nextChild.nodeId; - nextIndex++; - } - - for (var removedId in oldChildren) { - // The rest is deleted - changeLog.push({ - method: 'childNodeRemoved', - args: [id, removedId] - }); - } - - descriptor.children = newChildren; -} - -function findAncestorWithMissingChildren(instance, decendant) { - if (ReactHost.isInstance(instance, decendant)) { - foundInstance = instance; - return null; - } - - var descriptor = descriptorCache[getID(instance)]; - if (!descriptor.children) { - return instance; - } - if (ReactHost.hasTextContent(instance)) { - return null; - } else if (instance._renderedComponent) { - return findAncestorWithMissingChildren(instance._renderedComponent, decendant); - } else if (instance._renderedChildren) { - return findAncestorWithMissingChildrenInSet(instance._renderedChildren, decendant); - } - return null; -} - -function findAncestorWithMissingChildrenInSet(children, decendant) { - for (var key in children) { - var child = children[key]; - if (!child) continue; - if (ReactHost.isAncestorOf(child, decendant)) { - return findAncestorWithMissingChildren(child, decendant); - } - } - return null; -} - -function appendInspectionEvents(domNodeOrInstance, changeLog) { - // TODO: Convert a public instance to an internal one - foundInstance = null; - var ancestor = findAncestorWithMissingChildrenInSet( - ReactHost.instancesByRootID, - domNodeOrInstance - ); - if (!ancestor) { - var instance = foundInstance; - foundInstance = null; - if (!instance) { - return; - } - changeLog.push({ - method: 'inspectNodeRequested', - args: [bindNode(instance)] - }); - return; - } - var children = getChildren(ancestor, -1, domNodeOrInstance); - var instance = foundInstance; - foundInstance = null; - descriptorCache[getID(ancestor)].children = children; - changeLog.push({ - method: 'setChildNodes', - args: [getID(ancestor), children] - }, { - method: 'inspectNodeRequested', - args: [bindNode(instance)] - }); -} - -DOMHost.reset = function() { - // Reset the state - for (var id in instanceCache) { - if (instanceCache.hasOwnProperty(id)) { - unbindNode(instanceCache[id]); - } - } - - updatedInstances = {}; - newRoots = {}; - deletedRoots = {}; - inspectedNodeOrInstance = null; - lastBreakpointInstance = null; -}; - -DOMHost.getChanges = function() { - var changeLog = []; - var descriptor; - - // New roots - - var previousRootId = null; - for (previousRootId in rootCache); - - for (var id in newRoots) { - descriptor = getDOMNode(newRoots[id], 0); - rootCache[descriptor.nodeId] = descriptor; - changeLog.push({ - method: 'childNodeInserted', - args: [ - 'react_root_element', - previousRootId, - descriptor - ] - }); - previousRootId = descriptor.nodeId; - } - - // Updates - - for (var id in updatedInstances) { - var instance = updatedInstances[id]; - var descriptor = descriptorCache[id]; - appendAttributeChanges(id, descriptor, instance, changeLog); - appendChildChanges(id, descriptor, instance, changeLog); - } - - // Removed roots - - for (var id in deletedRoots) { - delete rootCache[id]; - changeLog.push({ - method: 'childNodeRemoved', - args: [ - 'react_root_element', - id - ] - }); - } - - updatedInstances = {}; - newRoots = {}; - deletedRoots = {}; - - // Rendering breakpoint - - var breakpointInstance = ReactHost.getCurrentlyRenderingComponent(); - if (breakpointInstance) { - // This instance is currently rendering. It may be updated later. Mark it - // as updated for the next poll. - Subscriber.componentWillUpdate(breakpointInstance); - - // If this is a new breakpoint, let's inspect that instance - if (lastBreakpointInstance !== breakpointInstance) { - appendInspectionEvents(breakpointInstance, changeLog); - inspectedNodeOrInstance = null; - } - } - lastBreakpointInstance = breakpointInstance; - - // Inspected node - - if (inspectedNodeOrInstance) { - appendInspectionEvents(inspectedNodeOrInstance, changeLog); - inspectedNodeOrInstance = null; - } - - return changeLog; -}; - -var Subscriber = { - - componentWillMount: function(instance) { - if (ReactHost.instancesByRootID[instance._rootNodeID] === instance) { - // This is a new root - newRoots[bindNode(instance)] = instance; - } - Subscriber.componentWillUpdate(instance); - }, - - componentWillUpdate: function(instance) { - if (isBound(instance) && !(getID(instance) in newRoots)) { - updatedInstances[getID(instance)] = instance; - } - }, - - componentWillUnmount: function(instance) { - unbindNode(instance); - } - -}; - -ReactHost.subscribeToChanges(Subscriber); - -return DOMHost; - -}) diff --git a/injected/GlobalHook.js b/injected/GlobalHook.js deleted file mode 100644 index d8d56d21a9..0000000000 --- a/injected/GlobalHook.js +++ /dev/null @@ -1,18 +0,0 @@ -// Inject a `__REACT_DEVTOOLS_GLOBAL_HOOK__` global so that React can detect that the -// devtools are installed (and skip its suggestion to install the devtools). -var js = ( - "Object.defineProperty(" + - "window, '__REACT_DEVTOOLS_GLOBAL_HOOK__', {value: {" + - "inject: function(runtime) { this._reactRuntime = runtime; }," + - "getSelectedInstance: null," + - "Overlay: null" + - "}}" + - ")" -); - -// This script runs before the element is created, so we add the script -// to instead. -var script = document.createElement('script'); -script.textContent = js; -document.documentElement.appendChild(script); -script.parentNode.removeChild(script); diff --git a/injected/InjectedScriptHost.js b/injected/InjectedScriptHost.js deleted file mode 100644 index 66d8c84085..0000000000 --- a/injected/InjectedScriptHost.js +++ /dev/null @@ -1,106 +0,0 @@ -/** - * Copyright (c) 2013-2014, Facebook, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * * Neither the name Facebook nor the names of its contributors may be used to - * endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * This stubs out a host environment used by the InjectedScriptSource module, - * in the inspector package. - */ - -(function(ReactHost, inspectedWindow, injectedScriptId) { - -var InjectedScriptHost = { - - storageId: function(object) { console.warn('Host:storageId'); }, - getInternalProperties: function(object) { console.warn('Host:setInternalProperties'); }, - - functionDetails: function(func) { console.warn('Host:functionDetails'); }, - - isHTMLAllCollection: function(object) { return false; }, - - internalConstructorName: function(object) { - if (typeof object.constructor === 'function') { - if (object.constructor.displayName) { - return object.constructor.displayName; - } - if (object.constructor.name) { - return object.constructor.name; - } - } - if (typeof object.tagName === 'string') { - return object.tagName.toLowerCase(); - } - var name = Object.prototype.toString.call(object); - return name.substring(8, name.length - 1); - }, - - copyText: function(object) { console.warn('Host:copyText') }, - clearConsoleMessages: function() { console.warn('Host:clearConsoleMessages'); }, - - inspectedObject: function(index) { console.warn('Host:inspectedObject'); }, - - databaseId: function(object) { console.warn('Host:databaseId'); }, - - inspect: function(object, hints) { console.warn('Host:inspect'); }, - - type: function(object) { - // TODO: For DOM nodes and components return 'node' - switch (Object.prototype.toString.call(object)) { - case '[object Array]': - return 'array'; - case '[object Date]': - return 'date'; - case '[object RegExp]': - return 'regexp'; - default: - return null; - } - }, - - getEventListeners: function(object) { console.warn('Host:getEventListeners'); }, - - evaluate: function(expression) { - return eval(expression); - }, - - debugFunction: function(fn) { console.warn('Host:debugFunction'); }, - undebugFunction: function(fn) { console.warn('Host:undebugFunction'); }, - - monitorFunction: function(fn) { console.warn('Host:monitorFunction'); }, - unmonitorFunction: function(fn) { console.warn('Host:unmonitorFunction'); }, - - setFunctionVariableValue: function(fun, scopeNumber, variableName, newValue) { - console.warn('Host:setFunctionVariableValue'); - } - -}; - -return InjectedScriptHost; - -}) diff --git a/injected/Overlay.js b/injected/Overlay.js deleted file mode 100644 index 051ac744ad..0000000000 --- a/injected/Overlay.js +++ /dev/null @@ -1,231 +0,0 @@ -/** - * This module gets executed on the host page and exposes a serialized pseudo - * DOM from the React component tree. - */ -/** - * Copyright (c) 2013-2014, Facebook, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * * Neither the name Facebook nor the names of its contributors may be used to - * endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -(function() { - -var inspectorIframe; -var inspectorOverlayPage; -var inspectorIframeVisible = false; - -function addInspectorOverlayPage() { - var el = document.createElement('iframe'); - el.style.position = 'fixed'; - el.style.left = '0'; - el.style.top = '0'; - el.style.height = '100%'; - el.style.width = '100%'; - el.style.border = '0'; - el.style.zIndex = 2147483647; - el.style.pointerEvents = 'none'; - - document.body.appendChild(el); - - el.contentDocument.open(); - el.contentDocument.write( - window.__InspectorOverlayPage_html - ); - el.contentWindow.onload = function() { - var platform = "mac"; - var appVersion = navigator.appVersion; - if (appVersion.indexOf('Win') > -1) { - platform = "windows"; - } else if (appVersion.indexOf('Linux') > -1) { - platform = "linux" - } - el.contentWindow.setPlatform(platform); // TODO: add support for other browsers - }; - el.contentDocument.close(); - - inspectorOverlayPage = el.contentWindow; - inspectorIframe = el; -} - -function createQuad(x, y, width, height) { - return [ - {x: x, y: y}, - {x: x + width, y: y}, - {x: x + width, y: y + height}, - {x: x, y: y + height} - ]; -} - -function getElementDimensions(element) { - var calculatedStyle = window.getComputedStyle(element); - - return { - borderLeft: +calculatedStyle.borderLeftWidth.match(/[0-9]*/)[0], - borderRight: +calculatedStyle.borderRightWidth.match(/[0-9]*/)[0], - borderTop: +calculatedStyle.borderTopWidth.match(/[0-9]*/)[0], - borderBottom: +calculatedStyle.borderBottomWidth.match(/[0-9]*/)[0], - marginLeft: +calculatedStyle.marginLeft.match(/[0-9]*/)[0], - marginRight: +calculatedStyle.marginRight.match(/[0-9]*/)[0], - marginTop: +calculatedStyle.marginTop.match(/[0-9]*/)[0], - marginBottom: +calculatedStyle.marginBottom.match(/[0-9]*/)[0], - paddingLeft: +calculatedStyle.paddingLeft.match(/[0-9]*/)[0], - paddingRight: +calculatedStyle.paddingRight.match(/[0-9]*/)[0], - paddingTop: +calculatedStyle.paddingTop.match(/[0-9]*/)[0], - paddingBottom: +calculatedStyle.paddingBottom.match(/[0-9]*/)[0] - }; -} - -function getQuads(element, bounds) { - var scrollX = window.scrollX; - var scrollY = window.scrollY; - var dimensions = getElementDimensions(element); - - var contentQuad = createQuad( - scrollX + bounds.left + dimensions.borderLeft + dimensions.paddingLeft, - scrollY + bounds.top + dimensions.borderTop + dimensions.paddingTop, - bounds.width - dimensions.borderLeft - dimensions.paddingLeft - - dimensions.borderRight - dimensions.paddingRight, - bounds.height - dimensions.borderTop - dimensions.paddingTop - - dimensions.borderBottom - dimensions.paddingBottom - ); - - var paddingQuad = createQuad( - scrollX + bounds.left + dimensions.borderLeft, - scrollY + bounds.top + dimensions.borderTop, - bounds.width - dimensions.borderLeft - dimensions.borderRight, - bounds.height - dimensions.borderTop - dimensions.borderBottom - ); - - var borderQuad = createQuad( - scrollX + bounds.left, - scrollY + bounds.top, - bounds.width, - bounds.height - ); - - var marginQuad = createQuad( - scrollX + bounds.left - dimensions.marginLeft, - scrollY + bounds.top - dimensions.marginTop, - bounds.width + dimensions.marginLeft + dimensions.marginRight, - bounds.height + dimensions.marginTop + dimensions.marginBottom - ); - - return [ - marginQuad, - borderQuad, - paddingQuad, - contentQuad - ]; -} - -function getElementInfo(name, element, bounds) { - return { - tagName: name || '', - idValue: element.id, - className: element.className.trim().length ? - (' ' + element.className.trim()).replace(/\s{1,}/g, '.') : '', - nodeWidth: Math.round(bounds.width), - nodeHeight: Math.round(bounds.height) - }; -} - -function getHighlightColor(color) { - return 'rgba(' + color.r + ', ' + color.g + ', ' + color.b + ', ' + - (color.a || 1) + ')'; -} - -var Overlay = { - - highlightComponentInstance: function(instance, name, config) { - if (!inspectorOverlayPage) { - addInspectorOverlayPage(); - } - - if (!inspectorIframeVisible) { - inspectorIframe.style.display = ''; - inspectorIframeVisible = true; - } - - var element; - try { - // ART will throw on this lookup. TODO: Calculate ART rectangle. - element = instance.getDOMNode(); - } catch (x) { - element = null; - } - if (element == null) { - DOMHost.hideHighlight(); - return; - } - - var bounds = element.getBoundingClientRect(); - var quads = getQuads(element, bounds); - - inspectorOverlayPage.reset({ - viewportSize: { - width: window.innerWidth, - height: window.innerHeight - }, - deviceScaleFactor: 1, - pageScaleFactor: 1, - pageZoomFactor: 1, - scrollX: window.scrollX, - scrollY: window.scrollY - }); - - var elementInfo = null; - if (config.showInfo) { - elementInfo = getElementInfo(name, element, bounds); - } - - // highlight the element - inspectorOverlayPage.drawNodeHighlight({ - elementInfo: elementInfo, - marginColor: getHighlightColor(config.marginColor), - contentColor: getHighlightColor(config.contentColor), - borderColor: getHighlightColor(config.borderColor), - paddingColor: getHighlightColor(config.paddingColor), - quads: quads, - showRulers: config.showRulers - }); - }, - - hideHighlight: function() { - inspectorIframe.style.display = 'none'; - inspectorIframeVisible = false; - } - -}; - -if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' && - __REACT_DEVTOOLS_GLOBAL_HOOK__.Overlay) { - return __REACT_DEVTOOLS_GLOBAL_HOOK__.Overlay; -} - -return Overlay; - -}) diff --git a/injected/ReactHost.js b/injected/ReactHost.js deleted file mode 100644 index 83d47dc481..0000000000 --- a/injected/ReactHost.js +++ /dev/null @@ -1,252 +0,0 @@ -/** - * Copyright (c) 2013-2015, Facebook, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * * Neither the name Facebook nor the names of its contributors may be used to - * endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * This is the runtime that gets executed in the context of the inspected page. - * It is the glue that hooks into the React runtime and translates it into - * something that the inspector can use. - */ - -(function() { - -// Detect React environment - -var ReactInternals; -if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' && - __REACT_DEVTOOLS_GLOBAL_HOOK__._reactRuntime) { - ReactInternals = __REACT_DEVTOOLS_GLOBAL_HOOK__._reactRuntime; -} else if (typeof React !== 'undefined' && React.__internals) { - ReactInternals = React.__internals; -} else if (typeof require === 'function') { - try { ReactInternals = require('React').__internals; } catch (x) { - try { ReactInternals = require('react').__internals; } catch (x) { } - } -} -if (!ReactInternals) { - throw new Error('Unsupported environment. You need version 0.5+ of React.'); -} - -// Track which component the current breakpoint is in -var ReactCurrentOwner = ReactInternals.CurrentOwner; -// Get top level instances and extract IDs from real DOM nodes -var ReactMount = ReactInternals.Mount; -// Use instanceof check to see if this is plain text (can't duck check) -var ReactTextComponent = ReactInternals.TextComponent; -// Used to see if one instance is the ancestor of an instance or dom node -var ReactInstanceHandles = ReactInternals.InstanceHandles; - -if (ReactInternals.Component) { - // 0.11 - 0.12 - // Monkey patched to track updates - var ReactComponent = ReactInternals.Component; - - // Monkey patch Components to track rerenders - - var ComponentMixin = ReactComponent.Mixin; - var originalMountComponent = ComponentMixin.mountComponent; - var originalUpdateComponent = ComponentMixin.updateComponent; - var originalUnmountComponent = ComponentMixin.unmountComponent; - - ComponentMixin.mountComponent = function() { - originalMountComponent.apply(this, arguments); - ReactHost._changeSubscriber.componentWillMount(this); - }; - - ComponentMixin.updateComponent = function() { - originalUpdateComponent.apply(this, arguments); - ReactHost._changeSubscriber.componentWillUpdate(this); - }; - - ComponentMixin.unmountComponent = function() { - originalUnmountComponent.apply(this, arguments); - ReactHost._changeSubscriber.componentWillUnmount(this); - }; -} else if (ReactInternals.Reconciler) { - // 0.13 - - // Monkey patched to track updates - var ReactReconciler = ReactInternals.Reconciler; - - // Monkey patch Components to track rerenders - - var originalMountComponent = ReactReconciler.mountComponent; - var originalPerformUpdateIfNecessary = ReactReconciler.performUpdateIfNecessary; - var originalReceiveComponent = ReactReconciler.receiveComponent; - var originalUnmountComponent = ReactReconciler.unmountComponent; - - ReactReconciler.mountComponent = function(instance) { - var result = originalMountComponent.apply(this, arguments); - ReactHost._changeSubscriber.componentWillMount(instance); - return result; - }; - - ReactReconciler.performUpdateIfNecessary = function(instance) { - var result = originalPerformUpdateIfNecessary.apply(this, arguments); - ReactHost._changeSubscriber.componentWillUpdate(instance); - return result; - }; - - ReactReconciler.receiveComponent = function(instance) { - var result = originalReceiveComponent.apply(this, arguments); - ReactHost._changeSubscriber.componentWillUpdate(instance); - return result; - }; - - ReactReconciler.unmountComponent = function(instance) { - var result = originalUnmountComponent.apply(this, arguments); - ReactHost._changeSubscriber.componentWillUnmount(instance); - return result; - }; -} - -// React Host API - -var ReactHost = { - - _changeSubscriber: null, - - instancesByRootID: ReactMount._instancesByReactRootID || ReactMount._instancesByContainerID, - - subscribeToChanges: function(subscriber) { - this._changeSubscriber = subscriber; - }, - - isTextComponent: function(component) { - if (!ReactTextComponent) return false; - // ReactTextComponent is the type in React 0.10 but is the element factory - // in React 0.11+, so check both - return component instanceof ReactTextComponent || ( - ReactTextComponent.type && - component instanceof ReactTextComponent.type - ); - }, - - _unwrapMethod: function(method, targetEventName) { - var context = method.__reactBoundContext; - var originalMethod = method.__reactBoundMethod; - if (!originalMethod || !context) { - return { - name: targetEventName, - handler: method - }; - } - for (var autoBindKey in context.__reactAutoBindMap) { - if (!context.__reactAutoBindMap.hasOwnProperty(autoBindKey)) { - continue; - } - var method = context.__reactAutoBindMap[autoBindKey]; - if (method === originalMethod) { - return { - name: targetEventName, - handler: originalMethod, - owner: context, - methodName: autoBindKey - }; - } - } - return { - name: targetEventName, - handler: originalMethod - }; - }, - - getEventListeners: function(instance) { - if (!instance || (!instance.props && !instance._currentElement)) return []; - var props = instance.props || instance._currentElement.props; - var listeners = []; - for (var key in props) { - var listener = props[key]; - if (typeof listener === 'function') { - listeners.push(ReactHost._unwrapMethod(listener, key)); - } - } - return listeners; - }, - - isInstance: function(instance, instanceOrNode) { - if (instance === instanceOrNode) return true; - if (!ReactMount.isRenderedByReact(instanceOrNode)) return false; - var nodeID = ReactMount.getID(instanceOrNode); - if (nodeID !== instance._rootNodeID) { - return false; - } - if (!instance._renderedComponent) { - return true; - } - // This heuristic is used to determine that we're at the bottom layer, the - // rest is just a wrapped component. - return instance._renderedComponent.hasOwnProperty('_renderedChildren') && - instance._currentElement && - typeof instance._currentElement.type === 'string'; - }, - - isAncestorOf: function(ancestor, descendant) { - var ancestorID = ancestor._rootNodeID; - var descendantID = descendant._rootNodeID || ReactMount.getID(descendant); - return ReactInstanceHandles.isAncestorIDOf(ancestorID, descendantID); - }, - - hasTextContent: function(component) { - if (component._currentElement) { - var element = component._currentElement; - return ( - typeof element.type === 'string' && // if it's native - element.props && ( // and has text content as children - typeof element.props.children === 'string' || - typeof element.props.children === 'number' - ) - ); - } - // Return true if this is a native component with text content - return ( - component.tagName && - component.props && ( - typeof component.props.children === 'string' || - typeof component.props.children === 'number' - ) - ); - }, - - getTextContent: function(component) { - if (component._currentElement) { - return component._currentElement.props.children; - } - return component.props.children; - }, - - getCurrentlyRenderingComponent: function() { - return ReactCurrentOwner.current; - } - -}; - -return ReactHost; - -}) diff --git a/injected/RuntimeHost.js b/injected/RuntimeHost.js deleted file mode 100644 index ad99d88de7..0000000000 --- a/injected/RuntimeHost.js +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Copyright (c) 2013-2014, Facebook, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * * Neither the name Facebook nor the names of its contributors may be used to - * endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * This module gets executed on the host page and exposes hooks into the - * JavaScript object environment. Currently this is just a pass through - * for InjectedScript, but may extend it with custom functionality. - */ - -(function(ReactHost, InjectedScript) { - -return InjectedScript; - -}) \ No newline at end of file diff --git a/lib/react.js b/lib/react.js deleted file mode 100755 index e69222c7c0..0000000000 --- a/lib/react.js +++ /dev/null @@ -1,14294 +0,0 @@ -/** - * React v0.5.1 - */ -!function(e){"object"==typeof exports?module.exports=e():"function"==typeof define&&define.amd?define(e):"undefined"!=typeof window?window.React=e():"undefined"!=typeof global?global.React=e():"undefined"!=typeof self&&(self.React=e())}(function(){var define,module,exports; -return (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);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o createMarkupForStyles({width: '200px', height: 0}) - * "width:200px;height:0;" - * - * Undefined values are ignored so that declarative programming is easier. - * - * @param {object} styles - * @return {?string} - */ - createMarkupForStyles: function(styles) { - var serialized = ''; - for (var styleName in styles) { - if (!styles.hasOwnProperty(styleName)) { - continue; - } - var styleValue = styles[styleName]; - if (styleValue != null) { - serialized += processStyleName(styleName) + ':'; - serialized += dangerousStyleValue(styleName, styleValue) + ';'; - } - } - return serialized || null; - }, - - /** - * Sets the value for multiple styles on a node. If a value is specified as - * '' (empty string), the corresponding style property will be unset. - * - * @param {DOMElement} node - * @param {object} styles - */ - setValueForStyles: function(node, styles) { - var style = node.style; - for (var styleName in styles) { - if (!styles.hasOwnProperty(styleName)) { - continue; - } - var styleValue = dangerousStyleValue(styleName, styles[styleName]); - if (styleValue) { - style[styleName] = styleValue; - } else { - var expansion = CSSProperty.shorthandPropertyExpansions[styleName]; - if (expansion) { - // Shorthand property that IE8 won't like unsetting, so unset each - // component to placate it - for (var individualStyleName in expansion) { - style[individualStyleName] = ''; - } - } else { - style[styleName] = ''; - } - } - } - } - -}; - -module.exports = CSSPropertyOperations; - -},{"./CSSProperty":2,"./dangerousStyleValue":80,"./escapeTextForBrowser":82,"./hyphenate":94,"./memoizeStringOnly":103}],4:[function(require,module,exports){ -/** - * Copyright 2013 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 CallbackRegistry - * @typechecks static-only - */ - -"use strict"; - -var listenerBank = {}; - -/** - * Stores "listeners" by `registrationName`/`id`. There should be at most one - * "listener" per `registrationName`/`id` in the `listenerBank`. - * - * Access listeners via `listenerBank[registrationName][id]`. - * - * @class CallbackRegistry - * @internal - */ -var CallbackRegistry = { - - /** - * Stores `listener` at `listenerBank[registrationName][id]`. Is idempotent. - * - * @param {string} id ID of the DOM element. - * @param {string} registrationName Name of listener (e.g. `onClick`). - * @param {?function} listener The callback to store. - */ - putListener: function(id, registrationName, listener) { - var bankForRegistrationName = - listenerBank[registrationName] || (listenerBank[registrationName] = {}); - bankForRegistrationName[id] = listener; - }, - - /** - * @param {string} id ID of the DOM element. - * @param {string} registrationName Name of listener (e.g. `onClick`). - * @return {?function} The stored callback. - */ - getListener: function(id, registrationName) { - var bankForRegistrationName = listenerBank[registrationName]; - return bankForRegistrationName && bankForRegistrationName[id]; - }, - - /** - * Deletes a listener from the registration bank. - * - * @param {string} id ID of the DOM element. - * @param {string} registrationName Name of listener (e.g. `onClick`). - */ - deleteListener: function(id, registrationName) { - var bankForRegistrationName = listenerBank[registrationName]; - if (bankForRegistrationName) { - delete bankForRegistrationName[id]; - } - }, - - /** - * Deletes all listeners for the DOM element with the supplied ID. - * - * @param {string} id ID of the DOM element. - */ - deleteAllListeners: function(id) { - for (var registrationName in listenerBank) { - delete listenerBank[registrationName][id]; - } - }, - - /** - * This is needed for tests only. Do not use! - */ - __purge: function() { - listenerBank = {}; - } - -}; - -module.exports = CallbackRegistry; - -},{}],5:[function(require,module,exports){ -/** - * Copyright 2013 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 ChangeEventPlugin - */ - -"use strict"; - -var EventConstants = require("./EventConstants"); -var EventPluginHub = require("./EventPluginHub"); -var EventPropagators = require("./EventPropagators"); -var ExecutionEnvironment = require("./ExecutionEnvironment"); -var SyntheticEvent = require("./SyntheticEvent"); - -var isEventSupported = require("./isEventSupported"); -var isTextInputElement = require("./isTextInputElement"); -var keyOf = require("./keyOf"); - -var topLevelTypes = EventConstants.topLevelTypes; - -var eventTypes = { - change: { - phasedRegistrationNames: { - bubbled: keyOf({onChange: null}), - captured: keyOf({onChangeCapture: null}) - } - } -}; - -/** - * For IE shims - */ -var activeElement = null; -var activeElementID = null; -var activeElementValue = null; -var activeElementValueProp = null; - -/** - * SECTION: handle `change` event - */ -function shouldUseChangeEvent(elem) { - return ( - elem.nodeName === 'SELECT' || - (elem.nodeName === 'INPUT' && elem.type === 'file') - ); -} - -var doesChangeEventBubble = false; -if (ExecutionEnvironment.canUseDOM) { - // See `handleChange` comment below - doesChangeEventBubble = isEventSupported('change') && ( - !('documentMode' in document) || document.documentMode > 8 - ); -} - -function manualDispatchChangeEvent(nativeEvent) { - var event = SyntheticEvent.getPooled( - eventTypes.change, - activeElementID, - nativeEvent - ); - EventPropagators.accumulateTwoPhaseDispatches(event); - - // If change bubbled, we'd just bind to it like all the other events - // and have it go through ReactEventTopLevelCallback. Since it doesn't, we - // manually listen for the change event and so we have to enqueue and - // process the abstract event manually. - EventPluginHub.enqueueEvents(event); - EventPluginHub.processEventQueue(); -} - -function startWatchingForChangeEventIE8(target, targetID) { - activeElement = target; - activeElementID = targetID; - activeElement.attachEvent('onchange', manualDispatchChangeEvent); -} - -function stopWatchingForChangeEventIE8() { - if (!activeElement) { - return; - } - activeElement.detachEvent('onchange', manualDispatchChangeEvent); - activeElement = null; - activeElementID = null; -} - -function getTargetIDForChangeEvent( - topLevelType, - topLevelTarget, - topLevelTargetID) { - if (topLevelType === topLevelTypes.topChange) { - return 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. - stopWatchingForChangeEventIE8(); - startWatchingForChangeEventIE8(topLevelTarget, topLevelTargetID); - } else if (topLevelType === topLevelTypes.topBlur) { - stopWatchingForChangeEventIE8(); - } -} - - -/** - * SECTION: handle `input` event - */ -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 - ); -} - -/** - * (For old IE.) Replacement getter/setter for the `value` property that gets - * set on the active element. - */ -var newValueProp = { - get: function() { - return activeElementValueProp.get.call(this); - }, - set: function(val) { - // Cast to a string so we can do equality checks. - activeElementValue = '' + val; - activeElementValueProp.set.call(this, val); - } -}; - -/** - * (For old IE.) Starts tracking propertychange events on the passed-in element - * and override the value property so that we can distinguish user events from - * value changes in JS. - */ -function startWatchingForValueChange(target, targetID) { - activeElement = target; - activeElementID = targetID; - activeElementValue = target.value; - activeElementValueProp = Object.getOwnPropertyDescriptor( - target.constructor.prototype, - 'value' - ); - - Object.defineProperty(activeElement, 'value', newValueProp); - activeElement.attachEvent('onpropertychange', handlePropertyChange); -} - -/** - * (For old IE.) Removes the event listeners from the currently-tracked element, - * if any exists. - */ -function stopWatchingForValueChange() { - if (!activeElement) { - return; - } - - // delete restores the original property definition - delete activeElement.value; - activeElement.detachEvent('onpropertychange', handlePropertyChange); - - activeElement = null; - activeElementID = null; - activeElementValue = null; - activeElementValueProp = null; -} - -/** - * (For old IE.) Handles a propertychange event, sending a `change` event if - * the value of the active element has changed. - */ -function handlePropertyChange(nativeEvent) { - if (nativeEvent.propertyName !== 'value') { - return; - } - var value = nativeEvent.srcElement.value; - if (value === activeElementValue) { - return; - } - activeElementValue = value; - - manualDispatchChangeEvent(nativeEvent); -} - -/** - * If a `change` event should be fired, returns the target's ID. - */ -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 - return topLevelTargetID; - } -} - -// For IE8 and IE9. -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 - // equal to 'value' - // In IE9, propertychange fires for most input events but is buggy and - // doesn't fire when text is deleted, but conveniently, selectionchange - // appears to fire in all of the remaining cases so we catch those and - // forward the event if the value has changed - // In either case, we don't want to call the event handler if the value - // is changed from JS so we redefine a setter for `.value` that updates - // our activeElementValue variable, allowing us to ignore those changes - // - // stopWatching() should be a noop here but we call it just in case we - // missed a blur event somehow. - stopWatchingForValueChange(); - startWatchingForValueChange(topLevelTarget, topLevelTargetID); - } else if (topLevelType === topLevelTypes.topBlur) { - stopWatchingForValueChange(); - } -} - -// For IE8 and IE9. -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. - // - // 99% of the time, keydown and keyup aren't necessary. IE8 fails to fire - // propertychange on the first input event after setting `value` from a - // script and fires only keydown, keypress, keyup. Catching keyup usually - // gets it and catching keydown lets us fire an event for the first - // keystroke if user does a key repeat (it'll be a little delayed: right - // before the second keystroke). Other input methods (e.g., paste) seem to - // fire selectionchange normally. - if (activeElement && activeElement.value !== activeElementValue) { - activeElementValue = activeElement.value; - return activeElementID; - } - } -} - - -/** - * SECTION: handle `click` event - */ -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') - ); -} - -function getTargetIDForClickEvent( - topLevelType, - topLevelTarget, - topLevelTargetID) { - if (topLevelType === topLevelTypes.topClick) { - return topLevelTargetID; - } -} - -/** - * This plugin creates an `onChange` event that normalizes change events - * across form elements. This event fires at a time when it's possible to - * change the element's value without seeing a flicker. - * - * Supported elements are: - * - input (see `isTextInputElement`) - * - textarea - * - select - */ -var ChangeEventPlugin = { - - eventTypes: eventTypes, - - /** - * @param {string} topLevelType Record from `EventConstants`. - * @param {DOMEventTarget} topLevelTarget The listening component root node. - * @param {string} topLevelTargetID ID of `topLevelTarget`. - * @param {object} nativeEvent Native browser event. - * @return {*} An accumulation of synthetic events. - * @see {EventPluginHub.extractEvents} - */ - extractEvents: function( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent) { - - var getTargetIDFunc, handleEventFunc; - if (shouldUseChangeEvent(topLevelTarget)) { - if (doesChangeEventBubble) { - getTargetIDFunc = getTargetIDForChangeEvent; - } else { - handleEventFunc = handleEventsForChangeEventIE8; - } - } else if (isTextInputElement(topLevelTarget)) { - if (isInputEventSupported) { - getTargetIDFunc = getTargetIDForInputEvent; - } else { - getTargetIDFunc = getTargetIDForInputEventIE; - handleEventFunc = handleEventsForInputEventIE; - } - } else if (shouldUseClickEvent(topLevelTarget)) { - getTargetIDFunc = getTargetIDForClickEvent; - } - - if (getTargetIDFunc) { - var targetID = getTargetIDFunc( - topLevelType, - topLevelTarget, - topLevelTargetID - ); - if (targetID) { - var event = SyntheticEvent.getPooled( - eventTypes.change, - targetID, - nativeEvent - ); - EventPropagators.accumulateTwoPhaseDispatches(event); - return event; - } - } - - if (handleEventFunc) { - handleEventFunc( - topLevelType, - topLevelTarget, - topLevelTargetID - ); - } - } - -}; - -module.exports = ChangeEventPlugin; - -},{"./EventConstants":14,"./EventPluginHub":16,"./EventPropagators":19,"./ExecutionEnvironment":20,"./SyntheticEvent":65,"./isEventSupported":96,"./isTextInputElement":98,"./keyOf":102}],6:[function(require,module,exports){ -/** - * Copyright 2013 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 CompositionEventPlugin - * @typechecks static-only - */ - -"use strict"; - -var EventConstants = require("./EventConstants"); -var EventPropagators = require("./EventPropagators"); -var ExecutionEnvironment = require("./ExecutionEnvironment"); -var ReactInputSelection = require("./ReactInputSelection"); -var SyntheticCompositionEvent = require("./SyntheticCompositionEvent"); - -var getTextContentAccessor = require("./getTextContentAccessor"); -var keyOf = require("./keyOf"); - -var END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space -var START_KEYCODE = 229; - -var useCompositionEvent = ExecutionEnvironment.canUseDOM && - 'CompositionEvent' in window; -var topLevelTypes = EventConstants.topLevelTypes; -var currentComposition = null; - -// Events and their corresponding property names. -var eventTypes = { - compositionEnd: { - phasedRegistrationNames: { - bubbled: keyOf({onCompositionEnd: null}), - captured: keyOf({onCompositionEndCapture: null}) - } - }, - compositionStart: { - phasedRegistrationNames: { - bubbled: keyOf({onCompositionStart: null}), - captured: keyOf({onCompositionStartCapture: null}) - } - }, - compositionUpdate: { - phasedRegistrationNames: { - bubbled: keyOf({onCompositionUpdate: null}), - captured: keyOf({onCompositionUpdateCapture: null}) - } - } -}; - -/** - * Translate native top level events into event types. - * - * @param {string} topLevelType - * @return {object} - */ -function getCompositionEventType(topLevelType) { - switch (topLevelType) { - case topLevelTypes.topCompositionStart: - return eventTypes.compositionStart; - case topLevelTypes.topCompositionEnd: - return eventTypes.compositionEnd; - case topLevelTypes.topCompositionUpdate: - return eventTypes.compositionUpdate; - } -} - -/** - * Does our fallback best-guess model think this event signifies that - * composition has begun? - * - * @param {string} topLevelType - * @param {object} nativeEvent - * @return {boolean} - */ -function isFallbackStart(topLevelType, nativeEvent) { - return ( - topLevelType === topLevelTypes.topKeyDown && - nativeEvent.keyCode === START_KEYCODE - ); -} - -/** - * Does our fallback mode think that this event is the end of composition? - * - * @param {string} topLevelType - * @param {object} nativeEvent - * @return {boolean} - */ -function isFallbackEnd(topLevelType, nativeEvent) { - switch (topLevelType) { - case topLevelTypes.topKeyUp: - // Command keys insert or clear IME input. - 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); - case topLevelTypes.topKeyPress: - case topLevelTypes.topMouseDown: - case topLevelTypes.topBlur: - // Events are not possible without cancelling IME. - return true; - default: - return false; - } -} - -/** - * Helper class stores information about selection and document state - * so we can figure out what changed at a later date. - * - * @param {DOMEventTarget} root - */ -function FallbackCompositionState(root) { - this.root = root; - this.startSelection = ReactInputSelection.getSelection(root); - this.startValue = this.getText(); -} - -/** - * Get current text of input. - * - * @return {string} - */ -FallbackCompositionState.prototype.getText = function() { - return this.root.value || this.root[getTextContentAccessor()]; -}; - -/** - * Text that has changed since the start of composition. - * - * @return {string} - */ -FallbackCompositionState.prototype.getData = function() { - var endValue = this.getText(); - var prefixLength = this.startSelection.start; - var suffixLength = this.startValue.length - this.startSelection.end; - - return endValue.substr( - prefixLength, - endValue.length - suffixLength - prefixLength - ); -}; - -/** - * This plugin creates `onCompositionStart`, `onCompositionUpdate` and - * `onCompositionEnd` events on inputs, textareas and contentEditable - * nodes. - */ -var CompositionEventPlugin = { - - eventTypes: eventTypes, - - /** - * @param {string} topLevelType Record from `EventConstants`. - * @param {DOMEventTarget} topLevelTarget The listening component root node. - * @param {string} topLevelTargetID ID of `topLevelTarget`. - * @param {object} nativeEvent Native browser event. - * @return {*} An accumulation of synthetic events. - * @see {EventPluginHub.extractEvents} - */ - extractEvents: function( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent) { - - var eventType; - var data; - - if (useCompositionEvent) { - eventType = getCompositionEventType(topLevelType); - } else if (!currentComposition) { - if (isFallbackStart(topLevelType, nativeEvent)) { - eventType = eventTypes.start; - currentComposition = new FallbackCompositionState(topLevelTarget); - } - } else if (isFallbackEnd(topLevelType, nativeEvent)) { - eventType = eventTypes.compositionEnd; - data = currentComposition.getData(); - currentComposition = null; - } - - if (eventType) { - var event = SyntheticCompositionEvent.getPooled( - eventType, - topLevelTargetID, - nativeEvent - ); - if (data) { - // Inject data generated from fallback path into the synthetic event. - // This matches the property of native CompositionEventInterface. - event.data = data; - } - EventPropagators.accumulateTwoPhaseDispatches(event); - return event; - } - } -}; - -module.exports = CompositionEventPlugin; - -},{"./EventConstants":14,"./EventPropagators":19,"./ExecutionEnvironment":20,"./ReactInputSelection":46,"./SyntheticCompositionEvent":64,"./getTextContentAccessor":93,"./keyOf":102}],7:[function(require,module,exports){ -/** - * Copyright 2013 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 DOMChildrenOperations - * @typechecks static-only - */ - -"use strict"; - -var Danger = require("./Danger"); -var ReactMultiChildUpdateTypes = require("./ReactMultiChildUpdateTypes"); - -var getTextContentAccessor = require("./getTextContentAccessor"); - -/** - * The DOM property to use when setting text content. - * - * @type {string} - * @private - */ -var textContentAccessor = getTextContentAccessor() || 'NA'; - -/** - * Inserts `childNode` as a child of `parentNode` at the `index`. - * - * @param {DOMElement} parentNode Parent node in which to insert. - * @param {DOMElement} childNode Child node to insert. - * @param {number} index Index at which to insert the child. - * @internal - */ -function insertChildAt(parentNode, childNode, index) { - var childNodes = parentNode.childNodes; - if (childNodes[index] === childNode) { - return; - } - // If `childNode` is already a child of `parentNode`, remove it so that - // computing `childNodes[index]` takes into account the removal. - if (childNode.parentNode === parentNode) { - parentNode.removeChild(childNode); - } - if (index >= childNodes.length) { - parentNode.appendChild(childNode); - } else { - parentNode.insertBefore(childNode, childNodes[index]); - } -} - -/** - * Operations for updating with DOM children. - */ -var DOMChildrenOperations = { - - dangerouslyReplaceNodeWithMarkup: Danger.dangerouslyReplaceNodeWithMarkup, - - /** - * Updates a component's children by processing a series of updates. The - * update configurations are each expected to have a `parentNode` property. - * - * @param {array} updates List of update configurations. - * @param {array} markupList List of markup strings. - * @internal - */ - processUpdates: function(updates, markupList) { - var update; - // Mapping from parent IDs to initial child orderings. - var initialChildren = null; - // List of children that will be moved or removed. - var updatedChildren = null; - - for (var i = 0; update = updates[i]; i++) { - 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; - - initialChildren = initialChildren || {}; - initialChildren[parentID] = initialChildren[parentID] || []; - initialChildren[parentID][updatedIndex] = updatedChild; - - updatedChildren = updatedChildren || []; - updatedChildren.push(updatedChild); - } - } - - var renderedMarkup = Danger.dangerouslyRenderMarkup(markupList); - - // Remove updated children first so that `toIndex` is consistent. - if (updatedChildren) { - for (var j = 0; j < updatedChildren.length; j++) { - updatedChildren[j].parentNode.removeChild(updatedChildren[j]); - } - } - - for (var k = 0; update = updates[k]; k++) { - switch (update.type) { - case ReactMultiChildUpdateTypes.INSERT_MARKUP: - insertChildAt( - update.parentNode, - renderedMarkup[update.markupIndex], - update.toIndex - ); - break; - case ReactMultiChildUpdateTypes.MOVE_EXISTING: - insertChildAt( - update.parentNode, - initialChildren[update.parentID][update.fromIndex], - update.toIndex - ); - break; - case ReactMultiChildUpdateTypes.TEXT_CONTENT: - update.parentNode[textContentAccessor] = update.textContent; - break; - case ReactMultiChildUpdateTypes.REMOVE_NODE: - // Already removed by the for-loop above. - break; - } - } - } - -}; - -module.exports = DOMChildrenOperations; - -},{"./Danger":10,"./ReactMultiChildUpdateTypes":52,"./getTextContentAccessor":93}],8:[function(require,module,exports){ -/** - * Copyright 2013 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 DOMProperty - * @typechecks static-only - */ - -/*jslint bitwise: true */ - -"use strict"; - -var invariant = require("./invariant"); - -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_BOOLEAN_VALUE: 0x4, - HAS_SIDE_EFFECTS: 0x8, - - /** - * Inject some specialized knowledge about the DOM. This takes a config object - * with the following properties: - * - * isCustomAttribute: function that given an attribute name will return true - * if it can be inserted into the DOM verbatim. Useful for data-* or aria-* - * attributes where it's impossible to enumerate all of the possible - * attribute names, - * - * Properties: object mapping DOM property name to one of the - * DOMPropertyInjection constants or null. If your attribute isn't in here, - * it won't get written to the DOM. - * - * DOMAttributeNames: object mapping React attribute name to the DOM - * attribute name. Attribute names not specified use the **lowercase** - * normalized name. - * - * DOMPropertyNames: similar to DOMAttributeNames but for DOM properties. - * Property names not specified use the normalized name. - * - * DOMMutationMethods: Properties that require special mutation methods. If - * `value` is undefined, the mutation method should unset the property. - * - * @param {object} domPropertyConfig the config as described above. - */ - injectDOMPropertyConfig: function(domPropertyConfig) { - var Properties = domPropertyConfig.Properties || {}; - var DOMAttributeNames = domPropertyConfig.DOMAttributeNames || {}; - var DOMPropertyNames = domPropertyConfig.DOMPropertyNames || {}; - var DOMMutationMethods = domPropertyConfig.DOMMutationMethods || {}; - - if (domPropertyConfig.isCustomAttribute) { - DOMProperty._isCustomAttributeFunctions.push( - domPropertyConfig.isCustomAttribute - ); - } - - for (var propName in Properties) { - invariant( - !DOMProperty.isStandardName[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 - ); - - DOMProperty.isStandardName[propName] = true; - - var lowerCased = propName.toLowerCase(); - DOMProperty.getPossibleStandardName[lowerCased] = propName; - - var attributeName = DOMAttributeNames[propName]; - if (attributeName) { - DOMProperty.getPossibleStandardName[attributeName] = propName; - } - - DOMProperty.getAttributeName[propName] = attributeName || lowerCased; - - DOMProperty.getPropertyName[propName] = - DOMPropertyNames[propName] || propName; - - var mutationMethod = DOMMutationMethods[propName]; - if (mutationMethod) { - DOMProperty.getMutationMethod[propName] = mutationMethod; - } - - var propConfig = Properties[propName]; - DOMProperty.mustUseAttribute[propName] = - propConfig & DOMPropertyInjection.MUST_USE_ATTRIBUTE; - DOMProperty.mustUseProperty[propName] = - propConfig & DOMPropertyInjection.MUST_USE_PROPERTY; - DOMProperty.hasBooleanValue[propName] = - propConfig & DOMPropertyInjection.HAS_BOOLEAN_VALUE; - DOMProperty.hasSideEffects[propName] = - propConfig & DOMPropertyInjection.HAS_SIDE_EFFECTS; - - invariant( - !DOMProperty.mustUseAttribute[propName] || - !DOMProperty.mustUseProperty[propName], - 'DOMProperty: Cannot use require using both attribute and property: %s', - propName - ); - invariant( - DOMProperty.mustUseProperty[propName] || - !DOMProperty.hasSideEffects[propName], - 'DOMProperty: Properties that have side effects must use property: %s', - propName - ); - } - } -}; -var defaultValueCache = {}; - -/** - * DOMProperty exports lookup objects that can be used like functions: - * - * > DOMProperty.isValid['id'] - * true - * > DOMProperty.isValid['foobar'] - * undefined - * - * Although this may be confusing, it performs better in general. - * - * @see http://jsperf.com/key-exists - * @see http://jsperf.com/key-missing - */ -var DOMProperty = { - - /** - * Checks whether a property name is a standard property. - * @type {Object} - */ - isStandardName: {}, - - /** - * 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 the property should be removed when set to a falsey value. - * @type {Object} - */ - hasBooleanValue: {}, - - /** - * 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: {}, - - /** - * All of the isCustomAttribute() functions that have been injected. - */ - _isCustomAttributeFunctions: [], - - /** - * Checks whether a property name is a custom attribute. - * @method - */ - isCustomAttribute: function(attributeName) { - return DOMProperty._isCustomAttributeFunctions.some( - function(isCustomAttributeFn) { - return isCustomAttributeFn.call(null, attributeName); - } - ); - }, - - /** - * Returns the default property value for a DOM property (i.e., not an - * attribute). Most default values are '' or false, but not all. Worse yet, - * some (in particular, `type`) vary depending on the type of element. - * - * 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) { - var nodeDefaults = defaultValueCache[nodeName]; - var testElement; - if (!nodeDefaults) { - defaultValueCache[nodeName] = nodeDefaults = {}; - } - if (!(prop in nodeDefaults)) { - testElement = document.createElement(nodeName); - nodeDefaults[prop] = testElement[prop]; - } - return nodeDefaults[prop]; - }, - - injection: DOMPropertyInjection -}; - -module.exports = DOMProperty; - -},{"./invariant":95}],9:[function(require,module,exports){ -/** - * Copyright 2013 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 DOMPropertyOperations - * @typechecks static-only - */ - -"use strict"; - -var DOMProperty = require("./DOMProperty"); - -var escapeTextForBrowser = require("./escapeTextForBrowser"); -var memoizeStringOnly = require("./memoizeStringOnly"); - -var processAttributeNameAndPrefix = memoizeStringOnly(function(name) { - return escapeTextForBrowser(name) + '="'; -}); - -if (true) { - var reactProps = { - __owner__: true, - children: true, - dangerouslySetInnerHTML: true, - key: true, - ref: true - }; - var warnedProperties = {}; - - var warnUnknownProperty = function(name) { - if (reactProps[name] || warnedProperties[name]) { - return; - } - - warnedProperties[name] = true; - var lowerCasedName = name.toLowerCase(); - - // data-* attributes should be lowercase; suggest the lowercase version - var standardName = DOMProperty.isCustomAttribute(lowerCasedName) ? - lowerCasedName : DOMProperty.getPossibleStandardName[lowerCasedName]; - - // For now, only warn when we have a suggested correction. This prevents - // logging too much when using transferPropsTo. - if (standardName != null) { - console.warn( - 'Unknown DOM property ' + name + '. Did you mean ' + standardName + '?' - ); - } - - }; -} - -/** - * Operations for dealing with DOM properties. - */ -var DOMPropertyOperations = { - - /** - * Creates markup for a property. - * - * @param {string} name - * @param {*} value - * @return {?string} Markup string, or null if the property was invalid. - */ - createMarkupForProperty: function(name, value) { - if (DOMProperty.isStandardName[name]) { - if (value == null || DOMProperty.hasBooleanValue[name] && !value) { - return ''; - } - var attributeName = DOMProperty.getAttributeName[name]; - return processAttributeNameAndPrefix(attributeName) + - escapeTextForBrowser(value) + '"'; - } else if (DOMProperty.isCustomAttribute(name)) { - if (value == null) { - return ''; - } - return processAttributeNameAndPrefix(name) + - escapeTextForBrowser(value) + '"'; - } else if (true) { - warnUnknownProperty(name); - } - return null; - }, - - /** - * Sets the value for a property on a node. - * - * @param {DOMElement} node - * @param {string} name - * @param {*} value - */ - setValueForProperty: function(node, name, value) { - if (DOMProperty.isStandardName[name]) { - var mutationMethod = DOMProperty.getMutationMethod[name]; - if (mutationMethod) { - mutationMethod(node, value); - } else if (DOMProperty.mustUseAttribute[name]) { - if (DOMProperty.hasBooleanValue[name] && !value) { - node.removeAttribute(DOMProperty.getAttributeName[name]); - } else { - node.setAttribute(DOMProperty.getAttributeName[name], '' + value); - } - } else { - var propName = DOMProperty.getPropertyName[name]; - if (!DOMProperty.hasSideEffects[name] || node[propName] !== value) { - node[propName] = value; - } - } - } else if (DOMProperty.isCustomAttribute(name)) { - node.setAttribute(name, '' + value); - } else if (true) { - warnUnknownProperty(name); - } - }, - - /** - * Deletes the value for a property on a node. - * - * @param {DOMElement} node - * @param {string} name - */ - deleteValueForProperty: function(node, name) { - if (DOMProperty.isStandardName[name]) { - var mutationMethod = DOMProperty.getMutationMethod[name]; - if (mutationMethod) { - mutationMethod(node, undefined); - } else if (DOMProperty.mustUseAttribute[name]) { - node.removeAttribute(DOMProperty.getAttributeName[name]); - } else { - var propName = DOMProperty.getPropertyName[name]; - node[propName] = DOMProperty.getDefaultValueForProperty( - node.nodeName, - name - ); - } - } else if (DOMProperty.isCustomAttribute(name)) { - node.removeAttribute(name); - } else if (true) { - warnUnknownProperty(name); - } - } - -}; - -module.exports = DOMPropertyOperations; - -},{"./DOMProperty":8,"./escapeTextForBrowser":82,"./memoizeStringOnly":103}],10:[function(require,module,exports){ -/** - * Copyright 2013 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 Danger - * @typechecks static-only - */ - -/*jslint evil: true, sub: true */ - -"use strict"; - -var ExecutionEnvironment = require("./ExecutionEnvironment"); - -var createNodesFromMarkup = require("./createNodesFromMarkup"); -var emptyFunction = require("./emptyFunction"); -var getMarkupWrap = require("./getMarkupWrap"); -var invariant = require("./invariant"); -var mutateHTMLNodeWithMarkup = require("./mutateHTMLNodeWithMarkup"); - -var OPEN_TAG_NAME_EXP = /^(<[^ \/>]+)/; -var RESULT_INDEX_ATTR = 'data-danger-index'; - -/** - * Extracts the `nodeName` from a string of markup. - * - * NOTE: Extracting the `nodeName` does not require a regular expression match - * because we make assumptions about React-generated markup (i.e. there are no - * spaces surrounding the opening tag and there is at least one attribute). - * - * @param {string} markup String of markup. - * @return {string} Node name of the supplied markup. - * @see http://jsperf.com/extract-nodename - */ -function getNodeName(markup) { - return markup.substring(1, markup.indexOf(' ')); -} - -var Danger = { - - /** - * Renders markup into an array of nodes. The markup is expected to render - * into a list of root nodes. Also, the length of `resultList` and - * `markupList` should be the same. - * - * @param {array} markupList List of markup strings to render. - * @return {array} List of rendered nodes. - * @internal - */ - dangerouslyRenderMarkup: function(markupList) { - invariant( - ExecutionEnvironment.canUseDOM, - 'dangerouslyRenderMarkup(...): Cannot render markup in a Worker ' + - 'thread. This is likely a bug in the framework. Please report ' + - 'immediately.' - ); - var nodeName; - var markupByNodeName = {}; - // Group markup by `nodeName` if a wrap is necessary, else by '*'. - for (var i = 0; i < markupList.length; i++) { - invariant( - markupList[i], - 'dangerouslyRenderMarkup(...): Missing markup.' - ); - nodeName = getNodeName(markupList[i]); - nodeName = getMarkupWrap(nodeName) ? nodeName : '*'; - markupByNodeName[nodeName] = markupByNodeName[nodeName] || []; - markupByNodeName[nodeName][i] = markupList[i]; - } - var resultList = []; - var resultListAssignmentCount = 0; - for (nodeName in markupByNodeName) { - if (!markupByNodeName.hasOwnProperty(nodeName)) { - continue; - } - var markupListByNodeName = markupByNodeName[nodeName]; - - // This for-in loop skips the holes of the sparse array. The order of - // iteration should follow the order of assignment, which happens to match - // numerical index order, but we don't rely on that. - for (var resultIndex in markupListByNodeName) { - if (markupListByNodeName.hasOwnProperty(resultIndex)) { - var markup = markupListByNodeName[resultIndex]; - - // 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 + '" ' - ); - } - } - - // Render each group of markup with similar wrapping `nodeName`. - var renderNodes = createNodesFromMarkup( - markupListByNodeName.join(''), - emptyFunction // Do nothing special with - - - - - - - - - - - diff --git a/main.js b/main.js deleted file mode 100644 index 5c058d7c95..0000000000 --- a/main.js +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * 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. - * - */ - -var hasNewSelection = true; - -function runtimeLoaded(error) { - var elements = chrome.devtools.panels.elements; - if (!error) { - elements.onSelectionChanged.addListener(refreshSelection); - createMainPanel(); - } else { - elements.onSelectionChanged.addListener(retryRuntime); - } -} - -function retryRuntime() { - chrome.devtools.panels.elements.onSelectionChanged.removeListener( - retryRuntime - ); - ReactInspectorAgent.initialize(runtimeLoaded); -} - -function refreshSelection() { - // Wait to refresh the selection to avoid the React panel stealing focus - hasNewSelection = true; -} - -function createMainPanel() { - chrome.devtools.panels.create( - 'React', 'icon.png', 'views/devpanel.html', function(panel) { - panel.onShown.addListener(mainPanelShown); - } - ); -} - -function mainPanelShown(mainPanelWindow) { - if (!mainPanelWindow.wasShown) { - mainPanelWindow.focus(); - mainPanelWindow.initialize({ - InspectorBackend: InspectorBackend, - DOMAgent: DOMAgent, - RuntimeAgent: RuntimeAgent - }); - mainPanelWindow.wasShown = true; - } - - // Refresh selection - if (hasNewSelection) { - hasNewSelection = false; - ReactInspectorAgent.eval('DOM.inspectSelectedNode()', function() {}); - } -} - -ReactInspectorAgent.initialize(runtimeLoaded); diff --git a/manifest.json b/manifest.json deleted file mode 100644 index 67a0786b11..0000000000 --- a/manifest.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "manifest_version": 2, - "name": "React Developer Tools", - "description": "Adds React debugging tools to the Chrome Developer Tools.", - "version": "0.13.0", - "icons": { - "16": "icons/icon16.png", "48": "icons/icon48.png", "128": "icons/icon128.png" - }, - - "background": { - "scripts": [ "device/RegisterExtension.js" ], - "persistent": false - }, - - "devtools_page": "main.html", - - "content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'", - "web_accessible_resources": [ "main.html", "views/devpanel.html" ], - - "content_scripts": [ - { - "matches": [""], - "js": ["injected/GlobalHook.js"], - "run_at": "document_start" - } - ] -} diff --git a/tests/page.html b/tests/page.html deleted file mode 100644 index 01e5436f4e..0000000000 --- a/tests/page.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - Sample React Page - - - - - - - diff --git a/tests/page.js b/tests/page.js deleted file mode 100644 index 24c255bb3a..0000000000 --- a/tests/page.js +++ /dev/null @@ -1,133 +0,0 @@ -/** - * Copyright (c) 2013-2014, Facebook, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * * Neither the name Facebook nor the names of its contributors may be used to - * endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -var InnerComponent = React.createClass({ - - displayName: 'InnerComponent', - - render: function() { - var even = React.DOM.p({ key: 'even' }, 'even'); - var odd = React.DOM.p({ key: 'odd' }, 'odd'); - return React.DOM.div({}, - this.props.counter > 5 ? React.DOM.span(null, this.props.counter) : React.DOM.span(), - this.props.counter % 2 == 1 ? [even, odd] : [odd, even], - this.props.counter % 10 == 9 ? React.DOM.div() : null, - React.DOM.span({ onClick: this.props.onSomething.bind(null, 1, 2), regexp: /test/i, date: new Date(), array: [1,2,{},'str'] }, 'THIS HAS A HANDLER') - ); - } - -}); - -var TestComponent = React.createClass({ - - displayName: 'TestComponent', - - getInitialState: function() { - return { counter: 0 }; - }, - - componentDidMount: function() { - this._timer = setInterval(this.increment, 1000); - }, - - componentWillUnmount: function() { - clearInterval(this._timer); - }, - - increment: function() { - this.setState({ - counter: this.state.counter + 1 - }); - }, - - handleCallback: function(something) { - this.setState({ - counter: 0 - }); - }, - - render: function() { - return React.DOM.div({className: 'hello world'}, - this.state.counter, - InnerComponent({ counter: this.state.counter, onSomething: this.handleCallback }), - this.state.counter < 10 ? this.props.children : null - ); - } - -}); - -var List = React.createClass({ - - displayName: 'List', - - render: function() { - return React.DOM.ul(null, - this.props.items.map(function(item) { - return React.DOM.li(null, item) - }) - ); - } - -}); - -var OuterComponent = React.createClass({ - - displayName: 'OuterComponent', - - render: function() { - return React.DOM.div({}, - React.DOM.a( - { href: 'http://facebook.com' }, - React.DOM.img({ src: '/icons/icon128.png' }) - ), - React.DOM.div({}, React.DOM.span({}, List({items:['a', 'b', 'c']}))), - TestComponent( - { regexp3: /test/i }, - React.DOM.p({}, 'document', React.DOM.span()) - ) - ); - } - -}); - -var container = document.createElement('div'); -React.renderComponent(OuterComponent({ instance: 1 }), container); -document.body.appendChild(container); - -var container2 = document.createElement('div'); -document.body.appendChild(container2); - -setTimeout(function() { - // Render a second component later - React.renderComponent(OuterComponent({ instance: 2 }), container2); - setTimeout(function() { - React.unmountComponentAtNode(container2); - }, 5000); -}, 5000); diff --git a/views/components/ObjectSidebarPane.js b/views/components/ObjectSidebarPane.js deleted file mode 100644 index 21be1e018d..0000000000 --- a/views/components/ObjectSidebarPane.js +++ /dev/null @@ -1,95 +0,0 @@ -/** - * Copyright (c) 2013-2014, Facebook, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * * Neither the name Facebook nor the names of its contributors may be used to - * endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -ReactPanel.ObjectSidebarPane = function(name, emptyPlaceholder, editCallback) { - this._emptyPlaceholder = emptyPlaceholder; - this._editCallback = editCallback; - WebInspector.SidebarPane.call(this, name); -}; - -ReactPanel.ObjectSidebarPane.prototype = { - - update: function(object) { - var body = this.bodyElement; - body.removeChildren(); - - if (!object) { - return; - } - - var section = new WebInspector.ObjectPropertiesSection(object, '', '', this._emptyPlaceholder, false, null, ReactPanel.EditableObjectPropertyTreeElement.bind(null, this.onedit.bind(this))); - section.expanded = true; - section.editable = true; - section.headerElement.addStyleClass("hidden"); - body.appendChild(section.element); - }, - - onedit: function() { - if (this._editCallback) this._editCallback(); - }, - - __proto__: WebInspector.SidebarPane.prototype - -}; - -ReactPanel.EditableObjectPropertyTreeElement = function(editCallback, property) { - this._editCallback = editCallback; - WebInspector.ObjectPropertyTreeElement.call(this, property); -}; - -ReactPanel.EditableObjectPropertyTreeElement.prototype = { - - applyExpression: function(expression, updateInterface) { - expression = expression.trim(); - var expressionLength = expression.length; - function callback(error) - { - if (!updateInterface) - return; - - if (error) - this.update(); - - if (!expressionLength) { - // The property was deleted, so remove this tree element. - this.parent.removeChild(this); - } else { - // Call updateSiblings since their value might be based on the value that just changed. - this.updateSiblings(); - } - - this._editCallback(); - }; - this.property.parentObject.setPropertyValue(this.property.name, expression.trim(), callback.bind(this)); - }, - - __proto__: WebInspector.ObjectPropertyTreeElement.prototype - -}; diff --git a/views/components/ReactPanel.js b/views/components/ReactPanel.js deleted file mode 100755 index 471ed29b18..0000000000 --- a/views/components/ReactPanel.js +++ /dev/null @@ -1,1169 +0,0 @@ -/* - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. - * Copyright (C) 2008 Matt Lilek - * Copyright (C) 2009 Joseph Pecoraro - * Copyright (C) 2013-2014, Facebook, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -importScript("CSSNamedFlowCollectionsView.js"); -importScript("CSSNamedFlowView.js"); -importScript("EventListenersSidebarPane.js"); -importScript("ObjectSidebarPane.js"); - -var ReactPanel = function() -{ - WebInspector.View.call(this); - - this.element.addStyleClass("panel"); - this.element.addStyleClass("elements"); - - this.registerRequiredCSS("breadcrumbList.css"); - this.registerRequiredCSS("elementsPanel.css"); - this.registerRequiredCSS("textPrompt.css"); - this.setHideOnDetach(); - - const initialSidebarWidth = 325; - const minimumContentWidthPercent = 0.34; - const initialSidebarHeight = 325; - const minimumContentHeightPercent = 0.34; - this.createSidebarView(this.element, WebInspector.SidebarView.SidebarPosition.End, initialSidebarWidth, initialSidebarHeight); - this.splitView.setSidebarElementConstraints(Preferences.minElementsSidebarWidth, Preferences.minElementsSidebarHeight); - this.splitView.setMainElementConstraints(minimumContentWidthPercent, minimumContentHeightPercent); - this.splitView.addEventListener(WebInspector.SidebarView.EventTypes.Resized, this._updateTreeOutlineVisibleWidth.bind(this)); - - this._searchableView = new WebInspector.SearchableView(this); - this.splitView.mainElement.addStyleClass("vbox"); - this._searchableView.show(this.splitView.mainElement); - var stackElement = this._searchableView.element; - - this.contentElement = stackElement.createChild("div"); - this.contentElement.id = "elements-content"; - this.contentElement.addStyleClass("outline-disclosure"); - this.contentElement.addStyleClass("source-code"); - if (!WebInspector.settings.domWordWrap.get()) - this.contentElement.classList.add("nowrap"); - WebInspector.settings.domWordWrap.addChangeListener(this._domWordWrapSettingChanged.bind(this)); - - this.contentElement.addEventListener("contextmenu", this._contextMenuEventFired.bind(this), true); - this.splitView.sidebarElement.addEventListener("contextmenu", this._sidebarContextMenuEventFired.bind(this), false); - - this.treeOutline = new WebInspector.ElementsTreeOutline(true, true, this._populateContextMenu.bind(this), this._setPseudoClassForNodeId.bind(this)); - this.treeOutline.wireToDomAgent(); - this.treeOutline.addEventListener(WebInspector.ElementsTreeOutline.Events.SelectedNodeChanged, this._selectedNodeChanged, this); - this.treeOutline.addEventListener(WebInspector.ElementsTreeOutline.Events.ElementsTreeUpdated, this._updateBreadcrumbIfNeeded, this); - - this.element.addEventListener('keydown', this._treeKeyDown.bind(this), false); - - var crumbsContainer = stackElement.createChild("div"); - crumbsContainer.id = "elements-crumbs"; - this.crumbsElement = crumbsContainer.createChild("div", "crumbs"); - this.crumbsElement.addEventListener("mousemove", this._mouseMovedInCrumbs.bind(this), false); - this.crumbsElement.addEventListener("mouseout", this._mouseMovedOutOfCrumbs.bind(this), false); - - this.sidebarPanes = {}; - this.sidebarPanes.props = new ReactPanel.ObjectSidebarPane(WebInspector.UIString("Props"), WebInspector.UIString("No Props"), this.forceUpdate.bind(this)); - this.sidebarPanes.state = new ReactPanel.ObjectSidebarPane(WebInspector.UIString("State"), WebInspector.UIString("No State"), this.forceUpdate.bind(this)); - this.sidebarPanes.instance = new ReactPanel.ObjectSidebarPane(WebInspector.UIString("Component"), null, this.forceUpdate.bind(this));; - this.sidebarPanes.eventListeners = new WebInspector.EventListenersSidebarPane(); - - this.sidebarPanes.props.addEventListener(WebInspector.SidebarPane.EventTypes.wasShown, this.updateInstance.bind(this)); - this.sidebarPanes.state.addEventListener(WebInspector.SidebarPane.EventTypes.wasShown, this.updateInstance.bind(this)); - this.sidebarPanes.instance.addEventListener(WebInspector.SidebarPane.EventTypes.wasShown, this.updateInstance.bind(this)); - this.sidebarPanes.eventListeners.addEventListener(WebInspector.SidebarPane.EventTypes.wasShown, this.updateEventListeners.bind(this)); - - this.sidebarPanes.props.expand(); - this.sidebarPanes.state.expand(); - - //WebInspector.dockController.addEventListener(WebInspector.DockController.Events.DockSideChanged, this._dockSideChanged.bind(this)); - //WebInspector.settings.splitVerticallyWhenDockedToRight.addChangeListener(this._dockSideChanged.bind(this)); - this._dockSideChanged(); - - this._popoverHelper = new WebInspector.PopoverHelper(this.element, this._getPopoverAnchor.bind(this), this._showPopover.bind(this)); - this._popoverHelper.setTimeout(0); - - - WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.DocumentUpdated, this._documentUpdatedEvent, this); - - if (WebInspector.domAgent.existingDocument()) - this._documentUpdated(WebInspector.domAgent.existingDocument()); -} - -ReactPanel.prototype = { - - decorateNodeLabel: function(node, parentElement) - { - var title = node.nodeNameInCorrectCase(); - var nameElement = document.createElement(node.isStateful ? 'strong' : 'span'); - nameElement.textContent = title; - parentElement.appendChild(nameElement); - parentElement.title = title; - }, - - _treeKeyDown: function(event) { - if (event.target !== this.treeOutline.childrenListElement) - return; - - if (!this.treeOutline.selectedTreeElement || !event.shiftKey || event.altKey || event.metaKey || event.ctrlKey) - return; - - var nextNode; - if (event.keyIdentifier === 'Up') { - nextNode = this._findSiblingBreadcrumbNode(false); - } else if (event.keyIdentifier === 'Down') { - nextNode = this._findSiblingBreadcrumbNode(true); - } else { - return; - } - - if (nextNode) { - this.selectDOMNode(nextNode, true); - event.consume(true); - } - }, - - _findSiblingBreadcrumbNode: function(down) { - var crumbs = this.crumbsElement; - var crumb = crumbs.firstChild; - while (crumb) { - if (crumb.representedObject === this.selectedDOMNode()) { - var nextCrumb = down ? crumb.nextSibling : crumb.previousSibling; - return nextCrumb ? nextCrumb.representedObject : null; - } - crumb = crumb.nextSibling; - } - return null; - }, - - /* FROM PANEL */ - - createSidebarView: function(parentElement, position, defaultWidth, defaultHeight) - { - if (this.splitView) - return; - - if (!parentElement) - parentElement = this.element; - - this.splitView = new WebInspector.SidebarView(position, this._sidebarWidthSettingName(), defaultWidth, defaultHeight); - this.splitView.show(parentElement); - this.splitView.addEventListener(WebInspector.SidebarView.EventTypes.Resized, this.sidebarResized.bind(this)); - - this.sidebarElement = this.splitView.sidebarElement; - }, - - sidebarResized: function(event) - { - }, - - _sidebarWidthSettingName: function() - { - return "ElementsSidebarWidth"; - }, - - /* END FROM PANEL */ - - _updateTreeOutlineVisibleWidth: function() - { - if (!this.treeOutline) - return; - - var width = this.splitView.element.offsetWidth; - if (this.splitView.isVertical()) - width -= this.splitView.sidebarWidth(); - this.treeOutline.setVisibleWidth(width); - this.updateBreadcrumbSizes(); - }, - - defaultFocusedElement: function() - { - return this.treeOutline.element; - }, - - statusBarResized: function() - { - this.updateBreadcrumbSizes(); - }, - - wasShown: function() - { - // Attach heavy component lazily - if (this.treeOutline.element.parentElement !== this.contentElement) - this.contentElement.appendChild(this.treeOutline.element); - - this.updateBreadcrumb(); - this.treeOutline.updateSelection(); - this.treeOutline.setVisible(true); - - if (!this.treeOutline.rootDOMNode) - WebInspector.domAgent.requestDocument(); - }, - - willHide: function() - { - WebInspector.domAgent.hideDOMNodeHighlight(); - this.treeOutline.setVisible(false); - this._popoverHelper.hidePopover(); - - // Detach heavy component on hide - this.contentElement.removeChild(this.treeOutline.element); - - WebInspector.Panel.prototype.willHide.call(this); - }, - - onResize: function() - { - this.treeOutline.updateSelection(); - this.updateBreadcrumbSizes(); - }, - - createView: function(id) - { - if (!this._overridesView) - this._overridesView = new WebInspector.OverridesView(); - return this._overridesView; - }, - - _setPseudoClassForNodeId: function(nodeId, pseudoClass, enable) - { - var node = WebInspector.domAgent.nodeForId(nodeId); - if (!node) - return; - - var pseudoClasses = node.getUserProperty(WebInspector.ElementsTreeOutline.PseudoStateDecorator.PropertyName); - if (enable) { - pseudoClasses = pseudoClasses || []; - if (pseudoClasses.indexOf(pseudoClass) >= 0) - return; - pseudoClasses.push(pseudoClass); - node.setUserProperty(WebInspector.ElementsTreeOutline.PseudoStateDecorator.PropertyName, pseudoClasses); - } else { - if (!pseudoClasses || pseudoClasses.indexOf(pseudoClass) < 0) - return; - pseudoClasses.remove(pseudoClass); - if (!pseudoClasses.length) - node.removeUserProperty(WebInspector.ElementsTreeOutline.PseudoStateDecorator.PropertyName); - } - - this.treeOutline.updateOpenCloseTags(node); - WebInspector.cssModel.forcePseudoState(node.id, node.getUserProperty(WebInspector.ElementsTreeOutline.PseudoStateDecorator.PropertyName)); - this._metricsPaneEdited(); - this._stylesPaneEdited(); - - WebInspector.notifications.dispatchEventToListeners(WebInspector.UserMetrics.UserAction, { - action: WebInspector.UserMetrics.UserActionNames.ForcedElementState, - selector: node.appropriateSelectorFor(false), - enabled: enable, - state: pseudoClass - }); - }, - - _selectedNodeChanged: function() - { - var selectedNode = this.selectedDOMNode(); - if (!selectedNode && this._lastValidSelectedNode) - this._selectedPathOnReset = this._lastValidSelectedNode.path(); - - this.updateBreadcrumb(false); - - this._updateSidebars(); - - if (selectedNode) { - //ConsoleAgent.addInspectedNode(selectedNode.id); - this._lastValidSelectedNode = selectedNode; - } - WebInspector.notifications.dispatchEventToListeners(WebInspector.ElementsTreeOutline.Events.SelectedNodeChanged); - }, - - _updateSidebars: function() - { - for (var pane in this.sidebarPanes) - this.sidebarPanes[pane].needsUpdate = true; - - this.updateInstance(); - this.updateEventListeners(); - }, - - _reset: function() - { - delete this.currentQuery; - }, - - _documentUpdatedEvent: function(event) - { - this._documentUpdated(event.data); - }, - - _documentUpdated: function(inspectedRootDocument) - { - this._reset(); - this.searchCanceled(); - - this.treeOutline.rootDOMNode = inspectedRootDocument; - - if (!inspectedRootDocument) { - if (this.isShowing()) - WebInspector.domAgent.requestDocument(); - return; - } - - function selectNode(candidateFocusNode) - { - if (!candidateFocusNode) - candidateFocusNode = inspectedRootDocument; - - if (!candidateFocusNode) - return; - - this.selectDOMNode(candidateFocusNode, true); - if (this.treeOutline.selectedTreeElement) - this.treeOutline.selectedTreeElement.expand(); - } - - function selectLastSelectedNode(nodeId) - { - if (this.selectedDOMNode()) { - // Focused node has been explicitly set while reaching out for the last selected node. - return; - } - var node = nodeId ? WebInspector.domAgent.nodeForId(nodeId) : null; - selectNode.call(this, node); - } - - if (this._selectedPathOnReset) - WebInspector.domAgent.pushNodeByPathToFrontend(this._selectedPathOnReset, selectLastSelectedNode.bind(this)); - else - selectNode.call(this); - delete this._selectedPathOnReset; - }, - - searchCanceled: function() - { - delete this._searchQuery; - this._hideSearchHighlights(); - - delete this._currentSearchResultIndex; - delete this._searchResults; - WebInspector.domAgent.cancelSearch(); - }, - - performSearch: function(query, shouldJump) - { - // Call searchCanceled since it will reset everything we need before doing a new search. - this.searchCanceled(); - - const whitespaceTrimmedQuery = query.trim(); - if (!whitespaceTrimmedQuery.length) - return; - - this._searchQuery = query; - - function resultCountCallback(resultCount) - { - if (!resultCount) - return; - - this._searchResults = new Array(resultCount); - this._currentSearchResultIndex = -1; - if (shouldJump) - this.jumpToNextSearchResult(); - } - WebInspector.domAgent.performSearch(whitespaceTrimmedQuery, resultCountCallback.bind(this)); - }, - - _contextMenuEventFired: function(event) - { - function toggleWordWrap() - { - WebInspector.settings.domWordWrap.set(!WebInspector.settings.domWordWrap.get()); - } - - var contextMenu = new WebInspector.ContextMenu(event); - // Disabled - contextMenu.appendCheckboxItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Word wrap" : "Word Wrap"), toggleWordWrap.bind(this), WebInspector.settings.domWordWrap.get()); - - contextMenu.show(); - }, - - _showNamedFlowCollections: function() - { - if (!WebInspector.cssNamedFlowCollectionsView) - WebInspector.cssNamedFlowCollectionsView = new WebInspector.CSSNamedFlowCollectionsView(); - WebInspector.cssNamedFlowCollectionsView.showInDrawer(); - }, - - _domWordWrapSettingChanged: function(event) - { - if (event.data) - this.contentElement.removeStyleClass("nowrap"); - else - this.contentElement.addStyleClass("nowrap"); - - var selectedNode = this.selectedDOMNode(); - if (!selectedNode) - return; - - var treeElement = this.treeOutline.findTreeElement(selectedNode); - if (treeElement) - treeElement.updateSelection(); // Recalculate selection highlight dimensions. - }, - - switchToAndFocus: function(node) - { - // Reset search restore. - WebInspector.searchController.cancelSearch(); - WebInspector.inspectorView.setCurrentPanel(this); - this.selectDOMNode(node, true); - }, - - _populateContextMenu: function(contextMenu, node) - { - // Add debbuging-related actions - contextMenu.appendSeparator(); - var pane = WebInspector.domBreakpointsSidebarPane; - pane.populateNodeContextMenu(node, contextMenu); - }, - - _getPopoverAnchor: function(element) - { - var anchor = element.enclosingNodeOrSelfWithClass("webkit-html-resource-link"); - if (anchor) { - if (!anchor.href) - return null; - // Disabled image loading - } - return anchor; - }, - - _loadDimensionsForNode: function(treeElement, callback) - { - // We get here for CSS properties, too, so bail out early for non-DOM treeElements. - if (treeElement.treeOutline !== this.treeOutline) { - callback(); - return; - } - - var node = (treeElement.representedObject); - - if (!node.nodeName() || node.nodeName().toLowerCase() !== "img") { - callback(); - return; - } - - WebInspector.RemoteObject.resolveNode(node, "", resolvedNode); - - function resolvedNode(object) - { - if (!object) { - callback(); - return; - } - - object.callFunctionJSON(dimensions, undefined, callback); - object.release(); - - function dimensions() - { - return { offsetWidth: this.offsetWidth, offsetHeight: this.offsetHeight, naturalWidth: this.naturalWidth, naturalHeight: this.naturalHeight }; - } - } - }, - - _showPopover: function(anchor, popover) - { - var listItem = anchor.enclosingNodeOrSelfWithNodeName("li"); - if (listItem && listItem.treeElement) - this._loadDimensionsForNode(listItem.treeElement, WebInspector.DOMPresentationUtils.buildImagePreviewContents.bind(WebInspector.DOMPresentationUtils, anchor.href, true, showPopover)); - else - WebInspector.DOMPresentationUtils.buildImagePreviewContents(anchor.href, true, showPopover); - - function showPopover(contents) - { - if (!contents) - return; - popover.setCanShrink(false); - popover.show(contents, anchor); - } - }, - - jumpToNextSearchResult: function() - { - if (!this._searchResults) - return; - - this._hideSearchHighlights(); - if (++this._currentSearchResultIndex >= this._searchResults.length) - this._currentSearchResultIndex = 0; - - this._highlightCurrentSearchResult(); - }, - - jumpToPreviousSearchResult: function() - { - if (!this._searchResults) - return; - - this._hideSearchHighlights(); - if (--this._currentSearchResultIndex < 0) - this._currentSearchResultIndex = (this._searchResults.length - 1); - - this._highlightCurrentSearchResult(); - }, - - _highlightCurrentSearchResult: function() - { - var index = this._currentSearchResultIndex; - var searchResults = this._searchResults; - var searchResult = searchResults[index]; - - if (searchResult === null) { - WebInspector.searchController.updateCurrentMatchIndex(index, this); - return; - } - - if (typeof searchResult === "undefined") { - // No data for slot, request it. - function callback(node) - { - searchResults[index] = node || null; - this._highlightCurrentSearchResult(); - } - WebInspector.domAgent.searchResult(index, callback.bind(this)); - return; - } - - WebInspector.searchController.updateCurrentMatchIndex(index, this); - - var treeElement = this.treeOutline.findTreeElement(searchResult); - if (treeElement) { - treeElement.highlightSearchResults(this._searchQuery); - treeElement.reveal(); - var matches = treeElement.listItemElement.getElementsByClassName("highlighted-search-result"); - if (matches.length) - matches[0].scrollIntoViewIfNeeded(); - } - }, - - _hideSearchHighlights: function() - { - if (!this._searchResults) - return; - var searchResult = this._searchResults[this._currentSearchResultIndex]; - if (!searchResult) - return; - var treeElement = this.treeOutline.findTreeElement(searchResult); - if (treeElement) - treeElement.hideSearchHighlights(); - }, - - selectedDOMNode: function() - { - return this.treeOutline.selectedDOMNode(); - }, - - selectDOMNode: function(node, focus) - { - this.treeOutline.selectDOMNode(node, focus); - }, - - _updateBreadcrumbIfNeeded: function(event) - { - var nodes = (event.data || []); - if (!nodes.length) - return; - - var crumbs = this.crumbsElement; - for (var crumb = crumbs.firstChild; crumb; crumb = crumb.nextSibling) { - if (nodes.indexOf(crumb.representedObject) !== -1) { - this.updateBreadcrumb(true); - return; - } - } - }, - - - _mouseMovedInCrumbs: function(event) - { - var nodeUnderMouse = document.elementFromPoint(event.pageX, event.pageY); - var crumbElement = nodeUnderMouse.enclosingNodeOrSelfWithClass("crumb"); - - WebInspector.domAgent.highlightDOMNode(crumbElement ? crumbElement.representedObject.id : 0); - - if ("_mouseOutOfCrumbsTimeout" in this) { - clearTimeout(this._mouseOutOfCrumbsTimeout); - delete this._mouseOutOfCrumbsTimeout; - } - }, - - _mouseMovedOutOfCrumbs: function(event) - { - var nodeUnderMouse = document.elementFromPoint(event.pageX, event.pageY); - if (nodeUnderMouse && nodeUnderMouse.isDescendant(this.crumbsElement)) - return; - - WebInspector.domAgent.hideDOMNodeHighlight(); - - this._mouseOutOfCrumbsTimeout = setTimeout(this.updateBreadcrumbSizes.bind(this), 1000); - }, - - updateBreadcrumb: function(forceUpdate) - { - if (!this.isShowing()) - return; - - var crumbs = this.crumbsElement; - - var handled = false; - var crumb = crumbs.firstChild; - while (crumb) { - if (crumb.representedObject === this.selectedDOMNode()) { - crumb.addStyleClass("selected"); - handled = true; - } else { - crumb.removeStyleClass("selected"); - } - - crumb = crumb.nextSibling; - } - - if (handled && !forceUpdate) { - // We don't need to rebuild the crumbs, but we need to adjust sizes - // to reflect the new focused or root node. - this.updateBreadcrumbSizes(); - return; - } - - crumbs.removeChildren(); - - var panel = this; - - function selectCrumbFunction(event) - { - var crumb = event.currentTarget; - if (crumb.hasStyleClass("collapsed")) { - // Clicking a collapsed crumb will expose the hidden crumbs. - if (crumb === panel.crumbsElement.firstChild) { - // If the focused crumb is the first child, pick the farthest crumb - // that is still hidden. This allows the user to expose every crumb. - var currentCrumb = crumb; - while (currentCrumb) { - var hidden = currentCrumb.hasStyleClass("hidden"); - var collapsed = currentCrumb.hasStyleClass("collapsed"); - if (!hidden && !collapsed) - break; - crumb = currentCrumb; - currentCrumb = currentCrumb.nextSibling; - } - } - - panel.updateBreadcrumbSizes(crumb); - } else - panel.selectDOMNode(crumb.representedObject, true); - - event.preventDefault(); - } - - function getOwner(node) { - // If this node doesn't have an owner, try the parent's owner. - // This can happen for text nodes. - return current.ownerNode || (current.parentNode && current.parentNode.ownerNode); - } - - for (var current = this.selectedDOMNode(); current; current = getOwner(current)) { - if (current.nodeType() === Node.DOCUMENT_NODE) - continue; - - crumb = document.createElement("span"); - crumb.className = "crumb"; - crumb.representedObject = current; - crumb.addEventListener("mousedown", selectCrumbFunction, false); - - var crumbTitle = ""; - switch (current.nodeType()) { - case Node.ELEMENT_NODE: - if (current.pseudoType()) - crumbTitle = "::" + current.pseudoType(); - else - this.decorateNodeLabel(current, crumb); - break; - - case Node.TEXT_NODE: - crumbTitle = WebInspector.UIString("(text)"); - break; - - case Node.COMMENT_NODE: - crumbTitle = ""; - break; - - case Node.DOCUMENT_TYPE_NODE: - crumbTitle = ""; - break; - - default: - crumbTitle = current.nodeNameInCorrectCase(); - } - - if (!crumb.childNodes.length) { - var nameElement = document.createElement("span"); - nameElement.textContent = crumbTitle; - crumb.appendChild(nameElement); - crumb.title = crumbTitle; - } - - if (current === this.selectedDOMNode()) - crumb.addStyleClass("selected"); - if (!crumbs.childNodes.length) - crumb.addStyleClass("end"); - - crumbs.insertBefore(crumb, crumbs.firstChild); - } - - if (crumbs.hasChildNodes()) - crumbs.lastChild.addStyleClass("start"); - - this.updateBreadcrumbSizes(); - }, - - updateBreadcrumbSizes: function(focusedCrumb) - { - if (!this.isShowing()) - return; - - if (document.body.offsetWidth <= 0) { - // The stylesheet hasn't loaded yet or the window is closed, - // so we can't calculate what is need. Return early. - return; - } - - var crumbs = this.crumbsElement; - if (!crumbs.childNodes.length || crumbs.offsetWidth <= 0) - return; // No crumbs, do nothing. - - // A Zero index is the right most child crumb in the breadcrumb. - var selectedIndex = 0; - var focusedIndex = 0; - var selectedCrumb; - - var i = 0; - var crumb = crumbs.firstChild; - while (crumb) { - // Find the selected crumb and index. - if (!selectedCrumb && crumb.hasStyleClass("selected")) { - selectedCrumb = crumb; - selectedIndex = i; - } - - // Find the focused crumb index. - if (crumb === focusedCrumb) - focusedIndex = i; - - // Remove any styles that affect size before - // deciding to shorten any crumbs. - if (crumb !== crumbs.lastChild) - crumb.removeStyleClass("start"); - if (crumb !== crumbs.firstChild) - crumb.removeStyleClass("end"); - - crumb.removeStyleClass("compact"); - crumb.removeStyleClass("collapsed"); - crumb.removeStyleClass("hidden"); - - crumb = crumb.nextSibling; - ++i; - } - - // Restore the start and end crumb classes in case they got removed in coalesceCollapsedCrumbs(). - // The order of the crumbs in the document is opposite of the visual order. - crumbs.firstChild.addStyleClass("end"); - crumbs.lastChild.addStyleClass("start"); - - var contentElement = this.contentElement; - function crumbsAreSmallerThanContainer() - { - const rightPadding = 10; - return crumbs.offsetWidth + rightPadding < contentElement.offsetWidth; - } - - if (crumbsAreSmallerThanContainer()) - return; // No need to compact the crumbs, they all fit at full size. - - var BothSides = 0; - var AncestorSide = -1; - var ChildSide = 1; - - function makeCrumbsSmaller(shrinkingFunction, direction, significantCrumb) - { - if (!significantCrumb) - significantCrumb = (focusedCrumb || selectedCrumb); - - if (significantCrumb === selectedCrumb) - var significantIndex = selectedIndex; - else if (significantCrumb === focusedCrumb) - var significantIndex = focusedIndex; - else { - var significantIndex = 0; - for (var i = 0; i < crumbs.childNodes.length; ++i) { - if (crumbs.childNodes[i] === significantCrumb) { - significantIndex = i; - break; - } - } - } - - function shrinkCrumbAtIndex(index) - { - var shrinkCrumb = crumbs.childNodes[index]; - if (shrinkCrumb && shrinkCrumb !== significantCrumb) - shrinkingFunction(shrinkCrumb); - if (crumbsAreSmallerThanContainer()) - return true; // No need to compact the crumbs more. - return false; - } - - // Shrink crumbs one at a time by applying the shrinkingFunction until the crumbs - // fit in the container or we run out of crumbs to shrink. - if (direction) { - // Crumbs are shrunk on only one side (based on direction) of the signifcant crumb. - var index = (direction > 0 ? 0 : crumbs.childNodes.length - 1); - while (index !== significantIndex) { - if (shrinkCrumbAtIndex(index)) - return true; - index += (direction > 0 ? 1 : -1); - } - } else { - // Crumbs are shrunk in order of descending distance from the signifcant crumb, - // with a tie going to child crumbs. - var startIndex = 0; - var endIndex = crumbs.childNodes.length - 1; - while (startIndex != significantIndex || endIndex != significantIndex) { - var startDistance = significantIndex - startIndex; - var endDistance = endIndex - significantIndex; - if (startDistance >= endDistance) - var index = startIndex++; - else - var index = endIndex--; - if (shrinkCrumbAtIndex(index)) - return true; - } - } - - // We are not small enough yet, return false so the caller knows. - return false; - } - - function coalesceCollapsedCrumbs() - { - var crumb = crumbs.firstChild; - var collapsedRun = false; - var newStartNeeded = false; - var newEndNeeded = false; - while (crumb) { - var hidden = crumb.hasStyleClass("hidden"); - if (!hidden) { - var collapsed = crumb.hasStyleClass("collapsed"); - if (collapsedRun && collapsed) { - crumb.addStyleClass("hidden"); - crumb.removeStyleClass("compact"); - crumb.removeStyleClass("collapsed"); - - if (crumb.hasStyleClass("start")) { - crumb.removeStyleClass("start"); - newStartNeeded = true; - } - - if (crumb.hasStyleClass("end")) { - crumb.removeStyleClass("end"); - newEndNeeded = true; - } - - continue; - } - - collapsedRun = collapsed; - - if (newEndNeeded) { - newEndNeeded = false; - crumb.addStyleClass("end"); - } - } else - collapsedRun = true; - crumb = crumb.nextSibling; - } - - if (newStartNeeded) { - crumb = crumbs.lastChild; - while (crumb) { - if (!crumb.hasStyleClass("hidden")) { - crumb.addStyleClass("start"); - break; - } - crumb = crumb.previousSibling; - } - } - } - - function compact(crumb) - { - if (crumb.hasStyleClass("hidden")) - return; - crumb.addStyleClass("compact"); - } - - function collapse(crumb, dontCoalesce) - { - if (crumb.hasStyleClass("hidden")) - return; - crumb.addStyleClass("collapsed"); - crumb.removeStyleClass("compact"); - if (!dontCoalesce) - coalesceCollapsedCrumbs(); - } - - if (!focusedCrumb) { - // When not focused on a crumb we can be biased and collapse less important - // crumbs that the user might not care much about. - - // Compact child crumbs. - if (makeCrumbsSmaller(compact, ChildSide)) - return; - - // Collapse child crumbs. - if (makeCrumbsSmaller(collapse, ChildSide)) - return; - } - - // Compact ancestor crumbs, or from both sides if focused. - if (makeCrumbsSmaller(compact, (focusedCrumb ? BothSides : AncestorSide))) - return; - - // Collapse ancestor crumbs, or from both sides if focused. - if (makeCrumbsSmaller(collapse, (focusedCrumb ? BothSides : AncestorSide))) - return; - - if (!selectedCrumb) - return; - - // Compact the selected crumb. - compact(selectedCrumb); - if (crumbsAreSmallerThanContainer()) - return; - - // Collapse the selected crumb as a last resort. Pass true to prevent coalescing. - collapse(selectedCrumb, true); - }, - - updateInstance: function() - { - var node = this.selectedDOMNode(); - if (!node) return; - WebInspector.RemoteObject.resolveNode(node, 'react_panel_instance', nodeResolved.bind(this)); - function nodeResolved(object) - { - var pane = this.sidebarPanes.instance; - if (pane.isShowing() && pane.needsUpdate) { - pane.update(object); - } - if (object) { - object.getOwnProperties(propertiesResolved.bind(this)); - } - } - - function propertiesResolved(properties) { - var props = WebInspector.RemoteObject.fromPrimitiveValue(null); - var state = WebInspector.RemoteObject.fromPrimitiveValue(null); - for (var i = 0; i < properties.length; ++i) { - if (properties[i].name == 'props') { - props = properties[i].value; - } - if (properties[i].name == 'state') { - state = properties[i].value; - } - } - var pane = this.sidebarPanes.props; - if (pane.isShowing() && pane.needsUpdate) { - pane.update(props); - } - pane = this.sidebarPanes.state; - if (pane.isShowing() && pane.needsUpdate) { - pane.update(state); - } - } - }, - - updateEventListeners: function() - { - var eventListenersSidebarPane = this.sidebarPanes.eventListeners; - if (!eventListenersSidebarPane.isShowing() || !eventListenersSidebarPane.needsUpdate) - return; - - eventListenersSidebarPane.update(this.selectedDOMNode()); - eventListenersSidebarPane.needsUpdate = false; - }, - - handleShortcut: function(event) - { - function handleUndoRedo() - { - if (WebInspector.KeyboardShortcut.eventHasCtrlOrMeta(event) && !event.shiftKey && event.keyIdentifier === "U+005A") { // Z key - WebInspector.domAgent.undo(this._updateSidebars.bind(this)); - event.handled = true; - return; - } - - var isRedoKey = WebInspector.isMac() ? event.metaKey && event.shiftKey && event.keyIdentifier === "U+005A" : // Z key - event.ctrlKey && event.keyIdentifier === "U+0059"; // Y key - if (isRedoKey) { - DOMAgent.redo(this._updateSidebars.bind(this)); - event.handled = true; - } - } - - if (!this.treeOutline.editing()) { - handleUndoRedo.call(this); - if (event.handled) - return; - } - - this.treeOutline.handleShortcut(event); - }, - - handleCopyEvent: function(event) - { - // Don't prevent the normal copy if the user has a selection. - if (!window.getSelection().isCollapsed) - return; - event.clipboardData.clearData(); - event.preventDefault(); - this.selectedDOMNode().copyNode(); - }, - - sidebarResized: function(event) - { - this.treeOutline.updateSelection(); - }, - - _inspectElementRequested: function(event) - { - var node = event.data; - this.revealAndSelectNode(node.id); - }, - - revealAndSelectNode: function(nodeId) - { - // WebInspector.inspectorView.setCurrentPanel(this); - - var node = WebInspector.domAgent.nodeForId(nodeId); - if (!node) - return; - - WebInspector.domAgent.highlightDOMNodeForTwoSeconds(nodeId); - this.selectDOMNode(node, true); - }, - - appendApplicableItems: function(event, contextMenu, target) - { - function selectNode(nodeId) - { - if (nodeId) - WebInspector.domAgent.inspectElement(nodeId); - } - - function revealElement(remoteObject) - { - remoteObject.pushNodeToFrontend(selectNode); - } - - var commandCallback; - if (target instanceof WebInspector.RemoteObject) { - var remoteObject = (target); - if (remoteObject.subtype === "node") - commandCallback = revealElement.bind(this, remoteObject); - } else if (target instanceof WebInspector.DOMNode) { - var domNode = (target); - if (domNode.id) - commandCallback = WebInspector.domAgent.inspectElement.bind(WebInspector.domAgent, domNode.id); - } - if (!commandCallback) - return; - // Skip adding "Reveal..." menu item for our own tree outline. - if (this.treeOutline.element.isAncestor(event.target)) - return; - contextMenu.appendItem(WebInspector.useLowerCaseMenuTitles() ? "Reveal in Elements panel" : "Reveal in Elements Panel", commandCallback); - }, - - _sidebarContextMenuEventFired: function(event) - { - var contextMenu = new WebInspector.ContextMenu(event); - contextMenu.show(); - }, - - _dockSideChanged: function() - { - var vertically = false; - this._splitVertically(vertically); - }, - - _splitVertically: function(vertically) - { - if (this.sidebarPaneView && vertically === !this.splitView.isVertical()) - return; - - if (this.sidebarPaneView) - this.sidebarPaneView.detach(); - - this.splitView.setVertical(!vertically); - - if (!vertically) { - this.sidebarPaneView = new WebInspector.SidebarPaneStack(); - } else { - this.sidebarPaneView = new WebInspector.SidebarTabbedPane(); - } - for (var pane in this.sidebarPanes) - this.sidebarPaneView.addPane(this.sidebarPanes[pane]); - this.sidebarPaneView.show(this.splitView.sidebarElement); - }, - - forceUpdate: function() - { - var node = this.selectedDOMNode(); - if (!node) return; - WebInspector.RemoteObject.resolveNode(node, 'react_panel_instance', nodeResolved.bind(this)); - function nodeResolved(object) - { - function forceUpdate() { - if (this.forceUpdate) { - this.forceUpdate(); - } - } - - if (object) { - object.callFunction(forceUpdate); - } - } - }, - - __proto__: WebInspector.View.prototype -} diff --git a/views/components/WebInspectorPatch.js b/views/components/WebInspectorPatch.js deleted file mode 100644 index 5efab1a1c6..0000000000 --- a/views/components/WebInspectorPatch.js +++ /dev/null @@ -1,131 +0,0 @@ -/** - * Copyright (c) 2013-2014, Facebook, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * * Neither the name Facebook nor the names of its contributors may be used to - * endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -// Prevent initialization - -window.removeEventListener("DOMContentLoaded", windowLoaded, false); - -// Hook up click handler - -document.addEventListener("click", function(event) { - var anchor = event.target.enclosingNodeOrSelfWithNodeName("a"); - if (!anchor || (anchor.target === "_blank")) - return; - - // Prevent the link from navigating, since we don't do any navigation by following links normally. - event.consume(true); - - function followLink() { - if (WebInspector.isBeingEdited(event.target)) { - return; - } - - // Dispatch through main app - chrome.devtools.panels.openResource(anchor.href, anchor.lineNumber); - } - - if (WebInspector.followLinkTimeout) - clearTimeout(WebInspector.followLinkTimeout); - - if (anchor.preventFollowOnDoubleClick) { - // Start a timeout if this is the first click, if the timeout is canceled - // before it fires, then a double clicked happened or another link was clicked. - if (event.detail === 1) - WebInspector.followLinkTimeout = setTimeout(followLink, 333); - return; - } - - followLink(); -}, false); - -// Monkey patch some url resolution - -WebInspector.Linkifier.prototype.linkifyLocation = - function(sourceURL, lineNumber, columnNumber, classes) { - return WebInspector.linkifyResourceAsNode(sourceURL, lineNumber, classes); - }; - -WebInspector.Linkifier.prototype.linkifyRawLocation = - function(rawLocation, classes) { - return WebInspector.linkifyURLAsNode("", "", classes, false); - return anchor; - }; - -WebInspector.resourceForURL = function() { - return null; -}; - -WebInspector.workspace = { - uiSourceCodeForURL: function() { return null; } -}; - -function importScript(name) { - // Noop, we can't do synchronous fetching + eval in a chrome extension. - // Assume all scripts are already on the page. To figure out which ones you - // might be missing, console.log(name); - return; -} - -loadScript = importScript; - -debugCSS = true; // Make url() expressions resolves to the relative path - -WebInspector.View.prototype._registerRequiredCSS = - WebInspector.View.prototype.registerRequiredCSS; -WebInspector.View.prototype.registerRequiredCSS = function(cssFile) { - this._registerRequiredCSS('../blink/Source/devtools/front_end/' + cssFile); -}; - -WebInspector.debuggerModel = { - selectedCallFrame: function() {} -}; - -// Monkey patch DOM node constructor to allow custom extensions to the payload - -WebInspector._DOMNode = WebInspector.DOMNode; -WebInspector.DOMNode = function(domAgent, doc, isInShadowTree, payload) { - WebInspector._DOMNode.apply(this, arguments); - if (payload.ownerId) { - this.ownerNode = domAgent._idToDOMNode[payload.ownerId]; - } - this.isStateful = !!payload.stateful; -}; - -WebInspector.DOMNode.prototype = WebInspector._DOMNode.prototype; -WebInspector.DOMNode.prototype.constructor = WebInspector.DOMNode; - -for (var key in WebInspector._DOMNode) { - if (WebInspector._DOMNode.hasOwnProperty(key)) { - WebInspector.DOMNode[key] = WebInspector._DOMNode[key]; - } -} - -WebInspector.DOMNode.prototype.nodeNameInCorrectCase = - WebInspector.DOMNode.prototype.nodeName; diff --git a/views/devpanel.html b/views/devpanel.html deleted file mode 100644 index 92cc171a43..0000000000 --- a/views/devpanel.html +++ /dev/null @@ -1,93 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
-
- - - diff --git a/views/devpanel.js b/views/devpanel.js deleted file mode 100644 index 5c3898fc7b..0000000000 --- a/views/devpanel.js +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Copyright (c) 2013-2014, Facebook, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * * Neither the name Facebook nor the names of its contributors may be used to - * endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -var DOMAgent; -var RuntimeAgent; -var InspectorBackend; - -function initialize(agents) { - - DOMAgent = agents.DOMAgent; - RuntimeAgent = agents.RuntimeAgent; - InspectorBackend = agents.InspectorBackend; - - WebInspector.domAgent = new WebInspector.DOMAgent(); - WebInspector.runtimeModel = new WebInspector.RuntimeModel({ - addEventListener: function(){} - }); - WebInspector.installPortStyles(); - - var panel = new ReactPanel(); - panel.markAsRoot(); - panel.show(document.getElementById('main-panel-holder')); - - WebInspector.inspectorView = panel; - - WebInspector.domAgent.addEventListener( - WebInspector.DOMAgent.Events.InspectNodeRequested, - function(event) { - panel.revealAndSelectNode(event.data); - } - ); - -} \ No newline at end of file