diff --git a/.babelrc b/.babelrc deleted file mode 100644 index 070570723d..0000000000 --- a/.babelrc +++ /dev/null @@ -1,18 +0,0 @@ -{ "plugins": [ - "transform-es2015-block-scoping", - "transform-es2015-destructuring", - "transform-es2015-parameters", - "transform-es2015-spread", - "transform-flow-strip-types", - "transform-async-to-generator", - - ["module-resolver", { - "root": [ - "./packages/devtools-local-toolbox/src", - ], - "alias": { - "devtools/client/shared/vendor/react": "react", - "devtools/client/shared/vendor/react-dom": "react-dom" - } - }] -]} diff --git a/.editorconfig b/.editorconfig deleted file mode 100644 index 9099689136..0000000000 --- a/.editorconfig +++ /dev/null @@ -1,11 +0,0 @@ -# http://editorconfig.org - -root = true - -[*] -charset = utf-8 -indent_style = space -indent_size = 2 -end_of_line = lf -insert_final_newline = true -trim_trailing_whitespace = true diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 8cc2ec2de5..0000000000 --- a/.eslintignore +++ /dev/null @@ -1,9 +0,0 @@ -assets/* -src/test/examples/** -src/test/integration/** -src/test/unit-sources/** -src/test/mochitest/head.js -src/test/mochitest/examples/** -webpack.config.* -bin/ - diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index a34ba5669b..0000000000 --- a/.eslintrc +++ /dev/null @@ -1,450 +0,0 @@ -{ - "parser": "babel-eslint", - "plugins": [ - "react", - "mozilla", - "flowtype", - "babel" - ], - "globals": { - "atob": true, - "btoa": true, - "Cc": true, - "Ci": true, - "Components": true, - "console": true, - "Cr": true, - "Cu": true, - "devtools": true, - "dump": true, - "EventEmitter": true, - "exports": true, - "isWorker": true, - "loader": true, - "module": true, - "reportError": true, - "require": true, - "Services": true, - "Task": true, - "XPCNativeWrapper": true, - "XPCOMUtils": true, - "_Iterator": true, - "__dirname": true, - "process": true, - "expect": true, - "global": true, - "L10N": true - }, - "env": { - "es6": true, - "browser": true, - "mocha": true - }, - "rules": { - // These are the rules that have been configured so far to match the - // devtools coding style. - - // Rules from the mozilla plugin - "mozilla/mark-test-function-used": 1, - "mozilla/no-aArgs": 1, - // See bug 1224289. - "mozilla/reject-importGlobalProperties": 1, - "mozilla/var-only-at-top-level": 1, - - // Rules from the React plugin - "react/display-name": [2, { "ignoreTranspilerName": true }], - "react/no-danger": 1, - "react/no-did-mount-set-state": 1, - "react/no-did-update-set-state": 1, - "react/no-direct-mutation-state": 1, - "react/no-unknown-property": 1, - "react/prefer-es6-class": [1, "never"], - "react/prop-types": 1, - "react/sort-comp": [1, { - order: [ - "propTypes", - "everything-else", - "render" - ] - }], - - // Enforce the spacing around the * in generator functions. - "babel/generator-star-spacing": [2, "after"], - - "flowtype/define-flow-type": 1, - "flowtype/use-flow-type": 1, - - // Disallow using variables outside the blocks they are defined (especially - // since only let and const are used, see "no-var"). - "block-scoped-var": 2, - // Enforce one true brace style (opening brace on the same line) and avoid - // start and end braces on the same line. - "brace-style": [2, "1tbs", {"allowSingleLine": false}], - // Require camel case names - "camelcase": 2, - // Allow trailing commas for easy list extension. Having them does not - // impair readability, but also not required either. - "comma-dangle": 0, - // Enforce spacing before and after comma - "comma-spacing": [2, {"before": false, "after": true}], - // Enforce one true comma style. - "comma-style": [2, "last"], - // Warn about cyclomatic complexity in functions. - "complexity": 2, - // Don't warn for inconsistent naming when capturing this (not so important - // with auto-binding fat arrow functions). - "consistent-this": 0, - // Enforce curly brace conventions for all control statements. - "curly": 2, - // Don't require a default case in switch statements. Avoid being forced to - // add a bogus default when you know all possible cases are handled. - "default-case": 0, - // Enforce dots on the next line with property name. - "dot-location": [2, "property"], - // Encourage the use of dot notation whenever possible. - "dot-notation": 2, - // Enforce newline at the end of file, with no multiple empty lines. - "eol-last": 2, - // Allow using == instead of ===, in the interest of landing something since - // the devtools codebase is split on convention here. - "eqeqeq": 0, - // Don't require function expressions to have a name. - // This makes the code more verbose and hard to read. Our engine already - // does a fantastic job assigning a name to the function, which includes - // the enclosing function name, and worst case you have a line number that - // you can just look up. - "func-names": 0, - // Allow use of function declarations and expressions. - "func-style": 0, - // Deprecated, will be removed in 1.0. - "generator-star": 0, - // Deprecated, will be removed in 1.0. - "global-strict": 0, - // Only useful in a node environment. - "handle-callback-err": 0, - // Tab width. - "indent": [2, 2, {"SwitchCase": 1}], - // Enforces spacing between keys and values in object literal properties. - "key-spacing": [2, {"beforeColon": false, "afterColon": true}], - // Allow mixed 'LF' and 'CRLF' as linebreaks. - "linebreak-style": 0, - // Don't enforce the maximum depth that blocks can be nested. The complexity - // rule is a better rule to check this. - "max-depth": 0, - // Maximum length of a line. - "max-len": [2, 80, 2, {"ignoreUrls": true, "ignorePattern": "\\s*require\\s*\\(|^\\s*loader\\.lazy|-\\*-"}], - // Maximum depth callbacks can be nested. - "max-nested-callbacks": [2, 3], - // Don't limit the number of parameters that can be used in a function. - "max-params": 0, - // Don't limit the maximum number of statement allowed in a function. We - // already have the complexity rule that's a better measurement. - "max-statements": 0, - // Require a capital letter for constructors, only check if all new - // operators are followed by a capital letter. Don't warn when capitalized - // functions are used without the new operator. - "new-cap": [2, {"capIsNew": false}], - // Disallow the omission of parentheses when invoking a constructor with no - // arguments. - "new-parens": 2, - // Disallow use of the Array constructor. - "no-array-constructor": 2, - // Allow use of bitwise operators. - "no-bitwise": 0, - // Disallow use of arguments.caller or arguments.callee. - "no-caller": 2, - // Disallow the catch clause parameter name being the same as a variable in - // the outer scope, to avoid confusion. - "no-catch-shadow": 2, - // Deprecated, will be removed in 1.0. - "no-comma-dangle": 0, - // Disallow assignment in conditional expressions. - "no-cond-assign": 2, - // Allow using the console API. - "no-console": 0, - // Allow using constant expressions in conditions like while (true) - "no-constant-condition": 0, - // Allow use of the continue statement. - "no-continue": 0, - // Disallow control characters in regular expressions. - "no-control-regex": 2, - // Disallow use of debugger. - "no-debugger": 2, - // Disallow deletion of variables (deleting properties is fine). - "no-delete-var": 2, - // Allow division operators explicitly at beginning of regular expression. - "no-div-regex": 0, - // Disallow duplicate arguments in functions. - "no-dupe-args": 2, - // Disallow duplicate keys when creating object literals. - "no-dupe-keys": 2, - // Disallow a duplicate case label. - "no-duplicate-case": 2, - // Disallow else after a return in an if. The else around the second return - // here is useless: - // if (something) { return false; } else { return true; } - "no-else-return": 2, - // Disallow empty statements. This will report an error for: - // try { something(); } catch (e) {} - // but will not report it for: - // try { something(); } catch (e) { /* Silencing the error because ...*/ } - // which is a valid use case. - "no-empty": 2, - // Disallow the use of empty character classes in regular expressions. - "no-empty-character-class": 2, - // Disallow use of labels for anything other then loops and switches. - "no-labels": 2, - // Disallow use of eval(). We have other APIs to evaluate code in content. - "no-eval": 2, - // Disallow assigning to the exception in a catch block. - "no-ex-assign": 2, - // Disallow adding to native types - "no-extend-native": 2, - // Disallow unnecessary function binding. - "no-extra-bind": 2, - // Disallow double-negation boolean casts in a boolean context. - "no-extra-boolean-cast": 2, - // Allow unnecessary parentheses, as they may make the code more readable. - "no-extra-parens": 0, - // Disallow unnecessary semicolons. - "no-extra-semi": 2, - // Deprecated, will be removed in 1.0. - "no-extra-strict": 0, - // Disallow fallthrough of case statements, except if there is a comment. - "no-fallthrough": 2, - // Allow the use of leading or trailing decimal points in numeric literals. - "no-floating-decimal": 0, - // Disallow comments inline after code. - "no-inline-comments": 2, - // Disallow if as the only statement in an else block. - "no-lonely-if": 2, - // Allow mixing regular variable and require declarations (not a node env). - "no-mixed-requires": 0, - // Disallow mixed spaces and tabs for indentation. - "no-mixed-spaces-and-tabs": 2, - // Disallow use of multiple spaces (sometimes used to align const values, - // array or object items, etc.). It's hard to maintain and doesn't add that - // much benefit. - "no-multi-spaces": 2, - // Disallow use of multiline strings (use template strings instead). - "no-multi-str": 2, - "prefer-template": "error", - // Disallow multiple empty lines. - "no-multiple-empty-lines": [2, {"max": 1}], - // Disallow reassignments of native objects. - "no-native-reassign": 2, - // Disallow nested ternary expressions, they make the code hard to read. - "no-nested-ternary": 2, - // Allow use of new operator with the require function. - "no-new-require": 0, - // Disallow use of octal literals. - "no-octal": 2, - // Allow reassignment of function parameters. - "no-param-reassign": 0, - // Allow string concatenation with __dirname and __filename (not a node env). - "no-path-concat": 0, - // Allow use of unary operators, ++ and --. - "no-plusplus": 0, - // Allow using process.env (not a node environment). - "no-process-env": 0, - // Allow using process.exit (not a node environment). - "no-process-exit": 0, - // Disallow usage of __proto__ property. - "no-proto": 2, - // Disallow declaring the same variable more than once (we use let anyway). - "no-redeclare": 2, - // Disallow multiple spaces in a regular expression literal. - "no-regex-spaces": 2, - // Allow reserved words being used as object literal keys. - "no-reserved-keys": 0, - // Don't restrict usage of specified node modules (not a node environment). - "no-restricted-modules": 0, - // Disallow use of assignment in return statement. It is preferable for a - // single line of code to have only one easily predictable effect. - "no-return-assign": 2, - // Allow use of javascript: urls. - "no-script-url": 0, - // Disallow comparisons where both sides are exactly the same. - "no-self-compare": 2, - // Disallow use of comma operator. - "no-sequences": 2, - // Warn about declaration of variables already declared in the outer scope. - // This isn't an error because it sometimes is useful to use the same name - // in a small helper function rather than having to come up with another - // random name. - // Still, making this a warning can help people avoid being confused. - "no-shadow": 2, - // Disallow shadowing of names such as arguments. - "no-shadow-restricted-names": 2, - // Deprecated, will be removed in 1.0. - "no-space-before-semi": 0, - // Disallow space between function identifier and application. - "no-spaced-func": 2, - // Disallow sparse arrays, eg. let arr = [,,2]. - // Array destructuring is fine though: - // for (let [, breakpointPromise] of aPromises) - "no-sparse-arrays": 2, - // Allow use of synchronous methods (not a node environment). - "no-sync": 0, - // Allow the use of ternary operators. - "no-ternary": 0, - // Disallow throwing literals (eg. throw "error" instead of - // throw new Error("error")). - "no-throw-literal": 2, - // Disallow trailing whitespace at the end of lines. - "no-trailing-spaces": 2, - // Disallow use of undeclared variables unless mentioned in a /*global */ - // block. Note that globals from head.js are automatically imported in tests - // by the import-headjs-globals rule form the mozilla eslint plugin. - "no-undef": 2, - // Allow dangling underscores in identifiers (for privates). - "no-underscore-dangle": 0, - // Allow use of undefined variable. - "no-undefined": 0, - // Disallow the use of Boolean literals in conditional expressions. - "no-unneeded-ternary": 2, - // Disallow unreachable statements after a return, throw, continue, or break - // statement. - "no-unreachable": 2, - // Disallow global and local variables that arent used, but allow unused function arguments. - "no-unused-vars": [2, {"vars": "all", "args": "none"}], - // Allow using variables before they are defined. - "no-use-before-define": 0, - // We use var-only-at-top-level instead of no-var as we allow top level - // vars. - "no-var": 0, - // Allow using TODO/FIXME comments. - "no-warning-comments": 0, - // Disallow use of the with statement. - "no-with": 2, - "object-curly-spacing": ["error", "always", { - "objectsInObjects": false, - }], - // Dont require method and property shorthand syntax for object literals. - // We use this in the code a lot, but not consistently, and this seems more - // like something to check at code review time. - "object-shorthand": 0, - // Allow more than one variable declaration per function. - "one-var": 0, - // Disallow padding within blocks. - "padded-blocks": [2, "never"], - // Dont require quotes around object literal property names. - "quote-props": 0, - // Double quotes should be used. - "quotes": [2, "double", "avoid-escape"], - // Require use of the second argument for parseInt(). - "radix": 2, - // Always require use of semicolons wherever they are valid. - "semi": [2, "always"], - // Enforce spacing after semicolons. - "semi-spacing": [2, {"before": false, "after": true}], - // Dont require to sort variables within the same declaration block. - // Anyway, one-var is disabled. - "sort-vars": 0, - // Deprecated, will be removed in 1.0. - "space-after-function-name": 0, - // Require a space after keywords. - "keyword-spacing": 2, - // Require a space before the start brace of a block. - "space-before-blocks": [2, "always"], - // Deprecated, will be removed in 1.0. - "space-before-function-parentheses": 0, - // Disallow space before function opening parenthesis. - "space-before-function-paren": [2, "never"], - // Disable the rule that checks if spaces inside {} and [] are there or not. - // Our code is split on conventions, and itd be nice to have 2 rules - // instead, one for [] and one for {}. So, disabling until we write them. - "space-in-brackets": 0, - // Disallow spaces inside parentheses. - "space-in-parens": [2, "never"], - // Require spaces around operators, except for a|0. - "space-infix-ops": [2, {"int32Hint": true}], - // Require spaces before/after unary operators (words on by default, - // nonwords off by default). - "space-unary-ops": [2, { "words": true, "nonwords": false }], - // Deprecated, will be removed in 1.0. - "space-unary-word-ops": 0, - // Require a space immediately following the // in a line comment. - "spaced-comment": [2, "always"], - // Require "use strict" to be defined globally in the script. - "strict": [2, "global"], - // Disallow comparisons with the value NaN. - "use-isnan": 2, - // Warn about invalid JSDoc comments. - // Disabled for now because of https://github.com/eslint/eslint/issues/2270 - // The rule fails on some jsdoc comments like in: - // devtools/client/webconsole/console-output.js - "valid-jsdoc": 0, - // Ensure that the results of typeof are compared against a valid string. - "valid-typeof": 2, - // Allow vars to be declared anywhere in the scope. - "vars-on-top": 0, - // Dont require immediate function invocation to be wrapped in parentheses. - "wrap-iife": 0, - // Don't require regex literals to be wrapped in parentheses (which - // supposedly prevent them from being mistaken for division operators). - "wrap-regex": 0, - // Disallow Yoda conditions (where literal value comes first). - "yoda": 2, - - // And these are the rules that haven't been discussed so far, and that are - // disabled for now until we introduce them, one at a time. - - // Require for-in loops to have an if statement. - "guard-for-in": 0, - // allow/disallow an empty newline after var statement - "newline-after-var": 0, - // disallow the use of alert, confirm, and prompt - "no-alert": 0, - // disallow comparisons to null without a type-checking operator - "no-eq-null": 0, - // disallow overwriting functions written as function declarations - "no-func-assign": 0, - // disallow use of eval()-like methods - "no-implied-eval": 0, - // disallow function or variable declarations in nested blocks - "no-inner-declarations": 0, - // disallow invalid regular expression strings in the RegExp constructor - "no-invalid-regexp": 0, - // disallow irregular whitespace outside of strings and comments - "no-irregular-whitespace": 0, - // disallow usage of __iterator__ property - "no-iterator": 0, - // disallow labels that share a name with a variable - "no-label-var": 0, - // disallow unnecessary nested blocks - "no-lone-blocks": 0, - // disallow creation of functions within loops - "no-loop-func": 0, - // disallow negation of the left operand of an in expression - "no-negated-in-lhs": 0, - // disallow use of new operator when not part of the assignment or - // comparison - "no-new": 0, - // disallow use of new operator for Function object - "no-new-func": 0, - // disallow use of the Object constructor - "no-new-object": 0, - // disallows creating new instances of String,Number, and Boolean - "no-new-wrappers": 0, - // disallow the use of object properties of the global object (Math and - // JSON) as functions - "no-obj-calls": 0, - // disallow use of octal escape sequences in string literals, such as - // var foo = "Copyright \251"; - "no-octal-escape": 0, - // disallow use of undefined when initializing variables - "no-undef-init": 0, - // disallow usage of expressions in statement position - "no-unused-expressions": 0, - // disallow use of void operator - "no-void": 0, - // disallow wrapping of non-IIFE statements in parens - "no-wrap-func": 0, - // require assignment operator shorthand where possible or prohibit it - // entirely - "operator-assignment": 0, - // enforce operators to be placed before or after line breaks - "operator-linebreak": 0, - } -} diff --git a/.flowconfig b/.flowconfig deleted file mode 100644 index 90d0221e54..0000000000 --- a/.flowconfig +++ /dev/null @@ -1,11 +0,0 @@ -[ignore] -.*node_modules/cjson.* -.*node_modules/fbjs.* -.*node_modules/npm.* -.*node_modules/config-chain.* -.*firefox/.* -.*flow-coverage-report/.* - -[libs] -./packages/devtools-config/flow-interface.js -./src/global-types.js diff --git a/.github/PULL_REQUEST_TEMPLATE b/.github/PULL_REQUEST_TEMPLATE deleted file mode 100644 index c793648d1c..0000000000 --- a/.github/PULL_REQUEST_TEMPLATE +++ /dev/null @@ -1,23 +0,0 @@ -Associated Issue: # - -### Summary of Changes - -* change 1 -* change 2 - -### Test Plan - -Tell us a little a bit about how you tested your patch. - -Example test plan: - -- [x] Command-P opens the panel -- [x] Clicking “+” opens the panel -- [x] Clicking a source navigates to the source -- [x] Clicking "x" closes the panel - -Here's the Debugger's Testing doc -https://docs.google.com/document/d/1oBMRxV8A2ag2t22YsQOxTdEv0mXKzIg0tggJjRkU1S0/edit#. -Feel free to improve it! - -### Screenshots/Videos (OPTIONAL) diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 8a775c1eeb..0000000000 --- a/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -.DS_Store -build -node_modules -configs/local.json -npm-debug.log -.idea/ -.vscode/ -/firefox -lerna-debug.log -flow-coverage diff --git a/.stylelintignore b/.stylelintignore deleted file mode 100644 index 6039d25e2e..0000000000 --- a/.stylelintignore +++ /dev/null @@ -1,3 +0,0 @@ -src/components/SplitBox.css -src/components/reps.css -packages/devtools-local-toolbox/src/lib/themes/*.css diff --git a/.stylelintrc b/.stylelintrc deleted file mode 100644 index 05369fdaf0..0000000000 --- a/.stylelintrc +++ /dev/null @@ -1,68 +0,0 @@ -{ - "rules": { - "at-rule-empty-line-before": [ "always", { - "except": [ "blockless-group", "first-nested" ], - "ignore": ["after-comment"], - } ], - "at-rule-semicolon-newline-after": "always", - "block-closing-brace-newline-after": "always", - "block-closing-brace-newline-before": "always-multi-line", - "block-closing-brace-space-before": "always-single-line", - "block-no-empty": true, - "block-opening-brace-newline-after": "always-multi-line", - "block-opening-brace-space-after": "always-single-line", - "block-opening-brace-space-before": "always", - "color-hex-case": "lower", - "color-hex-length": "long", - "color-no-invalid-hex": true, - "declaration-bang-space-after": "never", - "declaration-bang-space-before": "always", - "declaration-block-no-ignored-properties": true, - "declaration-block-no-shorthand-property-overrides": true, - "declaration-block-semicolon-newline-after": "always-multi-line", - "declaration-block-semicolon-space-after": "always-single-line", - "declaration-block-semicolon-space-before": "never", - "declaration-block-single-line-max-declarations": 1, - "declaration-block-trailing-semicolon": "always", - "declaration-colon-newline-after": "always-multi-line", - "declaration-colon-space-after": "always-single-line", - "declaration-colon-space-before": "never", - "function-calc-no-unspaced-operator": true, - "function-comma-newline-after": "always-multi-line", - "function-comma-space-after": "always-single-line", - "function-comma-space-before": "never", - "function-linear-gradient-no-nonstandard-direction": true, - "function-parentheses-newline-inside": "always-multi-line", - "function-parentheses-space-inside": "never-single-line", - "function-whitespace-after": "always", - "indentation": 2, - "max-empty-lines": 1, - "media-feature-colon-space-after": "always", - "media-feature-colon-space-before": "never", - "media-feature-no-missing-punctuation": true, - "media-feature-range-operator-space-after": "always", - "media-feature-range-operator-space-before": "always", - "media-query-list-comma-newline-after": "always-multi-line", - "media-query-list-comma-space-after": "always-single-line", - "media-query-list-comma-space-before": "never", - "media-feature-parentheses-space-inside": "never", - "no-eol-whitespace": true, - "no-invalid-double-slash-comments": true, - "no-missing-end-of-source-newline": true, - "number-leading-zero": "always", - "number-no-trailing-zeros": true, - "rule-non-nested-empty-line-before": [ "always-multi-line", { - "ignore": ["after-comment"], - } ], - "selector-combinator-space-after": "always", - "selector-combinator-space-before": "always", - "selector-list-comma-newline-after": "always", - "selector-list-comma-space-before": "never", - "selector-pseudo-element-colon-notation": "double", - "selector-type-case": "lower", - "string-no-newline": true, - "value-list-comma-newline-after": "always-multi-line", - "value-list-comma-space-after": "always-single-line", - "value-list-comma-space-before": "never", - }, -} diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md deleted file mode 100644 index 22d0830ff0..0000000000 --- a/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,74 +0,0 @@ -# Contributor Covenant Code of Conduct - -## Our Pledge - -In the interest of fostering an open and welcoming environment, we as -contributors and maintainers pledge to making participation in our project and -our community a harassment-free experience for everyone, regardless of age, body -size, disability, ethnicity, gender identity and expression, level of experience, -nationality, personal appearance, race, religion, or sexual identity and -orientation. - -## Our Standards - -Examples of behavior that contributes to creating a positive environment -include: - -* Using welcoming and inclusive language -* Being respectful of differing viewpoints and experiences -* Gracefully accepting constructive criticism -* Focusing on what is best for the community -* Showing empathy towards other community members - -Examples of unacceptable behavior by participants include: - -* The use of sexualized language or imagery and unwelcome sexual attention or -advances -* Trolling, insulting/derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or electronic - address, without explicit permission -* Other conduct which could reasonably be considered inappropriate in a - professional setting - -## Our Responsibilities - -Project maintainers are responsible for clarifying the standards of acceptable -behavior and are expected to take appropriate and fair corrective action in -response to any instances of unacceptable behavior. - -Project maintainers have the right and responsibility to remove, edit, or -reject comments, commits, code, wiki edits, issues, and other contributions -that are not aligned to this Code of Conduct, or to ban temporarily or -permanently any contributor for other behaviors that they deem inappropriate, -threatening, offensive, or harmful. - -## Scope - -This Code of Conduct applies both within project spaces and in public spaces -when an individual is representing the project or its community. Examples of -representing a project or community include using an official project e-mail -address, posting via an official social media account, or acting as an appointed -representative at an online or offline event. Representation of a project may be -further defined and clarified by project maintainers. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported by contacting the project team at [inclusion@mozilla.com](mailto:inclusion@mozilla.com). All -complaints will be reviewed and investigated and will result in a response that -is deemed necessary and appropriate to the circumstances. The project team is -obligated to maintain confidentiality with regard to the reporter of an incident. -Further details of specific enforcement policies may be posted separately. - -Project maintainers who do not follow or enforce the Code of Conduct in good -faith may face temporary or permanent repercussions as determined by other -members of the project's leadership. - -## Attribution - -This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, -available at [http://contributor-covenant.org/version/1/4][version] - -[homepage]: http://contributor-covenant.org -[version]: http://contributor-covenant.org/version/1/4/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index 77059a936c..0000000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,389 +0,0 @@ -# Contributing to debugger.html - -:+1::tada: First off, thanks for taking the time to contribute! :tada::+1: - -We respect your time and want to help you make the most of it as you learn more about this project. - -#### Table Of Contents - -[What should I know before I get started?](#what-should-i-know-before-i-get-started) - * [debugger.html](#debuggerhtml) - * [devtools.html](#devtoolshtml) - * [Firefox Developer Tools](#firefox-developer-tools) - -[Getting Started](#getting-started) - * [Web Application](#web-application) - * [Debuggable Targets](#debuggable-targets) - * [Firefox Remote Debugging](#firefox) - * [Chrome Remote Debugging](#chrome) - * [Node.js Remote Debugging](#nodejs) - -[How Can I Contribute?](#how-can-i-contribute) - * [Reporting Bugs](#reporting-bugs-bug) - * [Suggesting Enhancements](#suggesting-enhancements-new) - * [Writing Documentation](#writing-documentation-book) - * [Writing Code](#writing-code-computer) - * [Your First Code Contribution](#your-first-code-contribution) - * [Coding Standards](#coding-standards) - * [Pull Requests](#pull-requests) - * [Hot Reloading](#hot-reloading-fire) - * [Logging](#logging) - * [Tests](#tests) - * [Unit Tests](#unit-tests) - * [Integration Tests](#integration-tests) - * [Linting](#linting) - * [Configuration](#configuration) - * [Create a local config file](#create-a-local-config-file) - * [Issues and Pull Request labels](#issues-and-pull-requests) - -## What should I know before I get started? - -The developer tools in most major browsers are just web applications. They are HTML & JS rendered by the browser and talk to the browser itself through an API that gives access to the page internals. This project is a brand new web application interface for JavaScript debugging designed for browsers and JS environments. - -We strive for collaboration with [mutual respect for each other](./CODE_OF_CONDUCT.md). Mozilla also has a set of [participation guidelines](https://www.mozilla.org/en-US/about/governance/policies/participation/) which goes into greater detail specific to Mozilla employees and contributors. - -### debugger.html - -The debugger.html project is a JavaScript debugger built from the ground up using modern web application technologies. It is designed first for debugging Firefox but also for working with projects like Chrome and Node. The name debugger.html was chosen because this debugger interface is being written using modern web technologies where as the previous Firefox debugger was written in [XUL](https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XUL). - -### devtools.html - -devtools.html is the larger umbrella initiative that encompasses the debugger.html and several other devtools projects. The devtools.html project claims its origin from a demo for a Mozilla (Dec 2015) work week in Orlando, FL USA where the team worked under a tight deadline to provide a proof of concept of the Firefox developer tools running in pure HTML; even outside of Firefox. The code for that demo can be found on GitHub under [@joewalker/devtools.html](https://github.com/joewalker/devtools.html). - -From that original demo the devtools.html project has progressed quite a bit. To learn more about it please read the [devtools.html proposal document](https://docs.google.com/document/d/1_5aerWTN_GVofr6YQVjmJlaGfZ4nv5YKZmdGHewfTpE/edit#heading=h.dw3amfbdp0lh) and take a look at the [devtools.html meta bug](https://bugzilla.mozilla.org/show_bug.cgi?id=1263750) for tracking progress. - -### Firefox Developer Tools - -The debugger.html project is targeted to land in Firefox for Firefox 52. However if you're looking to work directly on the DevTools project which ships developer tools for Firefox and Firefox Developer Edition right now you can find more information on the Mozilla wiki [DevTools / Get Involved](https://wiki.mozilla.org/DevTools/GetInvolved). - -## Getting Started - -The debugger.html is a web application that makes a [WebSocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API) connection to a debuggable target like the JavaScript engine of a web browser. The web application then interprets data and sends commands to the JS engine to manage the debugging environment; for example by creating a breakpoint or displaying that the JS engine is paused at a breakpoint. - -![debugger - web browser](https://cloud.githubusercontent.com/assets/2134/16933811/babb4eec-4d05-11e6-8c7e-f133e54b756f.png) - -### Web Application - -First we need to get the web application running. Within the source code directory, from the command line run these commands. - -### Linux or MacOs - -* `npm i -g yarn@0.16.1` - Install Yarn -* `git clone git@github.com:devtools-html/debugger.html.git` - Clone Debugger -* `yarn install` - Install dependencies. -* `yarn start` - Start development web server - -NOTE: :cat2: We use [Yarn](https://yarnpkg.com) so that we all have the same setup. - -### Windows - -It is recommended to use Git Shell which comes with [GitHub Desktop] application to emulate bash on Windows. - -* `npm i -g yarn@0.16.1` - Install Yarn -* `git clone git@github.com:devtools-html/debugger.html.git` - Clone Debugger -* `yarn install` - Install dependencies -* `yarn start` - Start development web server - -NOTE: :cat2: We use [Yarn](https://yarnpkg.com) so that we all have the same setup. - -### Open the debugger - -After `yarn start`, the debugger will be running on [http://localhost:8000](http://localhost:8000) and you can open it in any browser. [screenshot](https://cloud.githubusercontent.com/assets/254562/20393011/44ca6a8a-aca8-11e6-99f7-05f21767ae6d.png) - -### Debuggable Targets - -The following are instructions for getting Firefox, Chrome, and Node running with remote debugging turned on. Remote debugging is necessary for the debugger.html project to connect to these targets. - -#### Firefox - -The following command will automatically start a remote debuggable version of Firefox using a temporary profile and set all the necessary preferences for you. This command runs Firefox in a selenium environment that is great for quick testing. - -``` -$ yarn run firefox -``` - -When firefox is running, reload `localhost:8000` and you'll see the available firefox tabs to debug in the debugger. ![screenshot](https://cloud.githubusercontent.com/assets/254562/20393075/7e494024-aca8-11e6-8578-19a6d73be6ed.png) - -**Command line option** - -Here are the instructions for running Firefox from the command line without selenium: - -**MacOs**: - -``` -$ /Applications/Firefox.app/Contents/MacOS/firefox-bin --start-debugger-server 6080 -P development -``` - -**Windows:** - -``` -C:\Program Files (x86)\Mozilla Firefox\firefox.exe -start-debugger-server 6080 -P development -``` - -> If this command doesn't work for your OS or Firefox version see the other [Firefox commands for running in a debuggable state](./docs/remotely-debuggable-browsers.md#firefox) - -**NOTE**: The Firefox started from the `yarn run` command automatically sets the following necessary flags which you will need to do manually if you ran Firefox from the command line. - -Navigate to `about:config` and accept any warning message. Then search for the following preferences and double click them to toggle their values to the following. [example](http://g.recordit.co/3VsHIooZ9q.gif) - -* `devtools.debugger.remote-enabled` to `true` -* `devtools.chrome.enabled` to `true` -* `devtools.debugger.prompt-connection` to `false` - -Once you have Firefox running in a debuggable state go back up to instructions for restarting your development server. - -#### Chrome - -Start by running Chrome from the terminal with remote debugging turned on. - -``` -/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --remote-debugging-port=9222 --no-first-run --user-data-dir=/tmp/chrome-dev-profile http://localhost:7999/todomvc/ -``` - -* If this command doesn't work for your OS or Chrome version see the other [Chrome commands for running in a debuggable state](./docs/remotely-debuggable-browsers.md#chrome) -* NOTE: This command also creates a new _temporary_ profile - - -#### Node.js - -Debugging node requires at least node v6.3.0 and running node with the `inspect` flag turned on. Here's what running node looks like when running an example `server.js` file. - -``` -$ node --inspect server.js -``` - -With node running in _inspect mode_ go to your browser running `localhost:8000` and click **[connect to Node](http://localhost:8000/?ws=localhost:9229/node)** - -**Note:** Currently Node.js debugging is limited in some ways, there isn't support for seeing variables or the console, but you can manage breakpoints and navigate code execution (pause, step-in, step-over, etc.) in the debugger across various sources. - -## How Can I Contribute? - -Here is a great GitHub guide on [contributing to Open Source](https://guides.github.com/activities/contributing-to-open-source/) to help you get started. - -### Reporting Bugs :bug: - -If you find an issue with the code please do [file an issue](https://github.com/devtools-html/debugger.html/issues/new) and tag it with the label [bug](https://github.com/devtools-html/debugger.html/labels/bug). We'll do our best to review the issue in a timely manner and respond. - -### Suggesting Enhancements :new: - -We are actively investigating ways of support enhancement requests in the project so these instructions are subject to change. For now please create an issue, tag it with the [enhancement][labels-enhancement] label and we will attempt to respond. - -### Writing Documentation :book: - -Documentation is as important as code and we need your help to maintain clear and usable documentation. If you find an error in here or other project documentation please [file an issue](https://github.com/devtools-html/debugger.html/issues/new) and tag it with the label [docs](https://github.com/devtools-html/debugger.html/labels/docs). - -### Writing Code :computer: - -We have a number of tools to help you with your code contributions, the following describes them all and how you can make use of them. - -If you've contributed to an open source project before and would like to help this one please take a look through the `up for grabs` issues: - -* [up for grabs][labels-up-for-grabs] - issues should have clear requirements and a difficulty level set as a label - -If you find an `up for grabs` issue without a difficulty level set as a label or unclear requirements please comment in the issue so we can get that fixed. - -#### Your First Code Contribution - -If you're looking for a good issue, you can look through the `up-for-grabs` issues. These issues should be actionable and well documented. - -There are several difficulty levels, *easy*, *medium*, *hard*. We recommend grabbing an *easy* issue, but it's up to you. - -* [up-for-grabs][labels-up-for-grabs] - issues that are not assigned to anyone and are available to be worked on. -* [difficulty:easy][labels-difficulty-easy] - clear expectations and a mentor to help you through. -* [difficulty:medium][labels-difficulty-medium] - more complex and may not have as clear expectations. -* [difficulty:hard][labels-difficulty-hard] - complex and has some open technical questions. - - -To begin your work make sure you follow these steps: - -* [Fork this project](https://github.com/devtools-html/debugger.html#fork-destination-box) -* Create a branch to start your work `git checkout -b your-feature-name` -* Commit your work -* Create a [pull request](#pull-requests) - -#### Coding Standards - -> Be consistent with the rest of the code in the file - -Here are pointers to the DevTools general coding style and formatting guidelines. - -* [JS Coding Style](https://wiki.mozilla.org/DevTools/CodingStandards#Code_style) -* [Formatting Comments](https://wiki.mozilla.org/DevTools/CodingStandards#Comments) - -#### Issues - -We use issues and milestones for planning purposes as well as tracking bugs. - -**Keep Issues Relevant** - -We try to keep the number of open issues to a minimum. If work isn't going to be done in a timely manner we would rather close the issue than let them go stale. Closed issues can always be reopened again when we are ready to start the work. This process helps keep the focus of the project more understandable to others. - -**Intent to implement** - -When a person is assigned to an issue this indicates an _intent to implement_. Please ask within the issue if you would like to work on a fix so multiple people don't create pull requests for it. - -#### Pull Requests - -* Include screenshots and animated GIFs in your pull request whenever possible. -* List any steps necessary to trigger the feature you've created or bug you are fixing -* Always run the [unit tests](#unit-tests) locally before creating your PR - * The [integration tests](#integration-tests) will be run automatically by the CI or you can try running them locally as well -* Once the tests have passed in the PR you must receive a review using the GitHub review system - * To learn more about GitHub reviews take a look at their [documentation](https://help.github.com/articles/reviewing-changes-in-pull-requests/) and [video tutorial](https://youtu.be/HW0RPaJqm4g) -* Request review from @jasonLaster or @jlongster by mentioning their names in the PR - -> **Working on your first Pull Request?** You can learn how from this *free* series [How to Contribute to an Open Source Project on GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github) - -#### Hot Reloading :fire: - -Hot Reloading watches for changes in the React Components JS and CSS and propagates those changes up to the application without changing the state of the application. You want this turned on. - -To enabled Hot Reloading: - -* [Create a local config file](#create-a-local-config-file) if you don't already have one -* Edit the `config/local.json` you just created to change the value of `hotReloading` to be `true` - -```json -{ - "hotReloading": true -} -``` - -* Restart your development server by typing `ctrl+c` in the Terminal and run `yarn start` again - -Read more about [Hot Reloading](./docs/local-development.md#hot-reloading) - -### Logging - -Logging information can be very useful when developing, and there are a few logging options available to you. - -To enable logging: - -* [Create a local config file](#create-a-local-config-file) if you don't already have one -* Edit your local config, changing the value of the logger type you want to see to `true` - -```json - "logging": { - "client": false, - "firefoxProxy": false, - "actions": true - } -``` - -Let's cover the logging types. - -* client - This option is currently unused. - -* firefoxProxy - This logger outputs a verbose output of all the Firefox protocol packets to your shell. - -* actions - This logger outputs the Redux actions fired to the browser console. - -### Tests - -Your code must pass all tests to be merged in. Your tests should pass locally before you create a PR and the CI should run an automated test that also passes. - -Here's how can run all the unit tests, lints, and integration tests at once: - -``` -$ yarn run test-all -``` - -#### Unit Tests - -* `yarn test` - Run tests headlessly - * These are the basic unit tests which must always pass -* `yarn run mocha-server` - Run tests in the browser once you open `http://localhost:8003` - * This runs tests in the browser and is useful for fixing errors in the karma tests - -#### Integration tests - -We use [mochitests](https://developer.mozilla.org/en-US/docs/Mozilla/Projects/Mochitest) to do integration testing. Running these integration tests locally requires some finesse and so as a contributor we only ask that you run the unit tests. The mochitests will be run by the automated testing which runs once you've made a pull request and the maintainers are happy to help you through any issues which arise from that. - -Learn more about mochitests in our [mochitests docs](./docs/mochitests.md). - -#### Linting - -Run all of lint checks (JS + CSS) run the following command: - -``` -$ yarn run lint -``` - -##### Lint CSS - -We use [Stylelint](http://stylelint.io/) to maintain our CSS styles. The [.stylelintrc](https://github.com/devtools-html/debugger.html/blob/master/.stylelintrc) file contains the style definitions, please adhere to those styles when making changes. - -To test your CSS changes run the command: - -``` -$ yarn run lint-css -``` - -##### Lint JS - -We use [eslint](http://eslint.org/) to maintain our JavaScript styles. The [.eslintrc](https://github.com/devtools-html/debugger.html/blob/master/.eslintrc) file contains our style definitions, please adhere to those styles when making changes. - -To test your JS changes run the command: - -``` -$ yarn run lint-js -``` - -To automatically fix many errors run the command: - -``` -$ yarn run lint-fix -``` - -## Configuration - -All default config values are in [`packages/devtools-config/configs/development.json`](./packages/devtools-config/configs/development.json), to override these values you need to [create a local config file](#create-a-local-config-file). - -Here are the most common development configuration options: - -* `logging` - * `firefoxProxy` Enables logging the Firefox protocol in the terminal running `yarn start` -* `chrome` - * `debug` Enables listening for remotely debuggable Chrome browsers -* `hotReloading` enables [Hot Reloading](./docs/local-development.md#hot-reloading) of CSS and React - -For a list of all the configuration options see the [packages/devtools-config/README.md](./packages/devtools-config/README.md) - -### Create a local config file - -* Copy the [`configs/development.json`](./configs/development.json) to `configs/local.json` - -## Issues and Pull Request labels - -These are the [labels](https://github.com/devtools-html/debugger.html/labels) we use to help organize and communicate the state of issues and pull requests in the project. If you find a label being used that isn't described here please file an issue to get it listed. - -| Label name | query:mag_right: | Description | -| --- | --- | --- | -| `up-for-grabs` | [search][labels-up-for-grabs] | Good for contributors to work on | -| `difficulty:easy` | [search][labels-difficulty-easy] | Work that is small changes, updating tests, updating docs, expect very little review | -| `difficulty:medium` | [search][labels-difficulty-medium] | Work that adapts existing code, adapts existing tests, expect quick review | -| `difficulty:hard` | [search][labels-difficulty-hard] | Work that requires new tests, new code, and a good understanding of project; expect lots of review | -| `docs` | [search][labels-docs] | Issues with our documentation | -| `design` | [search][labels-design] | Issues that require design work | -| `enhancement` | [search][labels-enhancement] | [Requests](#suggesting-enhancements-new) for features | -| `bug` | [search][labels-bug] | [Reported Bugs](#reporting-bugs-bug) with the current code | -| `chrome` | [search][labels-chrome] | Chrome only issues | -| `firefox` | [search][labels-firefox] | Firefox only issues | -| `infrastructure` | [search][labels-infrastructure] | Issues with testing / build infrastructure | -| `not actionable` | [search][labels-not-actionable] | Issues need clearer requirements before work can be started | - -[labels-up-for-grabs]:https://github.com/devtools-html/debugger.html/labels/up%20for%20grabs -[labels-first-timers-only]:https://github.com/devtools-html/debugger.html/labels/first-timers-only -[labels-difficulty-easy]:https://github.com/devtools-html/debugger.html/labels/difficulty%3A%20easy -[labels-difficulty-medium]:https://github.com/devtools-html/debugger.html/labels/difficulty%3A%medium -[labels-difficulty-hard]:https://github.com/devtools-html/debugger.html/labels/difficulty%3A%hard -[labels-docs]:https://github.com/devtools-html/debugger.html/labels/docs -[labels-design]:https://github.com/devtools-html/debugger.html/labels/design -[labels-enhancement]:https://github.com/devtools-html/debugger.html/labels/enhancement -[labels-bug]:https://github.com/devtools-html/debugger.html/labels/bug -[labels-chrome]:https://github.com/devtools-html/debugger.html/labels/chrome -[labels-firefox]:https://github.com/devtools-html/debugger.html/labels/firefox -[labels-infrastructure]:https://github.com/devtools-html/debugger.html/labels/infrastructure -[labels-not-actionable]:https://github.com/devtools-html/debugger.html/labels/not%20actionable - -[GitHub Desktop]:https://desktop.github.com/ diff --git a/LICENSE b/LICENSE deleted file mode 100644 index a612ad9813..0000000000 --- a/LICENSE +++ /dev/null @@ -1,373 +0,0 @@ -Mozilla Public License Version 2.0 -================================== - -1. Definitions --------------- - -1.1. "Contributor" - means each individual or legal entity that creates, contributes to - the creation of, or owns Covered Software. - -1.2. "Contributor Version" - means the combination of the Contributions of others (if any) used - by a Contributor and that particular Contributor's Contribution. - -1.3. "Contribution" - means Covered Software of a particular Contributor. - -1.4. "Covered Software" - means Source Code Form to which the initial Contributor has attached - the notice in Exhibit A, the Executable Form of such Source Code - Form, and Modifications of such Source Code Form, in each case - including portions thereof. - -1.5. "Incompatible With Secondary Licenses" - means - - (a) that the initial Contributor has attached the notice described - in Exhibit B to the Covered Software; or - - (b) that the Covered Software was made available under the terms of - version 1.1 or earlier of the License, but not also under the - terms of a Secondary License. - -1.6. "Executable Form" - means any form of the work other than Source Code Form. - -1.7. "Larger Work" - means a work that combines Covered Software with other material, in - a separate file or files, that is not Covered Software. - -1.8. "License" - means this document. - -1.9. "Licensable" - means having the right to grant, to the maximum extent possible, - whether at the time of the initial grant or subsequently, any and - all of the rights conveyed by this License. - -1.10. "Modifications" - means any of the following: - - (a) any file in Source Code Form that results from an addition to, - deletion from, or modification of the contents of Covered - Software; or - - (b) any new file in Source Code Form that contains any Covered - Software. - -1.11. "Patent Claims" of a Contributor - means any patent claim(s), including without limitation, method, - process, and apparatus claims, in any patent Licensable by such - Contributor that would be infringed, but for the grant of the - License, by the making, using, selling, offering for sale, having - made, import, or transfer of either its Contributions or its - Contributor Version. - -1.12. "Secondary License" - means either the GNU General Public License, Version 2.0, the GNU - Lesser General Public License, Version 2.1, the GNU Affero General - Public License, Version 3.0, or any later versions of those - licenses. - -1.13. "Source Code Form" - means the form of the work preferred for making modifications. - -1.14. "You" (or "Your") - means an individual or a legal entity exercising rights under this - License. For legal entities, "You" includes any entity that - controls, is controlled by, or is under common control with You. For - purposes of this definition, "control" means (a) the power, direct - or indirect, to cause the direction or management of such entity, - whether by contract or otherwise, or (b) ownership of more than - fifty percent (50%) of the outstanding shares or beneficial - ownership of such entity. - -2. License Grants and Conditions --------------------------------- - -2.1. Grants - -Each Contributor hereby grants You a world-wide, royalty-free, -non-exclusive license: - -(a) under intellectual property rights (other than patent or trademark) - Licensable by such Contributor to use, reproduce, make available, - modify, display, perform, distribute, and otherwise exploit its - Contributions, either on an unmodified basis, with Modifications, or - as part of a Larger Work; and - -(b) under Patent Claims of such Contributor to make, use, sell, offer - for sale, have made, import, and otherwise transfer either its - Contributions or its Contributor Version. - -2.2. Effective Date - -The licenses granted in Section 2.1 with respect to any Contribution -become effective for each Contribution on the date the Contributor first -distributes such Contribution. - -2.3. Limitations on Grant Scope - -The licenses granted in this Section 2 are the only rights granted under -this License. No additional rights or licenses will be implied from the -distribution or licensing of Covered Software under this License. -Notwithstanding Section 2.1(b) above, no patent license is granted by a -Contributor: - -(a) for any code that a Contributor has removed from Covered Software; - or - -(b) for infringements caused by: (i) Your and any other third party's - modifications of Covered Software, or (ii) the combination of its - Contributions with other software (except as part of its Contributor - Version); or - -(c) under Patent Claims infringed by Covered Software in the absence of - its Contributions. - -This License does not grant any rights in the trademarks, service marks, -or logos of any Contributor (except as may be necessary to comply with -the notice requirements in Section 3.4). - -2.4. Subsequent Licenses - -No Contributor makes additional grants as a result of Your choice to -distribute the Covered Software under a subsequent version of this -License (see Section 10.2) or under the terms of a Secondary License (if -permitted under the terms of Section 3.3). - -2.5. Representation - -Each Contributor represents that the Contributor believes its -Contributions are its original creation(s) or it has sufficient rights -to grant the rights to its Contributions conveyed by this License. - -2.6. Fair Use - -This License is not intended to limit any rights You have under -applicable copyright doctrines of fair use, fair dealing, or other -equivalents. - -2.7. Conditions - -Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted -in Section 2.1. - -3. Responsibilities -------------------- - -3.1. Distribution of Source Form - -All distribution of Covered Software in Source Code Form, including any -Modifications that You create or to which You contribute, must be under -the terms of this License. You must inform recipients that the Source -Code Form of the Covered Software is governed by the terms of this -License, and how they can obtain a copy of this License. You may not -attempt to alter or restrict the recipients' rights in the Source Code -Form. - -3.2. Distribution of Executable Form - -If You distribute Covered Software in Executable Form then: - -(a) such Covered Software must also be made available in Source Code - Form, as described in Section 3.1, and You must inform recipients of - the Executable Form how they can obtain a copy of such Source Code - Form by reasonable means in a timely manner, at a charge no more - than the cost of distribution to the recipient; and - -(b) You may distribute such Executable Form under the terms of this - License, or sublicense it under different terms, provided that the - license for the Executable Form does not attempt to limit or alter - the recipients' rights in the Source Code Form under this License. - -3.3. Distribution of a Larger Work - -You may create and distribute a Larger Work under terms of Your choice, -provided that You also comply with the requirements of this License for -the Covered Software. If the Larger Work is a combination of Covered -Software with a work governed by one or more Secondary Licenses, and the -Covered Software is not Incompatible With Secondary Licenses, this -License permits You to additionally distribute such Covered Software -under the terms of such Secondary License(s), so that the recipient of -the Larger Work may, at their option, further distribute the Covered -Software under the terms of either this License or such Secondary -License(s). - -3.4. Notices - -You may not remove or alter the substance of any license notices -(including copyright notices, patent notices, disclaimers of warranty, -or limitations of liability) contained within the Source Code Form of -the Covered Software, except that You may alter any license notices to -the extent required to remedy known factual inaccuracies. - -3.5. Application of Additional Terms - -You may choose to offer, and to charge a fee for, warranty, support, -indemnity or liability obligations to one or more recipients of Covered -Software. However, You may do so only on Your own behalf, and not on -behalf of any Contributor. You must make it absolutely clear that any -such warranty, support, indemnity, or liability obligation is offered by -You alone, and You hereby agree to indemnify every Contributor for any -liability incurred by such Contributor as a result of warranty, support, -indemnity or liability terms You offer. You may include additional -disclaimers of warranty and limitations of liability specific to any -jurisdiction. - -4. Inability to Comply Due to Statute or Regulation ---------------------------------------------------- - -If it is impossible for You to comply with any of the terms of this -License with respect to some or all of the Covered Software due to -statute, judicial order, or regulation then You must: (a) comply with -the terms of this License to the maximum extent possible; and (b) -describe the limitations and the code they affect. Such description must -be placed in a text file included with all distributions of the Covered -Software under this License. Except to the extent prohibited by statute -or regulation, such description must be sufficiently detailed for a -recipient of ordinary skill to be able to understand it. - -5. Termination --------------- - -5.1. The rights granted under this License will terminate automatically -if You fail to comply with any of its terms. However, if You become -compliant, then the rights granted under this License from a particular -Contributor are reinstated (a) provisionally, unless and until such -Contributor explicitly and finally terminates Your grants, and (b) on an -ongoing basis, if such Contributor fails to notify You of the -non-compliance by some reasonable means prior to 60 days after You have -come back into compliance. Moreover, Your grants from a particular -Contributor are reinstated on an ongoing basis if such Contributor -notifies You of the non-compliance by some reasonable means, this is the -first time You have received notice of non-compliance with this License -from such Contributor, and You become compliant prior to 30 days after -Your receipt of the notice. - -5.2. If You initiate litigation against any entity by asserting a patent -infringement claim (excluding declaratory judgment actions, -counter-claims, and cross-claims) alleging that a Contributor Version -directly or indirectly infringes any patent, then the rights granted to -You by any and all Contributors for the Covered Software under Section -2.1 of this License shall terminate. - -5.3. In the event of termination under Sections 5.1 or 5.2 above, all -end user license agreements (excluding distributors and resellers) which -have been validly granted by You or Your distributors under this License -prior to termination shall survive termination. - -************************************************************************ -* * -* 6. Disclaimer of Warranty * -* ------------------------- * -* * -* Covered Software is provided under this License on an "as is" * -* basis, without warranty of any kind, either expressed, implied, or * -* statutory, including, without limitation, warranties that the * -* Covered Software is free of defects, merchantable, fit for a * -* particular purpose or non-infringing. The entire risk as to the * -* quality and performance of the Covered Software is with You. * -* Should any Covered Software prove defective in any respect, You * -* (not any Contributor) assume the cost of any necessary servicing, * -* repair, or correction. This disclaimer of warranty constitutes an * -* essential part of this License. No use of any Covered Software is * -* authorized under this License except under this disclaimer. * -* * -************************************************************************ - -************************************************************************ -* * -* 7. Limitation of Liability * -* -------------------------- * -* * -* Under no circumstances and under no legal theory, whether tort * -* (including negligence), contract, or otherwise, shall any * -* Contributor, or anyone who distributes Covered Software as * -* permitted above, be liable to You for any direct, indirect, * -* special, incidental, or consequential damages of any character * -* including, without limitation, damages for lost profits, loss of * -* goodwill, work stoppage, computer failure or malfunction, or any * -* and all other commercial damages or losses, even if such party * -* shall have been informed of the possibility of such damages. This * -* limitation of liability shall not apply to liability for death or * -* personal injury resulting from such party's negligence to the * -* extent applicable law prohibits such limitation. Some * -* jurisdictions do not allow the exclusion or limitation of * -* incidental or consequential damages, so this exclusion and * -* limitation may not apply to You. * -* * -************************************************************************ - -8. Litigation -------------- - -Any litigation relating to this License may be brought only in the -courts of a jurisdiction where the defendant maintains its principal -place of business and such litigation shall be governed by laws of that -jurisdiction, without reference to its conflict-of-law provisions. -Nothing in this Section shall prevent a party's ability to bring -cross-claims or counter-claims. - -9. Miscellaneous ----------------- - -This License represents the complete agreement concerning the subject -matter hereof. If any provision of this License is held to be -unenforceable, such provision shall be reformed only to the extent -necessary to make it enforceable. Any law or regulation which provides -that the language of a contract shall be construed against the drafter -shall not be used to construe this License against a Contributor. - -10. Versions of the License ---------------------------- - -10.1. New Versions - -Mozilla Foundation is the license steward. Except as provided in Section -10.3, no one other than the license steward has the right to modify or -publish new versions of this License. Each version will be given a -distinguishing version number. - -10.2. Effect of New Versions - -You may distribute the Covered Software under the terms of the version -of the License under which You originally received the Covered Software, -or under the terms of any subsequent version published by the license -steward. - -10.3. Modified Versions - -If you create software not governed by this License, and you want to -create a new license for such software, you may create and use a -modified version of this License if you rename the license and remove -any references to the name of the license steward (except to note that -such modified license differs from this License). - -10.4. Distributing Source Code Form that is Incompatible With Secondary -Licenses - -If You choose to distribute Source Code Form that is Incompatible With -Secondary Licenses under the terms of this version of the License, the -notice described in Exhibit B of this License must be attached. - -Exhibit A - Source Code Form License Notice -------------------------------------------- - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - -If it is not possible or desirable to put the notice in a particular -file, then You may include the notice in a location (such as a LICENSE -file in a relevant directory) where a recipient would be likely to look -for such a notice. - -You may add additional accurate notices of copyright ownership. - -Exhibit B - "Incompatible With Secondary Licenses" Notice ---------------------------------------------------------- - - This Source Code Form is "Incompatible With Secondary Licenses", as - defined by the Mozilla Public License, v. 2.0. diff --git a/README.md b/README.md index 5b7a7f2cd1..36c0d175d5 100644 --- a/README.md +++ b/README.md @@ -1,105 +1,25 @@ -# debugger.html +# Firefox Debugger -debugger.html is a hackable debugger for modern times, built from the ground up using [React][react] and [Redux][redux]. It is designed to be approachable, yet powerful. And it is engineered to be predictable, understandable, and testable. +The Firefox Debugger is now maintained in Mozilla's central repository. -[Mozilla][mozilla] created this debugger for use in the [Firefox][mozilla-firefox] Developer Tools. And we've purposely created this project in GitHub, using modern toolchains. We hope to not only to create a great debugger that works with the [Firefox](https://wiki.mozilla.org/Remote_Debugging_Protocol) and [Chrome Debugging Protocol](https://chromedevtools.github.io/debugger-protocol-viewer/1-1/) but development community that can embed this debugger in your own projects with tools like [NPM](http://npmjs.com/). +- Visit [docs][devtools-docs] to learn how to contribute +- Checkout our [dashboard][gfb] to find good first bugs. +- Go to [bugzilla][debugger-bugs] to report an issue or suggest an enhancement. +- Feel free to ask questions at any point on [Matrix][devtools-matrix] -debugger-screenshot +![debugger-screenshot] -![Circle CI status](https://circleci.com/gh/devtools-html/debugger.html.svg??&style=shield) -[![npm version](https://img.shields.io/npm/v/debugger.html.svg)](https://www.npmjs.com/package/debugger.html) -[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com) +[devtools-docs]: https://firefox-source-docs.mozilla.org/devtools/index.html?highlight=devtools#getting-started +[debugger-bugs]: https://bugzilla.mozilla.org/enter_bug.cgi?product=DevTools&component=Debugger +[gfb]: https://codetribute.mozilla.org/projects/devtools -## Getting Started -Here are instructions to get the debugger.html application installed and running. +### Thank You -### Linux or MacOs +The Firefox Debugger was built in Github for the first 3 years of its development. Over 300+ volunteers contributed thousands of commits and built many of the features we take for granted today. -* `npm i -g yarn@0.16.1` - Install Yarn -* `git clone git@github.com:devtools-html/debugger.html.git` - Clone Debugger -* `yarn install` - Install dependencies -* `yarn start` - Start development web server +We hope to continue that spirit today in Mozilla Central. We believe the Debugger can be a great place to collaborate on the next iteration of developer tools. And, that everyone regardless of background or experience can contribute work of significance. -NOTE: :cat2: We use [Yarn](https://yarnpkg.com) so that we all have the same setup. -### Windows - -It is recommended to use Git Shell which comes with [GitHub Desktop] application to emulate bash on Windows. - -* `npm i -g yarn@0.16.1` - Install Yarn -* `git clone git@github.com:devtools-html/debugger.html.git` - Clone Debugger -* `yarn install` - Install dependencies -* `yarn start` - Start development web server - -NOTE: :cat2: We use [Yarn](https://yarnpkg.com) so that we all have the same setup. - -### Open the Debugger - -After `yarn start`, the debugger will be running on [http://localhost:8000](http://localhost:8000) and you can open it in any browser. [screenshot](https://cloud.githubusercontent.com/assets/254562/20393011/44ca6a8a-aca8-11e6-99f7-05f21767ae6d.png) - -Now you have the debugger.html web app running, follow the instructions shown on that page to start up a debug target like a web browser or node.js. - -Please read [Getting Started][getting-started] in our [CONTRIBUTING][contributing] document for more detailed instructions. - -## Getting Involved - -This is an open source project and we would love your help. We have prepared a [CONTRIBUTING][contributing] guide to help you get started, here are some quick links to common questions. - - * [Reporting Bugs][reporting-bugs] - * [Suggesting Enhancements][suggesting-enhancements] - * [Your First Code Contribution][your-first-code-contribution] - * [Pull Requests][pull-requests] - * [Writing Code][writing-code] - * [Hot Reloading][hot-reloading] - * [Tests][tests] - * [Unit Tests][unit-tests] - * [Integration Tests][integration-tests] - * [Linting][linting] - -We use the [up for grabs](https://github.com/devtools-html/debugger.html/labels/up%20for%20grabs) label to indicate this work is open for anyone to take. If you already know what you're doing and want to dive in, take a look at those issues. - -We strive for collaboration with [mutual respect for each other](./CODE_OF_CONDUCT.md). Mozilla also has a set of [participation guidelines](https://www.mozilla.org/en-US/about/governance/policies/participation/) which goes into greater detail specific to Mozilla employees and contributors. - -## Discussion - -We're all on Mozilla's IRC in the [#devtools-html][irc-devtools-html] channel on irc.mozilla.org. - - -* **Open Office Hours** Every Tuesday, Thursday at 3pm EST. [Event](https://calendar.google.com/calendar/render#eventpage_6%7Ceid-MzBtZHBhNm5jcW44dXR0dm1yajliOWQzamNfMjAxNjExMjJUMjAwMDAwWiBodWtoZG9rbzNuMm5oNzZiZGw2dWUya2pqb0Bn-1-0-) -* **DevTools Call** Every Tuesday at 12pm EST. [info](https://wiki.mozilla.org/DevTools) - -## License - -[MPL 2](./LICENSE) - -[react]:https://facebook.github.io/react/ -[redux]:http://redux.js.org/ -[mozilla]:https://www.mozilla.org/ -[mozilla-firefox]:https://www.mozilla.org/firefox/ - -[contributing]:./CONTRIBUTING.md -[getting-started]:./CONTRIBUTING.md#getting-started - -[getting-started-firefox]:./CONTRIBUTING.md#firefox - -[getting-started-chrome]:./CONTRIBUTING.md#chrome - -[getting-started-node]:./CONTRIBUTING.md#nodejs - -[create-local-config]:./CONTRIBUTING.md#create-a-local-config-file - -[reporting-bugs]:./CONTRIBUTING.md#reporting-bugs-bug -[suggesting-enhancements]:./CONTRIBUTING.md#suggesting-enhancements-new -[your-first-code-contribution]:./CONTRIBUTING.md#your-first-code-contribution -[pull-requests]:./CONTRIBUTING.md#pull-requests -[writing-code]:./CONTRIBUTING.md#writing-code-computer -[hot-reloading]:./CONTRIBUTING.md#hot-reloading-fire -[tests]:./CONTRIBUTING.md#tests -[unit-tests]:./CONTRIBUTING.md#unit-tests -[integration-tests]:./CONTRIBUTING.md#integration-tests -[linting]:./CONTRIBUTING.md#linting - -[irc-devtools-html]:irc://irc.mozilla.org/devtools-html - -[GitHub Desktop]:https://desktop.github.com/ +[debugger-screenshot]: https://shipusercontent.com/47aaaa7a6512691f964101bfb0832abe/Screen%20Shot%202017-08-15%20at%202.34.05%20PM.png +[devtools-matrix]: https://chat.mozilla.org/#/room/#devtools:mozilla.org diff --git a/assets/images/Svg.js b/assets/images/Svg.js deleted file mode 100644 index 775aecfc07..0000000000 --- a/assets/images/Svg.js +++ /dev/null @@ -1,43 +0,0 @@ -const React = require("react"); -const InlineSVG = require("svg-inline-react"); - -const svg = { - "angle-brackets": require("./angle-brackets.svg"), - "arrow": require("./arrow.svg"), - "blackBox": require("./blackBox.svg"), - "breakpoint": require("./breakpoint.svg"), - "close": require("./close.svg"), - "domain": require("./domain.svg"), - "file": require("./file.svg"), - "folder": require("./folder.svg"), - "globe": require("./globe.svg"), - "magnifying-glass": require("./magnifying-glass.svg"), - "pause": require("./pause.svg"), - "pause-exceptions": require("./pause-exceptions.svg"), - "plus": require("./plus.svg"), - "prettyPrint": require("./prettyPrint.svg"), - "resume": require("./resume.svg"), - "settings": require("./settings.svg"), - "stepIn": require("./stepIn.svg"), - "stepOut": require("./stepOut.svg"), - "stepOver": require("./stepOver.svg"), - "subSettings": require("./subSettings.svg"), - "toggleBreakpoints": require("./toggle-breakpoints.svg"), - "worker": require("./worker.svg"), - "sad-face": require("./sad-face.svg") -}; - -module.exports = function(name, props) { // eslint-disable-line - if (!svg[name]) { - throw new Error("Unknown SVG: " + name); - } - let className = name; - if (props && props.className) { - className = `${name} ${props.className}`; - } - if (name === "subSettings") { - className = ""; - } - props = Object.assign({}, props, { className, src: svg[name] }); - return React.createElement(InlineSVG, props); -}; diff --git a/assets/images/angle-brackets.svg b/assets/images/angle-brackets.svg deleted file mode 100644 index b353bee9ec..0000000000 --- a/assets/images/angle-brackets.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - diff --git a/assets/images/arrow.svg b/assets/images/arrow.svg deleted file mode 100644 index 33a1077971..0000000000 --- a/assets/images/arrow.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/assets/images/blackBox.svg b/assets/images/blackBox.svg deleted file mode 100644 index b98d62f138..0000000000 --- a/assets/images/blackBox.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - diff --git a/assets/images/breakpoint.svg b/assets/images/breakpoint.svg deleted file mode 100644 index f0e5de106b..0000000000 --- a/assets/images/breakpoint.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - diff --git a/assets/images/close.svg b/assets/images/close.svg deleted file mode 100644 index 7efd07f80c..0000000000 --- a/assets/images/close.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/assets/images/domain.svg b/assets/images/domain.svg deleted file mode 100644 index f00c9b37d3..0000000000 --- a/assets/images/domain.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/assets/images/favicon.png b/assets/images/favicon.png deleted file mode 100644 index 98f1d48e4d..0000000000 Binary files a/assets/images/favicon.png and /dev/null differ diff --git a/assets/images/file.svg b/assets/images/file.svg deleted file mode 100644 index 7f5a70855c..0000000000 --- a/assets/images/file.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/assets/images/folder.svg b/assets/images/folder.svg deleted file mode 100644 index 6b8ef6ac37..0000000000 --- a/assets/images/folder.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - diff --git a/assets/images/globe.svg b/assets/images/globe.svg deleted file mode 100644 index d513a659f6..0000000000 --- a/assets/images/globe.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - diff --git a/assets/images/magnifying-glass.svg b/assets/images/magnifying-glass.svg deleted file mode 100644 index 8560132835..0000000000 --- a/assets/images/magnifying-glass.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/assets/images/pause-exceptions.svg b/assets/images/pause-exceptions.svg deleted file mode 100644 index 8a0eb2c832..0000000000 --- a/assets/images/pause-exceptions.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/assets/images/pause.svg b/assets/images/pause.svg deleted file mode 100644 index b27bf2a856..0000000000 --- a/assets/images/pause.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - diff --git a/assets/images/plus.svg b/assets/images/plus.svg deleted file mode 100644 index ae7a69dfde..0000000000 --- a/assets/images/plus.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - diff --git a/assets/images/prettyPrint.svg b/assets/images/prettyPrint.svg deleted file mode 100644 index 62e2707f94..0000000000 --- a/assets/images/prettyPrint.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - diff --git a/assets/images/resume.svg b/assets/images/resume.svg deleted file mode 100644 index 4a8b7fcd4d..0000000000 --- a/assets/images/resume.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - diff --git a/assets/images/sad-face.svg b/assets/images/sad-face.svg deleted file mode 100644 index 6c42ca43b6..0000000000 --- a/assets/images/sad-face.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - diff --git a/assets/images/settings.svg b/assets/images/settings.svg deleted file mode 100644 index 310438f7eb..0000000000 --- a/assets/images/settings.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - diff --git a/assets/images/stepIn.svg b/assets/images/stepIn.svg deleted file mode 100644 index eff11c0c91..0000000000 --- a/assets/images/stepIn.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - diff --git a/assets/images/stepOut.svg b/assets/images/stepOut.svg deleted file mode 100644 index 4e54571412..0000000000 --- a/assets/images/stepOut.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - diff --git a/assets/images/stepOver.svg b/assets/images/stepOver.svg deleted file mode 100644 index c1d30c051f..0000000000 --- a/assets/images/stepOver.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - diff --git a/assets/images/subSettings.svg b/assets/images/subSettings.svg deleted file mode 100644 index 6b23555846..0000000000 --- a/assets/images/subSettings.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - diff --git a/assets/images/toggle-breakpoints.svg b/assets/images/toggle-breakpoints.svg deleted file mode 100644 index 9b2cccf822..0000000000 --- a/assets/images/toggle-breakpoints.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - diff --git a/assets/images/worker.svg b/assets/images/worker.svg deleted file mode 100644 index 4a9874efb8..0000000000 --- a/assets/images/worker.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - diff --git a/assets/locales/debugger.properties b/assets/locales/debugger.properties deleted file mode 100644 index 83a924f1b7..0000000000 --- a/assets/locales/debugger.properties +++ /dev/null @@ -1,410 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# LOCALIZATION NOTE These strings are used inside the Debugger -# which is available from the Web Developer sub-menu -> 'Debugger'. -# The correct localization of this file might be to keep it in -# English, or another language commonly spoken among web developers. -# You want to make that choice consistent across the developer tools. -# A good criteria is the language in which you'd find the best -# documentation on web development on the web. - -# LOCALIZATION NOTE (collapsePanes): This is the tooltip for the button -# that collapses the left and right panes in the debugger UI. -collapsePanes=Collapse panes - -# LOCALIZATION NOTE (expandPanes): This is the tooltip for the button -# that expands the left and right panes in the debugger UI. -expandPanes=Expand panes - -# LOCALIZATION NOTE (pauseButtonTooltip): The tooltip that is displayed for the pause -# button when the debugger is in a running state. -pauseButtonTooltip=Click to pause (%S) - -# LOCALIZATION NOTE (pausePendingButtonTooltip): The tooltip that is displayed for -# the pause button after it's been clicked but before the next JavaScript to run. -pausePendingButtonTooltip=Waiting for next execution - -# LOCALIZATION NOTE (resumeButtonTooltip): The label that is displayed on the pause -# button when the debugger is in a paused state. -resumeButtonTooltip=Click to resume (%S) - -# LOCALIZATION NOTE (stepOverTooltip): The label that is displayed on the -# button that steps over a function call. -stepOverTooltip=Step Over (%S) - -# LOCALIZATION NOTE (stepInTooltip): The label that is displayed on the -# button that steps into a function call. -stepInTooltip=Step In (%S) - -# LOCALIZATION NOTE (stepOutTooltip): The label that is displayed on the -# button that steps out of a function call. -stepOutTooltip=Step Out (%S) - -# LOCALIZATION NOTE (noWorkersText): The text to display in the workers list -# when there are no workers. -noWorkersText=This page has no workers. - -# LOCALIZATION NOTE (noSourcesText): The text to display in the sources list -# when there are no sources. -noSourcesText=This page has no sources. - -# LOCALIZATION NOTE (noEventListenersText): The text to display in the events tab -# when there are no events. -noEventListenersText=No event listeners to display - -# LOCALIZATION NOTE (noStackFramesText): The text to display in the call stack tab -# when there are no stack frames. -noStackFramesText=No stack frames to display - -# LOCALIZATION NOTE (eventCheckboxTooltip): The tooltip text to display when -# the user hovers over the checkbox used to toggle an event breakpoint. -eventCheckboxTooltip=Toggle breaking on this event - -# LOCALIZATION NOTE (eventOnSelector): The text to display in the events tab -# for every event item, between the event type and event selector. -eventOnSelector=on - -# LOCALIZATION NOTE (eventInSource): The text to display in the events tab -# for every event item, between the event selector and listener's owner source. -eventInSource=in - -# LOCALIZATION NOTE (eventNodes): The text to display in the events tab when -# an event is listened on more than one target node. -eventNodes=%S nodes - -# LOCALIZATION NOTE (eventNative): The text to display in the events tab when -# a listener is added from plugins, thus getting translated to native code. -eventNative=[native code] - -# LOCALIZATION NOTE (*Events): The text to display in the events tab for -# each group of sub-level event entries. -animationEvents=Animation -audioEvents=Audio -batteryEvents=Battery -clipboardEvents=Clipboard -compositionEvents=Composition -deviceEvents=Device -displayEvents=Display -dragAndDropEvents=Drag and Drop -gamepadEvents=Gamepad -indexedDBEvents=IndexedDB -interactionEvents=Interaction -keyboardEvents=Keyboard -mediaEvents=HTML5 Media -mouseEvents=Mouse -mutationEvents=Mutation -navigationEvents=Navigation -pointerLockEvents=Pointer Lock -sensorEvents=Sensor -storageEvents=Storage -timeEvents=Time -touchEvents=Touch -otherEvents=Other - -# LOCALIZATION NOTE (blackBoxCheckboxTooltip): The tooltip text to display when -# the user hovers over the checkbox used to toggle black boxing its associated -# source. -blackBoxCheckboxTooltip=Toggle black boxing - -# LOCALIZATION NOTE (noMatchingStringsText): The text to display in the -# global search results when there are no matching strings after filtering. -noMatchingStringsText=No matches found - -# LOCALIZATION NOTE (emptySearchText): This is the text that appears in the -# filter text box when it is empty and the scripts container is selected. -emptySearchText=Search scripts (%S) - -# LOCALIZATION NOTE (emptyVariablesFilterText): This is the text that -# appears in the filter text box for the variables view container. -emptyVariablesFilterText=Filter variables - -# LOCALIZATION NOTE (emptyPropertiesFilterText): This is the text that -# appears in the filter text box for the editor's variables view bubble. -emptyPropertiesFilterText=Filter properties - -# LOCALIZATION NOTE (searchPanelFilter): This is the text that appears in the -# filter panel popup for the filter scripts operation. -searchPanelFilter=Filter scripts (%S) - -# LOCALIZATION NOTE (searchPanelGlobal): This is the text that appears in the -# filter panel popup for the global search operation. -searchPanelGlobal=Search in all files (%S) - -# LOCALIZATION NOTE (searchPanelFunction): This is the text that appears in the -# filter panel popup for the function search operation. -searchPanelFunction=Search for function definition (%S) - -# LOCALIZATION NOTE (searchPanelToken): This is the text that appears in the -# filter panel popup for the token search operation. -searchPanelToken=Find in this file (%S) - -# LOCALIZATION NOTE (searchPanelGoToLine): This is the text that appears in the -# filter panel popup for the line search operation. -searchPanelGoToLine=Go to line (%S) - -# LOCALIZATION NOTE (searchPanelVariable): This is the text that appears in the -# filter panel popup for the variables search operation. -searchPanelVariable=Filter variables (%S) - -# LOCALIZATION NOTE (breakpointMenuItem): The text for all the elements that -# are displayed in the breakpoints menu item popup. -breakpointMenuItem.setConditional=Configure conditional breakpoint -breakpointMenuItem.enableSelf=Enable breakpoint -breakpointMenuItem.disableSelf=Disable breakpoint -breakpointMenuItem.deleteSelf=Remove breakpoint -breakpointMenuItem.enableOthers=Enable others -breakpointMenuItem.disableOthers=Disable others -breakpointMenuItem.deleteOthers=Remove others -breakpointMenuItem.enableAll=Enable all breakpoints -breakpointMenuItem.disableAll=Disable all breakpoints -breakpointMenuItem.deleteAll=Remove all breakpoints - -# LOCALIZATION NOTE (breakpoints.header): Breakpoints right sidebar pane header. -breakpoints.header=Breakpoints - -# LOCALIZATION NOTE (breakpoints.none): The text that appears when there are -# no breakpoints present -breakpoints.none=No Breakpoints - -# LOCALIZATION NOTE (callStack.header): Call Stack right sidebar pane header. -callStack.header=Call Stack - -# LOCALIZATION NOTE (callStack.notPaused): Call Stack right sidebar pane -# message when not paused. -callStack.notPaused=Not Paused - -# LOCALIZATION NOTE (callStack.collapse): Call Stack right sidebar pane -# message to hide some of the frames that are shown. -callStack.collapse=Collapse Rows - -# LOCALIZATION NOTE (callStack.expand): Call Stack right sidebar pane -# message to show more of the frames. -callStack.expand=Expand Rows - -# LOCALIZATION NOTE (editor.searchResults): Editor Search bar message -# for the summarizing the selected search result. e.g. 5 of 10 results. -editor.searchResults=%d of %d results - -# LOCALIZATION NOTE (editor.noResults): Editor Search bar message -# for when no results found. -editor.noResults=no results - -# LOCALIZATION NOTE(editor.addBreakpoint): Editor gutter context menu item -# for adding a breakpoint on a line. -editor.addBreakpoint=Add Breakpoint - -# LOCALIZATION NOTE(editor.disableBreakpoint): Editor gutter context menu item -# for disabling a breakpoint on a line. -editor.disableBreakpoint=Disable Breakpoint - -# LOCALIZATION NOTE(editor.enableBreakpoint): Editor gutter context menu item -# for enabling a breakpoint on a line. -editor.enableBreakpoint=Enable Breakpoint - -# LOCALIZATION NOTE(editor.removeBreakpoint): Editor gutter context menu item -# for removing a breakpoint on a line. -editor.removeBreakpoint=Remove Breakpoint - -# LOCALIZATION NOTE(editor.editBreakpoint): Editor gutter context menu item -# for setting a breakpoint condition on a line. -editor.editBreakpoint=Edit Breakpoint - -# LOCALIZATION NOTE(editor.addConditionalBreakpoint): Editor gutter context -# menu item for adding a breakpoint condition on a line. -editor.addConditionalBreakpoint=Add Conditional Breakpoint - -# LOCALIZATION NOTE(editor.conditionalPanel.placeholder): Placeholder text for -# input element inside ConditionalPanel component -editor.conditionalPanel.placeholder=This breakpoint will pause when the expression is true - -# LOCALIZATION NOTE(expressions.placeholder): Placeholder text for expression -# input element -expressions.placeholder=Add Watch Expression - -# LOCALIZATION NOTE (sourceTabs.closeTab): Editor source tab context menu item -# for closing the selected tab below the mouse. -sourceTabs.closeTab=Close tab - -# LOCALIZATION NOTE (sourceTabs.closeOtherTabs): Editor source tab context menu item -# for closing the other tabs. -sourceTabs.closeOtherTabs=Close others - -# LOCALIZATION NOTE (sourceTabs.closeTabsToRight): Editor source tab context menu item -# for closing the tabs to the right of the selected tab. -sourceTabs.closeTabsToRight=Close tabs to the right - -# LOCALIZATION NOTE (sourceTabs.closeAllTabs): Editor source tab context menu item -# for closing all tabs. -sourceTabs.closeAllTabs=Close all tabs - -# LOCALIZATION NOTE (scopes.header): Scopes right sidebar pane header. -scopes.header=Scopes - -# LOCALIZATION NOTE (scopes.notAvailable): Scopes right sidebar pane message -# for when the debugger is paused, but there isn't pause data. -scopes.notAvailable=Scopes Unavailable - -# LOCALIZATION NOTE (scopes.notPaused): Scopes right sidebar pane message -# for when the debugger is not paused. -scopes.notPaused=Not Paused - -# LOCALIZATION NOTE (scopes.block): Scopes right sidebar block subheading -scopes.block=Block - -# LOCALIZATION NOTE (sources.header): Sources left sidebar header -sources.header=Sources - -# LOCALIZATION NOTE (sources.search): Sources left sidebar prompt -# e.g. Cmd+P to search. On a mac, we use the command unicode character. -# On windows, it's ctrl. -sources.search=%S to search - -# LOCALIZATION NOTE (watchExpressions.header): Watch Expressions right sidebar -# pane header. -watchExpressions.header=Watch Expressions - -# LOCALIZATION NOTE (welcome.search): The center pane welcome panel's -# search prompt. e.g. cmd+p to search for files. On windows, it's ctrl, on -# a mac we use the unicode character. -welcome.search=%S to search for files - -# LOCALIZATION NOTE (sourceSearch.search): The center pane Source Search -# prompt for searching for files. -sourceSearch.search=Search… - -# LOCALIZATION NOTE (sourceSearch.noResults): The center pane Source Search -# message when the query did not match any of the sources. -sourceSearch.noResults=No files matching %S found - -# LOCALIZATION NOTE (sourceFooter.debugBtnTooltip): Tooltip text associated -# with the pretty-print button -sourceFooter.debugBtnTooltip=Prettify Source - -# LOCALIZATION NOTE (ignoreExceptions): The pause on exceptions button tooltip -# when the debugger will not pause on exceptions. -ignoreExceptions=Ignore exceptions. Click to pause on uncaught exceptions - -# LOCALIZATION NOTE (pauseOnUncaughtExceptions): The pause on exceptions button -# tooltip when the debugger will pause on uncaught exceptions. -pauseOnUncaughtExceptions=Pause on uncaught exceptions. Click to pause on all exceptions - -# LOCALIZATION NOTE (pauseOnExceptions): The pause on exceptions button tooltip -# when the debugger will pause on all exceptions. -pauseOnExceptions=Pause on all exceptions. Click to ignore exceptions - -# LOCALIZATION NOTE (loadingText): The text that is displayed in the script -# editor when the loading process has started but there is no file to display -# yet. -loadingText=Loading\u2026 - -# LOCALIZATION NOTE (errorLoadingText2): The text that is displayed in the debugger -# viewer when there is an error loading a file -errorLoadingText2=Error loading this URL: %S - -# LOCALIZATION NOTE (addWatchExpressionText): The text that is displayed in the -# watch expressions list to add a new item. -addWatchExpressionText=Add watch expression - -# LOCALIZATION NOTE (addWatchExpressionButton): The button that is displayed in the -# variables view popup. -addWatchExpressionButton=Watch - -# LOCALIZATION NOTE (emptyVariablesText): The text that is displayed in the -# variables pane when there are no variables to display. -emptyVariablesText=No variables to display - -# LOCALIZATION NOTE (scopeLabel): The text that is displayed in the variables -# pane as a header for each variable scope (e.g. "Global scope, "With scope", -# etc.). -scopeLabel=%S scope - -# LOCALIZATION NOTE (watchExpressionsScopeLabel): The name of the watch -# expressions scope. This text is displayed in the variables pane as a header for -# the watch expressions scope. -watchExpressionsScopeLabel=Watch expressions - -# LOCALIZATION NOTE (globalScopeLabel): The name of the global scope. This text -# is added to scopeLabel and displayed in the variables pane as a header for -# the global scope. -globalScopeLabel=Global - -# LOCALIZATION NOTE (variablesViewErrorStacktrace): This is the text that is -# shown before the stack trace in an error. -variablesViewErrorStacktrace=Stack trace: - -# LOCALIZATION NOTE (variablesViewMoreObjects): the text that is displayed -# when you have an object preview that does not show all of the elements. At the end of the list -# you see "N more..." in the web console output. -# This is a semi-colon list of plural forms. -# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals -# #1 number of remaining items in the object -# example: 3 more… -variablesViewMoreObjects=#1 more…;#1 more… - -# LOCALIZATION NOTE (variablesEditableNameTooltip): The text that is displayed -# in the variables list on an item with an editable name. -variablesEditableNameTooltip=Double click to edit - -# LOCALIZATION NOTE (variablesEditableValueTooltip): The text that is displayed -# in the variables list on an item with an editable value. -variablesEditableValueTooltip=Click to change value - -# LOCALIZATION NOTE (variablesCloseButtonTooltip): The text that is displayed -# in the variables list on an item which can be removed. -variablesCloseButtonTooltip=Click to remove - -# LOCALIZATION NOTE (variablesEditButtonTooltip): The text that is displayed -# in the variables list on a getter or setter which can be edited. -variablesEditButtonTooltip=Click to set value - -# LOCALIZATION NOTE (variablesEditableValueTooltip): The text that is displayed -# in a tooltip on the "open in inspector" button in the the variables list for a -# DOMNode item. -variablesDomNodeValueTooltip=Click to select the node in the inspector - -# LOCALIZATION NOTE (configurable|...|Tooltip): The text that is displayed -# in the variables list on certain variables or properties as tooltips. -# Expanations of what these represent can be found at the following links: -# https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty -# https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible -# https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen -# https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed -# It's probably best to keep these in English. -configurableTooltip=configurable -enumerableTooltip=enumerable -writableTooltip=writable -frozenTooltip=frozen -sealedTooltip=sealed -extensibleTooltip=extensible -overriddenTooltip=overridden -WebIDLTooltip=WebIDL - -# LOCALIZATION NOTE (variablesSeparatorLabel): The text that is displayed -# in the variables list as a separator between the name and value. -variablesSeparatorLabel=: - -# LOCALIZATION NOTE (watchExpressionsSeparatorLabel2): The text that is displayed -# in the watch expressions list as a separator between the code and evaluation. -watchExpressionsSeparatorLabel2=\u0020→ - -# LOCALIZATION NOTE (functionSearchSeparatorLabel): The text that is displayed -# in the functions search panel as a separator between function's inferred name -# and its real name (if available). -functionSearchSeparatorLabel=← - -# LOCALIZATION NOTE (resumptionOrderPanelTitle): This is the text that appears -# as a description in the notification panel popup, when multiple debuggers are -# open in separate tabs and the user tries to resume them in the wrong order. -# The substitution parameter is the URL of the last paused window that must be -# resumed first. -resumptionOrderPanelTitle=There are one or more paused debuggers. Please resume the most-recently paused debugger first at: %S - -variablesViewOptimizedOut=(optimized away) -variablesViewUninitialized=(uninitialized) -variablesViewMissingArgs=(unavailable) - -anonymousSourcesLabel=Anonymous Sources - -experimental=This is an experimental feature diff --git a/bin/cypress-server.js b/bin/cypress-server.js deleted file mode 100755 index e989431fec..0000000000 --- a/bin/cypress-server.js +++ /dev/null @@ -1,47 +0,0 @@ -"use strict"; - -const express = require("express"); -const bodyParser = require("body-parser"); -const fs = require('fs'); -const path = require('path'); - -/** - saves a fixture file to src/test/fixtures - - @param name - name of the fixture file - @param text - fixture json text -*/ -function saveFixture(name, text) { - function getFixtureFile(name) { - const fixturePath = path.join(__dirname, "../src/test/fixtures"); - const fixtureFile = path.join(fixturePath, name + ".json"); - if (!fs.existsSync(fixturePath)) { - throw new Error("Could not find fixture " + name); - } - - return fixtureFile; - } - - const fixtureFile = getFixtureFile(name); - fs.writeFileSync(fixtureFile, text) -} - -const app = express(); -app.use(bodyParser.urlencoded({ extended: false })); -app.use(bodyParser.json({ limit: "50mb" })); - -app.post("/save-fixture", function(req, res) { - const fixtureName = req.body.fixtureName; - const fixtureText = req.body.fixtureText; - saveFixture(fixtureName, fixtureText); - - res.send(`saved fixture ${fixtureName}`); -}); - -app.listen(8001, "localhost", function(err, result) { - if (err) { - console.log(err); - } - - console.log("Development Server Listening at http://localhost:8001"); -}); diff --git a/bin/dev-server.js b/bin/dev-server.js deleted file mode 100644 index a1dcc0ad75..0000000000 --- a/bin/dev-server.js +++ /dev/null @@ -1,27 +0,0 @@ -const fs = require("fs"); -const path = require("path"); -const serveIndex = require("serve-index"); -const express = require("express"); - -const toolbox = require("devtools-local-toolbox/index"); -const feature = require("devtools-config"); -const getConfig = require("./getConfig"); - -const envConfig = getConfig(); -feature.setConfig(envConfig); - -const webpackConfig = require("../webpack.config"); -toolbox.startDevServer(envConfig, webpackConfig); - -const examples = express(); -examples.use(express.static("src/test/examples")); -examples.use(serveIndex("src/test/examples", { icons: true })); - -const examplesPort = feature.getValue("development.examplesPort"); -examples.listen(examplesPort, "0.0.0.0", (err, result) => { - if (err) { - console.log(err); - } else { - console.log(`View debugger examples at http://localhost:${examplesPort}`); - } -}); diff --git a/bin/download-firefox-artifact b/bin/download-firefox-artifact deleted file mode 100755 index 7b6c6cf0b8..0000000000 --- a/bin/download-firefox-artifact +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env bash - -ROOT=`dirname $0` -FIREFOX_PATH="$ROOT/../firefox" - -# check that mercurial is installed -if [ -z "`command -v hg`" ]; then - echo >&2 "mercurial is required for mochitests, use 'brew install mercurial' on MacOS"; - exit 1; -fi - -if [ -d "$FIREFOX_PATH" ]; then - # convert path to absolute path - FIREFOX_PATH=$(cd "$ROOT/../firefox"; pwd) - - # If we already have Firefox locally, just update it - cd "$FIREFOX_PATH"; - - if [ -n "`hg status`" ]; then - read -p "There are local changes to Firefox which will be overwritten. Are you sure? [Y/n] " -r - if [[ $REPLY == "n" ]]; then - exit 0; - fi - - # If the mochitest dir has been symlinked, remove it as revert - # does not follow symlinks. - if [ -h "$FIREFOX_PATH/devtools/client/debugger/new/test/mochitest" ]; then - rm "$FIREFOX_PATH/devtools/client/debugger/new/test/mochitest"; - fi - - hg revert -a - fi - - hg pull - hg update -C -else - echo "Downloading Firefox source code, requires about 10-30min depending on connection" - hg clone https://hg.mozilla.org/mozilla-central/ "$FIREFOX_PATH" - # if somebody cancels (ctrl-c) out of the long download don't continue - if [ $? -ne 0 ]; then - exit 1; - fi - cd "$FIREFOX_PATH" - - # Make an artifact build so it builds much faster - echo " -ac_add_options --enable-artifact-builds -mk_add_options MOZ_OBJDIR=./objdir-frontend -" > .mozconfig -fi diff --git a/bin/firefox-driver.js b/bin/firefox-driver.js deleted file mode 100755 index 724dc0ac65..0000000000 --- a/bin/firefox-driver.js +++ /dev/null @@ -1,94 +0,0 @@ - -const webdriver = require("selenium-webdriver"); -const firefox = require("selenium-webdriver/firefox"); -const By = webdriver.By; -const until = webdriver.until; -const Key = webdriver.Key; -const minimist = require("minimist"); -const url = require('url'); - - -const args = minimist(process.argv.slice(2), -{ - boolean: ["start", "tests", "websocket"], - string: ["location"], -}); - -const isWindows = /^win/.test(process.platform); -const shouldStart = args.start; -const isTests = args.tests; -const useWebSocket = args.websocket; - -function binaryArgs() { - return [ - (!isWindows ? "-" : "") + - "-start-debugger-server=" + - (useWebSocket ? "ws:6080" : "6080") - ]; -} - -function firefoxBinary() { - let binary = new firefox.Binary(); - - binary.addArguments(binaryArgs()); - - return binary; -} - -function firefoxProfile() { - let profile = new firefox.Profile(); - - profile.setPreference("devtools.debugger.remote-port", 6080); - profile.setPreference("devtools.debugger.remote-enabled", true); - profile.setPreference("devtools.chrome.enabled", true); - profile.setPreference("devtools.debugger.prompt-connection", false); - profile.setPreference("devtools.debugger.remote-websocket", useWebSocket); - - return profile; -} - -function start() { - let options = new firefox.Options(); - - options.setProfile(firefoxProfile()); - options.setBinary(firefoxBinary()); - - const driver = new webdriver.Builder() - .forBrowser("firefox") - .setFirefoxOptions(options) - .build(); - - return driver; -} - -if (shouldStart) { - const driver = start(); - let location = url.parse('about:blank'); - if (args.location) { - location = url.parse(args.location); - } - if (location.protocol === null) { - location.protocol = 'http:'; - } - driver.get(url.format(location)); - setInterval(() => {}, 100); -} - -function getResults(driver) { - driver - .findElement(By.id("mocha-stats")) - .getText().then(results => { - console.log("results ", results); - const match = results.match(/failures: (\d*)/); - const resultCode = parseInt(match[1], 10) > 0 ? 1 : 0; - process.exit(resultCode); - }); -} - -if (isTests) { - const driver = start(); - driver.get("http://localhost:8003"); - setTimeout(() => getResults(driver), 5000); -} - -module.exports = { start, By, Key, until }; diff --git a/bin/getConfig.js b/bin/getConfig.js deleted file mode 100644 index d3cafa17ce..0000000000 --- a/bin/getConfig.js +++ /dev/null @@ -1,25 +0,0 @@ -const merge = require("lodash").merge; -const fs = require("fs"); -const path = require("path"); - -function getConfig() { - const applicationConfig = require("../configs/application.json"); - const firefoxConfig = require("../configs/firefox-panel.json"); - const developmentConfig = require("../configs/development.json"); - - let localConfig = {}; - if (fs.existsSync(path.resolve(__dirname, "../configs/local.json"))) { - localConfig = require("../configs/local.json"); - } - - if (process.env.TARGET === "firefox-panel") { - return firefoxConfig; - } - - const envConfig = process.env.TARGET === "application" ? - applicationConfig : developmentConfig; - - return merge({}, envConfig, localConfig); -} - -module.exports = getConfig; diff --git a/bin/import-deps.js b/bin/import-deps.js deleted file mode 100644 index 63c0724501..0000000000 --- a/bin/import-deps.js +++ /dev/null @@ -1,29 +0,0 @@ - -const fs = require("fs"); -const glob = require("glob").sync; -const path = require("path"); - -const getConfig = require("../config/config").getConfig; -const feature = require("../config/feature"); -const config = getConfig(); -feature.setConfig(config); - -const geckoDir = feature.getValue("firefox.geckoDir"); -if (!geckoDir) { - console.log("Set firefox.geckoDir in your local.json config."); - exit(); -} - -glob("src/lib/devtools/**/*.js").forEach((debuggerFile) => { - const geckoFilePath = path.join( - geckoDir, - path.relative("src/lib/", debuggerFile) - ); - - if (fs.existsSync(geckoFilePath)) { - const fileText = fs.readFileSync(geckoFilePath, "utf8"); - fs.writeFileSync(debuggerFile, fileText); - } else { - console.log(`file: ${geckoFilePath} does not exist`); - } -}); diff --git a/bin/install-chrome b/bin/install-chrome deleted file mode 100755 index d1128131ad..0000000000 --- a/bin/install-chrome +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env bash - -curl -L -o google-chrome.deb https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb -sudo dpkg -i google-chrome.deb -sudo sed -i 's|HERE/chrome\"|HERE/chrome\" --disable-setuid-sandbox|g' /opt/google/chrome/google-chrome -rm google-chrome.deb diff --git a/bin/install-firefox b/bin/install-firefox deleted file mode 100755 index 6521ad0283..0000000000 --- a/bin/install-firefox +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash - -wget https://ftp.mozilla.org/pub/firefox/releases/46.0/linux-x86_64/en-US/firefox-46.0.tar.bz2 -tar -xjf firefox-46.0.tar.bz2 -sudo rm -rf /opt/firefox46 -sudo rm /usr/bin/firefox -sudo mv firefox /opt/firefox46 -sudo ln -s /opt/firefox46/firefox /usr/bin/firefox diff --git a/bin/make-firefox-bundle b/bin/make-firefox-bundle deleted file mode 100755 index 0e88902215..0000000000 --- a/bin/make-firefox-bundle +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/sh - -if [ -z "$1" ]; then - echo "Usage: $0 " - exit 1 -fi - -if [ "$2" == "--symlink-mochitests" ]; then - SYMLINK_MOCHITESTS=1 -fi - -ROOT=`dirname $0` -DEBUGGER_PATH="$1/devtools/client/debugger/new" -PROPERTIES_PATH="$1/devtools/client/locales/en-US/" -REV=`git log -1 --pretty=oneline` - -if [ ! -d "$DEBUGGER_PATH" ]; then - echo "Cannot find debugger at $DEBUGGER_PATH" - exit 2 -fi - -( - cd "$DEBUGGER_PATH"; - if [ -d "DEBUGGER_PATH/.git" ]; then - if ! git log --oneline bundle.js | head -n 1 | - grep "UPDATE_BUNDLE" > /dev/null; then - echo "\033[31mWARNING\033[0m: bundle has changed on mozilla-central"; - fi - fi -); - -TARGET=firefox-panel node_modules/.bin/webpack - -echo "// Generated from: $REV\n" | cat - assets/build/bundle.js > "$DEBUGGER_PATH/bundle.js" -cp assets/build/source-map-worker.js "$DEBUGGER_PATH" -cp assets/build/pretty-print-worker.js "$DEBUGGER_PATH" -cp assets/build/styles.css "$DEBUGGER_PATH" -cp assets/images/* "$DEBUGGER_PATH/images" -cp assets/locales/debugger.properties "$PROPERTIES_PATH" - -rm -r "$DEBUGGER_PATH/test/mochitest" -if [ -n "$SYMLINK_MOCHITESTS" ]; then - ln -s `pwd -P`"/$ROOT/../src/test/mochitest/" "$DEBUGGER_PATH/test/mochitest" -else - rsync -avz src/test/mochitest/ "$DEBUGGER_PATH/test/mochitest" -fi - -# Make sure a rebuild uses the new tests -touch "$DEBUGGER_PATH/test/mochitest/browser.ini" diff --git a/bin/mocha-server.js b/bin/mocha-server.js deleted file mode 100755 index 145f622ab1..0000000000 --- a/bin/mocha-server.js +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/env node -"use strict"; - -const path = require("path"); -const webpack = require("webpack"); -const express = require("express"); -const projectConfig = require("../webpack.config"); -const webpackDevMiddleware = require("webpack-dev-middleware"); -const fs = require("fs"); - -function recursiveReaddirSync(dir) { - let list = []; - const files = fs.readdirSync(dir); - - files.forEach(function(file) { - const stats = fs.lstatSync(path.join(dir, file)); - if (stats.isDirectory()) { - list = list.concat(recursiveReaddirSync(path.join(dir, file))); - } else { - list.push(path.join(dir, file)); - } - }); - - return list; -} - -function getTestPaths(dir) { - const paths = recursiveReaddirSync(dir); - - return paths.filter(p => { - const inTestDirectory = path.dirname(p).includes("tests"); - const inIntegrationDir = path.dirname(p).includes("integration"); - const aHiddenFile = path.basename(p).charAt(0) == "."; - return inTestDirectory && !aHiddenFile && !inIntegrationDir; - }); -} - -const testPaths = getTestPaths(path.join(__dirname, "../src")); - -projectConfig.entry.bundle = projectConfig.entry.bundle.concat(testPaths); -const config = Object.assign({}, projectConfig, {}); - -const app = express(); -const compiler = webpack(config); - -app.use(express.static("public")); -app.use(express.static("node_modules")); - -app.use(webpackDevMiddleware(compiler, { - publicPath: projectConfig.output.publicPath, - noInfo: true, - stats: { - colors: true - } -})); - -app.get("/", function(req, res) { - res.sendFile(path.join(__dirname, "../mocha-runner.html")); -}); - -app.listen(8003, "localhost", function(err, result) { - if (err) { - console.log(err); - } - - console.log("Listening at http://localhost:8003"); -}); diff --git a/bin/prepare-mochitests-dev b/bin/prepare-mochitests-dev deleted file mode 100755 index 71c08782b9..0000000000 --- a/bin/prepare-mochitests-dev +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash - -ROOT=`dirname $0` -FIREFOX_PATH="$ROOT/../firefox" - -# This will either download or update the local Firefox repo -"$ROOT/download-firefox-artifact" - -# Update the debugger files, build firefox, and run all the mochitests -"$ROOT/make-firefox-bundle" "$FIREFOX_PATH" --symlink-mochitests -cd "$FIREFOX_PATH" -./mach build diff --git a/bin/run-mochitests-docker b/bin/run-mochitests-docker deleted file mode 100755 index 812aa91398..0000000000 --- a/bin/run-mochitests-docker +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh - -TARGET=firefox-panel node_modules/.bin/webpack - -docker run -it \ - -v `pwd`/assets/build/bundle.js:/firefox/devtools/client/debugger/new/bundle.js \ - -v `pwd`/assets/build/source-map-worker.js:/firefox/devtools/client/debugger/new/source-map-worker.js \ - -v `pwd`/assets/build/pretty-print-worker.js:/firefox/devtools/client/debugger/new/pretty-print-worker.js \ - -v `pwd`/assets/build/styles.css:/firefox/devtools/client/debugger/new/styles.css \ - -v `pwd`/assets/images:/firefox/devtools/client/debugger/new/images \ - -v `pwd`/src/test/mochitest:/firefox/devtools/client/debugger/new/test/mochitest \ - -v "/tmp/.X11-unix:/tmp/.X11-unix:rw" \ - -e "DISPLAY=unix$DISPLAY" \ - --ipc host \ - jlongster/mochitest-runner \ - /bin/bash -c "export SHELL=/bin/bash; touch devtools/client/debugger/new/test/mochitest/browser.ini && ./mach mochitest --subsuite devtools devtools/client/debugger/new/test/mochitest/" diff --git a/bin/update-docker b/bin/update-docker deleted file mode 100755 index 7d7fe546eb..0000000000 --- a/bin/update-docker +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env bash - -DOWNLOADS_PATH=${DOWNLOADS_PATH:-"$HOME/downloads"} - -mkdir -p $DOWNLOADS_PATH - -if [[ -e $DOWNLOADS_PATH/mochitest-runner.tar ]]; then - time docker load -i $DOWNLOADS_PATH/mochitest-runner.tar; -fi - -docker images - -time docker pull jlongster/mochitest-runner - -docker images - -time docker save jlongster/mochitest-runner > $DOWNLOADS_PATH/mochitest-runner.tar diff --git a/circle.yml b/circle.yml deleted file mode 100644 index 7c6cb8ab86..0000000000 --- a/circle.yml +++ /dev/null @@ -1,43 +0,0 @@ -machine: - node: - version: 7.0 - services: - - docker - environment: - DOWNLOADS_PATH: "$HOME/downloads" - YARN_PATH: "$HOME/.yarn-cache" - post: - - mkdir -p $DOWNLOADS_PATH - - mkdir -p $YARN_PATH - -checkout: - post: - - mv configs/ci.json configs/local.json -test: - override: - - mkdir -p $CIRCLE_TEST_REPORTS/mocha - - node src/test/node-unit-tests.js --ci - - ./bin/run-mochitests-docker - - npm run firefox-unit-test - post: - - npm run lint-css - - npm run lint-js - - npm run flow - -dependencies: - pre: - cache_directories: - - ~/downloads - - ~/.yarn-cache - - ~/.yarn - override: - - npm i -g yarn@0.16.1 - - npm i -g jasonlaster/lerna - - yarn install - - ./bin/update-docker - -experimental: - notify: - branches: - only: - - master diff --git a/configs/application.json b/configs/application.json deleted file mode 100644 index 566904c005..0000000000 --- a/configs/application.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "title": "Debugger", - "environment": "development", - "baseWorkerURL": "http://localhost:8000/assets/build/", - "host": "http://localhost:8000", - "theme": "light", - "logging": { - "client": false, - "firefoxProxy": false, - "actions": false - }, - "features": { - "watchExpressions": false, - "editorSearch": false - }, - "chrome": { - "debug": true, - "host": "localhost", - "port": 9222 - }, - "node": { - "debug": true, - "host": "localhost", - "port": 9229 - }, - "firefox": { - "webSocketConnection": false, - "proxyHost": "localhost:9000", - "websocketHost": "localhost:6080" - }, - "development": { - "serverPort": 8000, - "examplesPort": 7999 - } -} diff --git a/configs/ci.json b/configs/ci.json deleted file mode 100644 index 2091bbc267..0000000000 --- a/configs/ci.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "features": { - "sourceMaps": true, - "prettyPrint": true, - "watchExpressions": true - }, - "chrome": { - "debug": true - } -} diff --git a/configs/development.json b/configs/development.json deleted file mode 100644 index 2c1828ebea..0000000000 --- a/configs/development.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "title": "Debugger", - "environment": "development", - "baseWorkerURL": "http://localhost:8000/assets/build/", - "host": "", - "theme": "light", - "logging": { - "client": false, - "firefoxProxy": false, - "actions": false - }, - "features": { - "watchExpressions": false, - "editorSearch": false - }, - "chrome": { - "debug": true, - "host": "localhost", - "port": 9222 - }, - "node": { - "debug": true, - "host": "localhost", - "port": 9229 - }, - "firefox": { - "webSocketConnection": false, - "proxyHost": "localhost:9000", - "websocketHost": "localhost:6080" - }, - "development": { - "serverPort": 8000, - "examplesPort": 7999 - } -} diff --git a/configs/firefox-panel.json b/configs/firefox-panel.json deleted file mode 100644 index acfa7ecdbb..0000000000 --- a/configs/firefox-panel.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "environment": "firefox-panel", - "baseWorkerURL": "resource://devtools/client/debugger/new/", - "host": "", - "logging": false, - "clientLogging": false -} diff --git a/configs/local.sample.json b/configs/local.sample.json deleted file mode 100644 index fdbdb4e06b..0000000000 --- a/configs/local.sample.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "theme": "light", - "hotReloading": true, - "logging": { - "actions": false - }, - "features": {} -} diff --git a/docs/debugger-html-react-redux-overview.md b/docs/debugger-html-react-redux-overview.md deleted file mode 100644 index 15438429fd..0000000000 --- a/docs/debugger-html-react-redux-overview.md +++ /dev/null @@ -1,673 +0,0 @@ -# Table of Contents -1. [Architecture](#Introduction) -2. [Components](#components) -3. [Component Data](#componentdata) -4. [Reducers](#reducers) -5. [Actions](#actions) - - - -debugger.html -============= - -Debugger.html is an open source project that is built on top of React and Redux that functions as a standalone debugger for Firefox, Chrome and Node. This project is being created to provide a debugger that is stand-alone and does not require a specific browser tool to do debugging. - -This document gives a detailed view of the components, actions and reducers that make up the debugger.html project. Prior knowledge of React and Redux is suggested. React documentation can be found [here](https://facebook.github.io/react/docs/getting-started.html). Redux documentation can be found [here](http://redux.js.org/). As with most documentation related to code, this document may be out of date. The last edit date occurred on August 30, 2016. If you find issues in the documentation please file an issue as described in the [contributing](https://github.com/devtools-html/debugger.html/blob/master/CONTRIBUTING.md#writing-documentation-book) guide. - -#Architecture - - -Debugger.html is a React-Redux based application — the UI is constructed using React Components. the follow illustration provides a simplictic high level view: - -![](https://docs.google.com/drawings/d/1JTDI-62CG29M37rpTGIDh70rOTuCmJf1VqxCKPe9zxM/pub?w=960&h=720) -[Click here to Edit](https://docs.google.com/drawings/d/1JTDI-62CG29M37rpTGIDh70rOTuCmJf1VqxCKPe9zxM/edit?usp=sharing) - -Application-critical objects are stored in one -global state object (housed in a Redux store) that some components have -access to. Many components are not aware of this state but are passed in -values to render using React properties. - -In the Debugger.html project we -also often use React’s setState to manage component local state. For -example, storing the state of a tree in the sources view or using it in -the App component to remember if the file search box is being displayed -(cmd->p). - -When a user -manipulates the UI, Redux Actions are fired to collect payload -data, which affects the state of the application for the given -operation. Actions set a specific type of operation for the store and -dispatch the event. - -Reducers handle all actions and decide the new -application state based on the action type. You can think of a reducer -as a set of functions that take a specific action type and the current -state of the app as parameters and returns the new state of the -application. - -The Store is a JavaScript object that contains and manages -the state of the application. After the Reducers create a new version -of the state, the store will fire a re-rendering of all the -components. Note that a new state is created every time — the old state -is not modified. - -React uses a Virtual DOM; only required changes to the -actual DOM will be rendered. - -#[Components](https://github.com/devtools-html/debugger.html/tree/master/src/components) - - -debbuger.html uses React [Components](https://github.com/devtools-html/debugger.html/tree/master/src/components) to render portions of the -application. Each component’s source code is located under the -src/components folder. In this section we will cover how the -presentation pieces fit together; later we will discuss -how debugger.html uses Redux to wire up data to each of the components. - -The top-level component is the App component; it encapsulates all -other components. Presented below is an overview of the component -architectural relationships: - - -![](https://docs.google.com/drawings/d/1cIa-Cf2pPi3vCKvsCrUSfC1_1LG3XDH7GpNKmWIIKWY/pub?w=960&h=720) -[Click here to Edit](https://docs.google.com/drawings/d/1cIa-Cf2pPi3vCKvsCrUSfC1_1LG3XDH7GpNKmWIIKWY/edit) - - -The App component uses two SplitBox components to separate the -presentation of the app into three different sections. Two Draggable -components are used to allow each of the sections to be expanded or -collapsed. - -![](https://docs.google.com/drawings/d/1lAEyyci8SQZzh4Dk-EowX0wGnvyOISGO3sqdtzgQqoo/pub?w=960&h=720) -[Click here to Edit](https://docs.google.com/drawings/d/1lAEyyci8SQZzh4Dk-EowX0wGnvyOISGO3sqdtzgQqoo/edit?usp=sharing) -##Source tree view - -The left-most section of the application displays the source tree for -the application being debugged. Three components are used to manage -the display of this data: - -* The Sources component is -aware of the Redux state and the other components are not — it passes required properties to be rendered down to the other -two. - -* The SourcesTree component is primarily responsible for rendering -the tree with a set of files/folders that are passed in as a property. - -* The ManagedTree component uses React local State to track which nodes -have been expanded or collapsed and which node or leaf on the tree has -focus. - -The Sources component encapsulates SourcesTree and -SourcesTree encapsulates ManagedTree. - -![](https://docs.google.com/drawings/d/1dOCy4BePfX77ky3yUTlZRnAeeFIIi4UAJcYaYmYvUcY/pub?w=960&h=720) -[Click here to Edit](https://docs.google.com/drawings/d/1dOCy4BePfX77ky3yUTlZRnAeeFIIi4UAJcYaYmYvUcY/edit?usp=sharing) -##Source editor/file search - -The center portion of the application displays either the source editor or a file search entry box. If the editor is displayed rendering is handled by three main components and one dynamic component. - -* At the top of the editor is the SourceTabs component, which is responsible for rendering tabs for every open file and highlighting the tab of the file currently open. - -* The Editor component is responsible for rendering the text, gutters and breakpoints for the currently selected file. Debugger.html uses the CodeMirror npm package to do the actual rendering. The Editor component manages calls to CodeMirror. - -* Any time a breakpoint is set, the Editor creates a dynamic component called Breakpoint. The Breakpoint component is contained in the EditorBreakpoint.js file. The BreakPoint component also makes calls to CodeMirror for actual rendering of the breakpoint within the editor. - -* The last component on the page is the SourceFooter component. This component renders buttons for blackboxing and prettify source functions. - -![](https://docs.google.com/drawings/d/1PC63VABa0x-W3hACi7ASXgawQeowbAvA_aqN_Z1wpRI/pub?w=960&h=720) -[Click here to Edit](https://docs.google.com/drawings/d/1PC63VABa0x-W3hACi7ASXgawQeowbAvA_aqN_Z1wpRI/edit?usp=sharing) - -At any time a user can search the sources for a specific string by -pressing cmd->p. This will replace all of the components in the -center section with a search box. The search box is rendered using the -Autocomplete component. - -![](images/search.png) - -##Tools view - -The farthest right section of the application is handled by many components. At the top of the component architecture is the RightSidebar component, which renders the play/pause command bar and encapsulates the Accordion component, responsible for formatting and rendering the layout including the arrow icons and headers. This component encapsulates the Breakpoints, Frames, and Scopes component: - -* The Breakpoints component renders a list of all existing breakpoints. - -* The Frames component is responsible for rendering the current call stack when a breakpoint is reached. - -* The Scopes component is responsible for rendering the current variable scopes for the given breakpoint. It uses the ObjectInpector component to render the tree for all scopes and variables. The state of which nodes are collapsed/expanded are maintained using a ManagedTree component, in similar fashion to the SourcesTree component. - -![](https://docs.google.com/drawings/d/1zHogPebNmOFT9Xx6cZsaA6R6cTQLUzBXePV9sf62chA/pub?w=960&h=720) -[Click here to Edit](https://docs.google.com/drawings/d/1zHogPebNmOFT9Xx6cZsaA6R6cTQLUzBXePV9sf62chA/edit?usp=sharing) - -#Component Data - -Some components in Debugger.html are aware of the Redux store; others are -not and are just rendering passed in properties. The Redux-aware -components are connected to the Redux store using the connect() method, as illustrated by the following code: - -```javascript -const React = require("react"); -const { connect } = require("react-redux"); -const { bindActionCreators } = require("redux"); -. -. -const actions = require("../actions"); -. -. -. - -module.exports = connect( -state => ({ pauseInfo: getPause(state), -expressions: getExpressions(state) }), -dispatch => bindActionCreators(actions, dispatch) -)(Expressions); -``` - -This example shows the Expressions component, which should be aware of -the Redux state. We are using Redux’s connect() method to connect to the -Redux store. This example is pulling in pauseInfo and Expressions from -the Redux state. Finally, all of the actions in the actions folder are -combined and the contained actionCreators in each of the files are setup -so the actions can be called directly from the component. - -#[Reducers](https://github.com/devtools-html/debugger.html/tree/master/src/reducers) - - -The [Reducers](https://github.com/devtools-html/debugger.html/tree/master/src/reducers) are all located in the src/reducers folder and are -all combined using Redux’s combineReducters() function. This function is -executed in main.js as follows: - -```javascript -const reducers = require("./reducers"); - -. - -. - -const store = createStore(combineReducers(reducers)); -``` - -All of the reducers are combined using the index.js file in the -reducers folder. In the Debbuger.html project, each reducer has an -update() function to handle actions for its slice of state. - -##Asynch-requests - -The **asynch-requests** reducer creates an array that stores a unique -sequence number for every promise being executed from an action. -It removes the sequence number from the array when a specific promise -resolves or rejects. The following image shows a snapshot of the -debugger.html state with an active promise. - -![](images/asynchreducer.png) - -##Breakpoints - -The **breakpoints reducer** is responsible for handling breakpoint -state. It adds an Immutable Map of breakpoint objects and a Boolean -value for whether breakpoints are disabled to the application state. - -![](images/breakpoints1.png) - -Each breakpoint object in the map contains information like the -location, the actual source file, whether the breakpoint is disabled, -a unique id, and the text for the breakpoint. The following is an example -of what the breakpoints state looks like for a selected breakpoint: - -![](images/breakpoints2.png) - -The breakpoints reducer handles several action types. The actions -handled by this reducer are all fired wrapped in a promise. The status -of the promise can be checked in the action object using code similar to -the following: - -```javascript -if (action.status === "start") { -``` - -Valid values are start, done and error. - -The following action types are handled: - -- ADD\_BREAKPOINT - This command adds breakpoints to the state as - shown in the image above. While the promise is being fulfilled the - loading attribute is set to true and a basic breakpoint object - is created. If the promise is completed, the location is updated - and the loading attribute is set to false. If the promise fails, the - breakpoint is deleted from the state. - -- TOGGLE\_BREAKPOINTS - Sets the value of the breakpointsDisabled - attribute and is used to disable or enable all breakpoints. - -- SET\_BREAKPOINT\_CONDITION - This action sets the condition - attribute for a specific breakpoint. This functionality is currently not implemented in the UI. - -- REMOVE\_BREAKPOINT - This action actually handles disabling or - removing a breakpoint. If the breakpoint is being disabled the - disabled attribute of the breakpoint is set to false. If - the breakpoint is removed it is deleted from the breakpoints state. - - -The breakpoints reducer additionally supplies functions to -retrieve information from the breakpoints state. For example the -getBreakpointsForSource() function returns all breakpoints for a given -source file. The editor component uses this to retrieve all the -breakpoints for the currently opened file. - - - -##Events-listeners - -The **events-listeners** reducer is responsible for managing the state -for the current list of DOM events that currently have listeners bound -in the web application being debugged. This reducer also stores the -current listeners selected for the debugger to break on. Additionally -this reducer manages state that keeps track of when the event listeners -are being fetched with the fetchingListeners flag. - -\*\*As of this moment the UI for this feature is not implemented. I also -did not see gThreadClient created. - -![](images/eventlisteners.png) - -##Pause - -The **pause** reducer is responsible for managing state variables needed -to primarily handle pause and resume conditions in the debugger. These -pause conditions can occur because of a set breakpoint in code being -debugged, an exception, or an event listener being -debugged. - -![](images/pause.png) - -* The pause object stores information like why the debugger paused, the -current call stack frame, the current source location, and the current -variable scope. - -* The frames object stores all the frames for the current -call stack. - -* The selectedFrame object stores the call stack frame -currently selected in the Debugger.html UI. - -* The loadedObjects object -stores the currently selected and expanded variable in the scopes pane. - -\*\*The expessions object stores all of the current watch expressions, -which is not implemented in the UI yet. - -The pause reducer handles the following action types: - -- PAUSE – Handles loading and updating the state for all the variables - described above. - -- RESUME – Clears all state variables associated with a pause. - -- BRAKE\_ON\_NEXT – This action type is triggered when a user presses - the pause button and informs the JavaScript engine to break on the - next JavaScript statement. Until the engine actually breaks, a flag that tracks the status is stored in state. - -- LOADED\_FRAMES – This action type occurs when all the frames for the - call stack have been retrieved. As stated above these are stored in - the application state. - -- SELECT\_FRAME - This action type occurs when a user is selecting - different frames of the call stack while the debugger is paused. - -- LOAD\_OBJECT\_PROPERTIES – This action type occurs when a user is - expanding the variable tree under the scope pane. The currently - expanded variable is then stored in state. - -- PAUSE\_ON\_EXCEPTIONS – This action type occurs when the settings - (pause on exceptions and ignore caught exceptions) for the debugger - are changed. These values are then stored in state. - -- ADD\_EXPRESSION – This action type occurs when a new watch - expression has been added. - -- EVALUATE\_EXPRESSION – This action type is triggered when a watch - expression is being evaluated. - -- UPDATE\_EXPRESSION – This action type is triggered when updating a - watch expression. - -- DELETE\_EXPRESSION – This action type is triggered when a watch - expression is deleted. - -The pause reducer also has many getter functions to retrieve portions of -state that are stored by this reducer. - - -##Sources - -The **sources** reducer is responsible for maintaining state variables -that are used in the managing of opening and closing source files in the -debugger. The state variables for this reducer contain elements that -manage things like sources in the source tree, the currently open file, the -source text for all open files, source maps for source files, and open -tabs within the editor. - -* The sources object contains an array of all the sources in the source -tree and is built when a project is loaded into the debugger. When the -prettify source button is selected a new source is added to the sources -object representing the new text prettified. - -* The selectedSource object -contains information on the currently opened file in the editor and is -altered when new files are opened or tabs are switched. - -* The sourcesText -state variable is an array of objects where each object contains the -source text for an open file in the debugger. - -* The sourceMaps object is -similar to sourcesText but it contains the associated source map text. - -* The tabs object manages how many tabs are opened and what file is -associated with each. - -![](images/sources.png) - -The sources reducer handles the following action types: - -- ADD\_SOURCE – This action type occurs when a project is loading and - source files are being added to the source tree. Additionally - prettify source will add additional files. - -- ADD\_SOURCES – This type is similar to ADD\_SOURCE but takes a map - of source files. Currently this type is not used in the debugger. - -- LOAD\_SOURCE\_MAP – This action type occurs when a source map is - loaded for a specific source file. - -- SELECT\_SOURCE – This action type is triggered when a file is opened - or a different tab is selected in the debugger. - -- SELECT\_SOURCE\_URL – This action type is triggered when a URL - designates the selected source file. Need more data on this one. - -- CLOSE\_TAB – This action type is triggered when a tab is closed in - the debugger. The tab is cleared from state and the proper source - is selected. - -- LOAD\_SOURCE\_TEXT – This event is triggered when the text of a file - is being loaded. The event is wrapped in a promise so it will be - called twice — once when it is started and once when it is complete. - Once loaded the text is loaded in the sourcesText state object. - -- BLACKBOX – This event is triggered when black boxing is enabled and - the button is selected for a given source. The black box status for - each file is stored in the sources state object. - -- TOGGLE\_PRETTY\_PRINT – The event is triggered when a toggling of - the prettify source button is selected. The reducer updates the - sourcesText with the new text and updates the isPrettyPrinted flag - in the sources state object. - -The sources reducer also has many getter functions to retrieve portions -of state that are handled in this reducer. - -##Tabs - -The **tabs** reducer is used to track which connected application is -being debugged. When the main debugger is started every connected -application will be displayed. For example, all the open tabs in a -Firefox browser that are connected to the debugger will be shown. - -![](images/maintab.png) - -This reducer stores two objects in state: - -* The tabs object stores an -array of connected applications. - -* The selectedTab object stores the -current application that is being debugged. - -![](images/tabs.png) - -The tabs reducer handles the following action types: - -- ADD\_TABS – This action type is triggered for every connected - application when the debugger is started. - -- SELECT\_TAB – This action type is triggered when a specific - application is selected for debugging. - -#[Actions](https://github.com/devtools-html/debugger.html/tree/master/src/actions) - -The [actions](https://github.com/devtools-html/debugger.html/tree/master/src/actions) in debugger.html are all located in the -src/actions folder; there is an action file corresponding to - each reducer, which is responsible for dispatching the -proper event when the application state needs to be modified. In this -section we will cover each action file. As stated earlier, many of the -actions defined in these files are actionCreators that are setup to use -in a component via the bindActionsCreator() Redux method. - -##breakpoints - -The **breakpoints** action file handles manipulating breakpoints in the -debugger - -The breakpoints file exports the following functions: - -- enableBreakpoint() - This function dispatches the ADD\_BREAKPOINT - action and is called from the breakpoints component when a user - selects the checkbox next to a breakpoint listed in the Breakpoints - category on the right bar. Breakpoints listed here are currently enabled or previously - enabled and now disabled, therefore this function is only called - when re-enabling an existing breakpoint. - -- addBreakpoint() - This function dispatches the ADD\_BREAKPOINT action - and is called from the Editor component when a user clicks on the - left gutter next to the source text and no breakpoint is currently - on this line. - -- disableBreakpoint - This function dispatches the REMOVE\_BREAKPOINT - action and is called from the breakpoints component when clicking on - the checkbox next to a breakpoint listed in the right bar under the - Breakpoints category. Ultimately the breakpoint is not removed — - the disabled flag is set for the specific breakpoint, which is - handled in the breakpoints reducer. - -- removeBreakpoint() - This function dispatches the REMOVE\_BREAKPOINT action - and is called from the editor component when a user clicks on an - existing breakpoint from the left side gutter. - -- toggleAllBreakpoints() – This function dispatches the - TOGGLE\_BREAKPOINTS action and is called from the RightSideBar - component when the disable/enable all breakpoints button is clicked. - This results in either disableBreakpoint() or enableBreakpoint() being - called for every breakpoint currently active. - -- setBreakpointCondition() – Currently not implemented. - -##event-listeners - -The **event-listeners** action file handles retrieving a list of all the -DOM events that currently have listeners bound in the web application -being debugged. In addition, it handles selecting specific ones for the -debugger to break on. - -The event-listeners file exports the following functions: - -- updateEventBreakpoints() – This function passes an array of DOM events that should cause the debugger to break to the connected client - being debugged. Next it dispatches the - UPDATE\_EVENT\_BREAKPOINTS action. The UI is not yet built - for this. - -- fetchEventListeners() – This function retrieves a list of DOM events that - currently have listeners bound for the application being debugged. - Once retrieved the fetchEventListeners() function dispatches the - FETCH\_EVENT\_LISTENERS action. - -##pause - -The **pause** action file handles all functions responsible for -pausing, resuming and manipulating the debugger by stepping through -code. The functions contained in this file handle several calls back and -forth with the connected client (Firefox, Chrome, Node). Most of the -client functions are defined in the -src/clients/specificclient/events.js and -src/clients/specificclient/commands.js files. The pause action -file exports the following functions: - -- addExpression() – Called from the - Expressions component, this function dispatches the ADD\_EXPRESSION action. - Expressions are passed and evaluated by the connected client. - -- updateExpression() - Called from the - Expressions component, this function dispatches the UPDATE\_EXPRESSION action. - . Expressions are passed and evaluated by the connected client. - -- deleteExpression() - Called from the - Expressions component, this function dispatches the DELETE\_EXPRESSION action. - . Expressions are passed and evaluated by the connected client. - -- resumed() – Called from the connected client, this function - dispatches the RESUME action. This - function is called anytime the connected client resumes execution - after a pause. This includes using a step function to advance - execution by one line. - -- paused() – Called from the connected client - anytime the client pauses and dispatches a PAUSED action. Before - dispatching the call stack frames, current frame, and reason - for the pause are retrieved from the connected client. These values - are all passed in the dispatched action. - -- pauseOnExceptions() – This function is called from the RightSideBar - component and dispatches the PAUSE\_ON\_EXCEPTIONS action. Before - doing this the connected client is called and passes two values to - instruct the connected client to (pause/not pause) on exceptions and - whether to ignore caught exceptions. - -- command() – This function is called indirectly by the - RightSideBar component. This is a generic function that sends - different commands to the connected client. After the command is - executed the COMMAND action is dispatched. The client commands are - defined in the src/clients/specificclient/commands.js file. - -- stepIn() – This function is called from the RightSideBar. This - function calls the command() function to pass it - to the connected client. - -- stepOut() - This function is called from the RightSideBar. This - function calls the command() function to pass it - to the connected client. - -- stepOver() - This function is called from the RightSideBar. - This function calls the command() function to pass it to the connected client. - -- resume() – This function is called from the RightSideBar when the play - button is pressed and the debugger is currently paused. This - function calls the command() function to pass it - to the connected client. - -- breakOnNext() – This function is called from the RightSideBar when the - pause button is pressed and the debugger is currently not paused. - This function calls the connected clients breakOnNext() function, - which is defined in the - src/clients/specificclient/commands.js file. After returning - from the client call the BREAK\_ON\_NEXT action is dispatched. - -- selectFrame() – This function is called from the Frames component when - a user selects a specific frame under the Call Stack UI. This - function first calls selectSource() function, which is defined in the - sources action. This loads up the editor with text for the - specific frame. The SELECT\_FRAME action is then dispatched. - -- loadObjectProperties() – This function is called from the Scopes - component, which passes the data to the ObjectInspector component as - a property to display in the variable tree under the Scopes panel. - This function is also called directly from the ObjectInspector as - the variable tree is expanded. The function calls the connected - client to retrieve the values and dispatches the - LOAD\_OBJECT\_PROPERTIES action. - - -##sources - -The **sources** action is responsible for providing functions that -support opening files in the editor, managing the tabs within the -editor and supplying black box and pretty print functionality. The sources -action file exports the following functions: - -- newSource() – This function is called from the connected - client as defined in src/clients/specificclient/events.js when - a project is loaded. In addition newSource() is called whenever a - source map is loaded to add it to the project. This function checks - to see if a source map needs to be loaded and if so dispatches the - LOAD\_SOURCE\_MAP action, then - the ADD\_SOURCE action. Finally, if this source is to be displayed - in the editor the selectSource() function is called. - -- selectSource() – This function is called any place in the - UI where a specific source needs to be displayed in the editor. This - can happen from the source tree, the tabs across the top of the - editor, in the Call Stack panel, and when the Prettify Source button - is pressed. These locations correspond to the SourcesTree, - SourceTabs, Breakpoints, and SourceFooter components. The function - first dispatches the LOAD\_SOURCE\_TEXT action, which is wrapped in - a promise. The SELECT\_SOURCE action is then dispatched. This - usually results in a LOAD\_SOURCE\_TEXT action firing first then the - SELECT\_SOURCE followed by another LOAD\_SOURCE\_TEXT when the - promise completes and the text is loaded. - -- selectSourceURL() – Currently this function is only exposed in the - src/main.js file to external clients. The function first - dispatches a SELECT\_SOURCE action and then dispatches the - SELECT\_SOURCE\_URL action. As stated above the text is loaded with - the selectSource() function. - -- closeTab() – This function is called from the SourceTabs() component - whenever a tab is closed. The function dispatches the - CLOSE\_TAB action. - -- blackbox() – This function is called from the SourceFooter component - whenever the blackBox button is pressed. The button acts as a toggle - for the file currently open in the editor. The function dispatches the - BLACKBOX action and calls the connected client to either enable or - disable black boxing on a specific file. - -- togglePrettyPrint() - This function is called from the SourceFooter - component whenever the Prettify Source button is pressed. This - function first creates a new URL for the formatted text and then - dispatches an ADD\_SOURCE action through an internal function, which - adds the new file to the project. Next, the function dispatches a - TOGGLE\_PRETTY\_PRINT action, which contains a promise that starts a - Worker thread to transform the source. The worker is defined - in assets/build/pretty-print-worker.js. The selectSource() function is then - called to select the new source. - -- loadSourceText() – This function is called whenever a source is - selected using the selectSource() function (described above) and - whenever getTextForSources() is called (described below). The - loadSourceText() function is responsible for loading the source text - for an individual file. The function first checks to see if the text - for the selected file is already is already stored in the state. If - it is, the function returns this text. If the text is not already - stored, the LOAD\_SOURCE\_TEXT action is dispatched and is wrapped - in a promise. This function will dispatch the LOAD\_SOURCE\_TEXT - once for the start of the promise and once for when it completes. It - returns the source text and if a source map is used, the text for - the source map will also be returned. These are then stored in state - by the reducer. - -- getTextForSources() – This function takes a set of source files and - calls loadSourceText() to load each file. Currently this function is - not used in debugger.html. - -##tabs - -The **tabs** action is responsible for gathering all connected -clients that can be debugged, and gathering the tabs for each application that can be debugged on the connected client. The tabs action -file exports the following functions: - -- newTabs() – This function is called from src/main.js and sets - the action type to ADD\_TABS. The action is dispatched from the - src/main.js when debugger.html is loading and displaying - the main page or when starting to debug when a specific tab - is selected. - -- selectTab() – This function is called from src/main.js when a - user has selected a specific tab from a connected application - to debug. It sets the action type to SELECT\_TAB and the action is - then dispatched in src/main.js. diff --git a/docs/feature-flags.md b/docs/feature-flags.md deleted file mode 100644 index e83a2831d2..0000000000 --- a/docs/feature-flags.md +++ /dev/null @@ -1,40 +0,0 @@ -## Feature Flags - -The debugger.html project has a system for [feature flags](https://en.wikipedia.org/wiki/Feature_toggle), a system that allows us to ship certain features which are off by default. Features must be in active development with the intention of landing in the core; feature flags are not intended for landing broken code or features which are not under active development. - -Feature flags toggle features that are either: -* experimental or in a testing phase -* designed to be configured locally - -Periodically feature flags are removed as features are either out of the experimental phase and merged into the core or are removed and no longer available. In the future we may turn on certain features for subsets of the population. - -## Configure - -All feature flags are configured in the [config directory](./config/). See the [config/README](./config/README.md) for descriptions of each flag. - -## Development - -When developing features behind a feature flag there are resources within the codebase to help you. Here are steps to follow when creating a feature flag. - -- Add an option to the [config/development.json](../config/development.json) file, default to `false` (off) -- Create a corresponding entry in the [config/README](./config/README.md) that describes the flag -- Add the code required to create the feature flag - -The `isEnabled` function checks the truthy value of a feature flag. Pass in the full object name and location for the value. Features are located within the `features` object and therefore have the name `features.X` where `X` is the name of the feature being described. - -### Example - -Search for [isEnabled](https://github.com/devtools-html/debugger.html/search?utf8=%E2%9C%93&q=isEnabled) in the code to find more examples. - -```js -// within the components directory you can require isEnabled -const { isEnabled } = require("devtools-config"); - -// feature check can be done in render() method -render() { - if (!isEnabled("pokemon-go")) { - return null; - } - return dom.div(null, 'pokestop!'); -} -``` diff --git a/docs/images/asynchreducer.png b/docs/images/asynchreducer.png deleted file mode 100644 index b661c81387..0000000000 Binary files a/docs/images/asynchreducer.png and /dev/null differ diff --git a/docs/images/breakpoints1.png b/docs/images/breakpoints1.png deleted file mode 100644 index 23c95daf37..0000000000 Binary files a/docs/images/breakpoints1.png and /dev/null differ diff --git a/docs/images/breakpoints2.png b/docs/images/breakpoints2.png deleted file mode 100644 index 8865a417c6..0000000000 Binary files a/docs/images/breakpoints2.png and /dev/null differ diff --git a/docs/images/eventlisteners.png b/docs/images/eventlisteners.png deleted file mode 100644 index bff0837d0c..0000000000 Binary files a/docs/images/eventlisteners.png and /dev/null differ diff --git a/docs/images/maintab.png b/docs/images/maintab.png deleted file mode 100644 index b657eaef8a..0000000000 Binary files a/docs/images/maintab.png and /dev/null differ diff --git a/docs/images/pause.png b/docs/images/pause.png deleted file mode 100644 index 21f83a5c81..0000000000 Binary files a/docs/images/pause.png and /dev/null differ diff --git a/docs/images/search.png b/docs/images/search.png deleted file mode 100644 index ac0c8fb4d4..0000000000 Binary files a/docs/images/search.png and /dev/null differ diff --git a/docs/images/sources.png b/docs/images/sources.png deleted file mode 100644 index 5f9daa7ba9..0000000000 Binary files a/docs/images/sources.png and /dev/null differ diff --git a/docs/images/tabs.png b/docs/images/tabs.png deleted file mode 100644 index 531e946e92..0000000000 Binary files a/docs/images/tabs.png and /dev/null differ diff --git a/docs/lerna.md b/docs/lerna.md deleted file mode 100644 index 9400accbf9..0000000000 --- a/docs/lerna.md +++ /dev/null @@ -1,17 +0,0 @@ -## Lerna - -The debugger uses [Lerna](https://github.com/lerna/lerna)to manage setting up -the Debugger and its packages. - -### How does it work? - -Lerna does two things to help setup the Debugger. First it links the Debugger's internal packages, then it installs the external dependencies. -During the linking phase, lerna figures out which packages depend on each other and installs symlinks in each packages' node_modules directory. -This setup has several benefits: - -* Packages can easily require one another -* It is easy to work on the entire project without worrying about re-installing different packages - -### Why is lerna forked? - -Lerna is forked so that the top-level package (debugger.html) can be linked with the sub-packages. This feature will hopefully be merged into Lerna soon. diff --git a/docs/local-development.md b/docs/local-development.md deleted file mode 100644 index 22fbec8b62..0000000000 --- a/docs/local-development.md +++ /dev/null @@ -1,222 +0,0 @@ -## Local Development - -* [Configs](#configs) -* [Hot Reloading](#hot-reloading) -* [Themes](#themes) -* [Internationalization](#internationalization) - * [L10N](#l10n) - * [RTL](#rtl) -* [Prefs](#prefs) -* [Flow](#flow) - -### Configs - -The local toolbox has [configs](../packages/devtools-config/README.md) for runtime configuration. - -**Local Configs** - -You can create a `configs/local.json` file to override development configs. This is great for enabling features locally or changing the theme. Copy the `local-sample` to get started. - -```bash -cp configs/local-sample.json configs/local-sample.json -``` - - -### Hot Reloading - -Hot reloading lets you make changes in React components and CSS and see the changes immediately. -Also, the changes will go into effect without changing the state of app. -Hot reloading does not work all the time, but once you get a sense of its quirks it can be a huge productivity boon. - -It can be turned on by setting `config/local.json` with the contents `{ "hotReloading: true" }`. - -### Themes - -The local debugger supports three themes: [light](https://cloud.githubusercontent.com/assets/254562/20676302/4cb04a7c-b55d-11e6-855f-654395e2c26f.png), [firebug](https://cloud.githubusercontent.com/assets/254562/20676303/4cbb0570-b55d-11e6-98b5-d1dd124345cd.png), and [dark](https://cloud.githubusercontent.com/assets/254562/20676304/4cbfbf16-b55d-11e6-9b84-3ee5595e36be.png). - - -You can change the theme by setting the `theme` field in `local.json` to `light`, `dark`, or `firebug`. [gif](http://g.recordit.co/nwBX4VBOBA.gif) - -`configs/local.json` -```json -{ - "theme": "dark" -} -``` - -### Internationalization - -The Debugger supports two types of internationalization RTL (right to left) layout and L10N (localization). - -#### L10N - -[L10N](https://github.com/devtools-html/debugger.html/blob/master/packages/devtools-local-toolbox/src/utils/L10N.js) is a global module with two methods `getStr` and `getFormatStr`. - -```js -L10N.getStr("scopes.header") -L10N.getFormatStr("editor.searchResults", index + 1, count) -``` - -#### RTL - -RTL stands for right to left and is an important feature for arabic languages and hebrew. Here's what the debugger looks like right to left [screenshot](https://cloud.githubusercontent.com/assets/394320/19226865/ef18b0d0-8eb9-11e6-82b4-8c4da702fe91.png). - -*How do I set the debugger to right to left?* - -`devtools-local-toolbox/index.html` -```html - - - - Firefox Debugger -``` - -*How do I change how something looks in rtl?* - -`public/js/components/SourceFooter.css` -```css -html:not([dir="rtl"]) .source-footer .command-bar { - float: right; -} - -html[dir="rtl"] .source-footer .command-bar { - float: left; -} -``` - -Translated strings are added to the local [strings](https://github.com/devtools-html/debugger.html/blob/master/src/strings.json) -file and m-c [debugger properties](https://dxr.mozilla.org/mozilla-central/source/devtools/client/locales/en-US/debugger.properties) file. - -### Prefs - -User preferences are stored in Prefs. Prefs uses localStorage locally and firefox's profiles in the panel. - -**Setting a default value** - -```js -pref("devtools.debugger.client-source-maps-enabled", true); -``` - -**Adding a pref** -```js -const prefs = new PrefsHelper("devtools", { - clientSourceMapsEnabled: ["Bool", "debugger.client-source-maps-enabled"], -}); -``` - -**Reading a pref** -```js -const { prefs } = require("./utils/prefs"); -console.log(prefs.clientSourceMapsEnabled) -``` - -**Setting a pref** -```js -const { prefs } = require("./utils/prefs"); -prefs.clientSourceMapsEnabled = false; -``` - -### SVGs - -We use SVGs in DevTools because they look good at any resolution. - - - -**Adding a new SVG** - -* add the SVG in [assets/images](../assets/images) -* add it to [Svg.js](../assets/images/Svg.js) - -```diff -diff --git a/assets/images/Svg.js b/assets/images/Svg.js -index 775aecf..6a7c19d 100644 ---- a/assets/images/Svg.js -+++ b/assets/images/Svg.js -@@ -24,7 +24,8 @@ const svg = { - "subSettings": require("./subSettings.svg"), - "toggleBreakpoints": require("./toggle-breakpoints.svg"), - "worker": require("./worker.svg"), -- "sad-face": require("./sad-face.svg") -+ "sad-face": require("./sad-face.svg"), -+ "happy-face": require("./happy-face.svg") - }; -``` - -**Using an SVG** - -* import the `Svg` module -* call `Svg()` - -```diff -diff --git a/src/components/Breakpoints.js b/src/components/Breakpoints.js -index 8c79f4d..6893673 100644 ---- a/src/components/Breakpoints.js -+++ b/src/components/Breakpoints.js -@@ -4,6 +4,7 @@ const { bindActionCreators } = require("redux"); - const ImPropTypes = require("react-immutable-proptypes"); - const classnames = require("classnames"); - const actions = require("../actions"); -+const Svg = require("./utils/Svg"); - const { getSource, getPause, getBreakpoints } = require("../selectors"); - const { makeLocationId } = require("../reducers/breakpoints"); - const { truncateStr } = require("../utils/utils"); -@@ -89,6 +90,7 @@ const Breakpoints = React.createClass({ - key: locationId, - onClick: () => this.selectBreakpoint(breakpoint) - }, -+ Svg("happy-face"), - dom.input({ - type: "checkbox", - className: "breakpoint-checkbox", -``` - -**Styling an SVG element** - -You can style several SVG elements (*svg*, *i*, *path*) just as you would other elements. - -* *fill* is especially useful for changing the color - - -```diff -diff --git a/src/components/Breakpoints.css b/src/components/Breakpoints.css -index 5996700..bb828d8 100644 ---- a/src/components/Breakpoints.css -+++ b/src/components/Breakpoints.css -@@ -69,3 +69,11 @@ - .breakpoint:hover .close { - display: block; - } -+ -+.breakpoint svg { -+ width: 16px; -+ position: absolute; -+ top: 12px; -+ left: 10px; -+ fill: var(--theme-graphs-full-red); -+} -``` - - -### Flow - -The debugger uses Facebook's [flow](https://flowtype.org/) type checker. - -Rationale: -* *code clarity* - helps team members understand the code -* *refactoring* - guarantees functions integrate well -* *code reviews* - adds a static check like linting - -**How do I run flow?** -``` -> flow -``` - -**How do I see a file's coverage?** -``` -> flow coverage --color -``` - -**How do I see the Debugger's flow coverage?** -``` -> npm run flow-coverage -``` diff --git a/docs/mochitests.md b/docs/mochitests.md deleted file mode 100644 index 112d51a28c..0000000000 --- a/docs/mochitests.md +++ /dev/null @@ -1,108 +0,0 @@ -We use [mochitests](https://developer.mozilla.org/en-US/docs/Mozilla/Projects/Mochitest) to do integration testing. Mochitests are part of Firefox and allow us to test the debugger literally as you would use it (as a devtools panel). While we are developing the debugger locally in a tab, it's important that we test it as a devtools panel. - -Mochitests require a local checkout of the Firefox source code. This is because they are used to test a lot of Firefox, and you would usually run them inside Firefox. We are developing the debugger outside of Firefox, but still want to test it as a devtools panel, so we've figured out a way to use them. It may not be elegant, but it allows us to ensure a high quality Firefox debugger. - -Mochitests live in `src/test/mochitest`. - -## Getting Started - -**Requirements** - -* mercurial ( `brew install mercurial` ) -* autoconf213 ( `brew install autoconf213 && brew unlink autoconf` ) - -If you haven't set up the mochitest environment yet, just run this: - -``` -./bin/prepare-mochitests-dev -``` - -This will set up everything you need. You should run this *every time* to start working on mochitests, as it makes sure your local copy of Firefox is up-to-date. - -On the first run, this will download a local copy of Firefox and set up an [artifact build](https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Build_Instructions/Artifact_builds) (just think of a super fast Firefox build). It may take a while (10-15 minutes) to download and build Firefox. - -Now, you can run the mochitests like this: - -``` -cd firefox -./mach mochitest --subsuite devtools devtools/client/debugger/new/test/mochitest/ -``` - -This works because we've symlinked the local mochitests into where the debugger lives in Firefox. Any changes to the tests in `src/test/mochitest` will be reflected and you can re-run the tests. - -Visit the [mochitest](https://developer.mozilla.org/en-US/docs/Mozilla/Projects/Mochitest) MDN page to learn more about mochitests and more advanced arguments. A few tips: - -* Passing `--jsdebugger` will open a JavaScript debugger and allow you to debug the tests (sometimes can be fickle) -* Add `{ "logging": { "actions": true } }` to your local config file to see verbose logs of all the redux actions - -### For Windows Developers - -The detailed instructions for setting up your environment to build Firefox for Windows can be found [here](https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Build_Instructions/Windows_Prerequisites). You need to install the latest `MozBuild` package. You can open a unix-flavor shell by starting: - -``` -C:\mozilla-build\start-shell.bat -``` - -In the shell, navigate to the debugger.html project folder, and follow the Getting Started instructions as mentioned. - -## Watching for Changes - -The mochitest are running against the compiled debugger bundle inside the Firefox checkout. This means that you need to update the bundle whenever you make code changes. `prepare-mochitests-dev` does this for you initially, but you can manually update it with: - -``` -./bin/make-firefox-bundle firefox -``` - -That will build the debugger and copy over all the relevant files into `firefox`, including mochitests. If you want it to only symlink the mochitests directory, pass `--symlink-mochitests` (which is what `prepare-mochitests-dev` does). - -It's annoying to have to manually update the bundle every single time though. If you want to automatically update the bundle in Firefox whenever you make a change, run this: - -``` -npm run mochitests-watch -``` - -Now you can make code changes the the bundle will be automatically built for you inside `firefox`, and you can simply run mochitests and edit code as much as you like. - -## Adding New Tests - -If you add new tests, make sure to list them in the `browser.ini` file. You will see the other tests there. Add a new entry with the same format as the others. You can also add new JS or HTML files by listing in under `support-files`. - -## API - -In addition to the standard mochtest API, we provide the following functions to help write tests. All of these expect a `dbg` context which is returned from `initDebugger` which should be called at the beginning of the test. An example skeleton test looks like this: - -```js -add_task(function* () { - const dbg = yield initDebugger("doc_simple.html", "code_simple.js"); - // do some stuff - ok(state.foo, "Foo is OK"); -}); -``` - -The Debugger Mochitest API Documentation can be found [here](https://devtools-html.github.io/debugger.html/reference#mochitest). - -## Writing Tests - -Here are a few tips for writing mochitests: - -* Only write mochitests for testing the interaction of multiple components on the page and to make sure that the protocol is working. -* By default, use the above builtin functions to drive the interaction and only dig into the DOM when you specifically want to test a component. For example, most tests should use the `addBreakpoint` command to add breakpoints, but certain tests may specifically want to test the editor gutter and left-click on that DOM element to add a breakpoint. -* The `dbg` object has the following properties: - - * `actions` - Redux actions (already bound to the store) - * `selectors` - State selectors - * `getState` - Function to get current state - * `store` - Redux store - * `toolbox` - Devtools toolbox - * `win` - The current debugger window - -* You can assert DOM structure like `is(dbg.win.document.querySelectorAll("#foo").length, 1, "...")` -* If you need to access the content page, use `ContentTask.spawn`: - -```js -ContentTask.spawn(gBrowser.selectedBrowser, null, function* () { - content.wrappedJSObject.foo(); -}); -``` - -The above calls the function `foo` that exists in the page itself. You can also access the DOM this way: `content.document.querySelector`, if you want to click a button or do other things. You can even you use assertions inside this callback to check DOM state. diff --git a/docs/reference/assets/anchor.js b/docs/reference/assets/anchor.js deleted file mode 100644 index 47d871ad40..0000000000 --- a/docs/reference/assets/anchor.js +++ /dev/null @@ -1,197 +0,0 @@ -/*! - * AnchorJS - v1.2.1 - 2015-07-02 - * https://github.com/bryanbraun/anchorjs - * Copyright (c) 2015 Bryan Braun; Licensed MIT - */ - -function AnchorJS(options) { - 'use strict'; - - this.options = options || {}; - - this._applyRemainingDefaultOptions = function(opts) { - this.options.icon = this.options.hasOwnProperty('icon') ? opts.icon : '\ue9cb'; // Accepts characters (and also URLs?), like '#', '¶', '❡', or '§'. - this.options.visible = this.options.hasOwnProperty('visible') ? opts.visible : 'hover'; // Also accepts 'always' - this.options.placement = this.options.hasOwnProperty('placement') ? opts.placement : 'right'; // Also accepts 'left' - this.options.class = this.options.hasOwnProperty('class') ? opts.class : ''; // Accepts any class name. - }; - - this._applyRemainingDefaultOptions(options); - - this.add = function(selector) { - var elements, - elsWithIds, - idList, - elementID, - i, - roughText, - tidyText, - index, - count, - newTidyText, - readableID, - anchor; - - this._applyRemainingDefaultOptions(this.options); - - // Provide a sensible default selector, if none is given. - if (!selector) { - selector = 'h1, h2, h3, h4, h5, h6'; - } else if (typeof selector !== 'string') { - throw new Error('The selector provided to AnchorJS was invalid.'); - } - - elements = document.querySelectorAll(selector); - if (elements.length === 0) { - return false; - } - - this._addBaselineStyles(); - - // We produce a list of existing IDs so we don't generate a duplicate. - elsWithIds = document.querySelectorAll('[id]'); - idList = [].map.call(elsWithIds, function assign(el) { - return el.id; - }); - - for (i = 0; i < elements.length; i++) { - - if (elements[i].hasAttribute('id')) { - elementID = elements[i].getAttribute('id'); - } else { - roughText = elements[i].textContent; - - // Refine it so it makes a good ID. Strip out non-safe characters, replace - // spaces with hyphens, truncate to 32 characters, and make toLowerCase. - // - // Example string: // '⚡⚡⚡ Unicode icons are cool--but they definitely don't belong in a URL fragment.' - tidyText = roughText.replace(/[^\w\s-]/gi, '') // ' Unicode icons are cool--but they definitely dont belong in a URL fragment' - .replace(/\s+/g, '-') // '-Unicode-icons-are-cool--but-they-definitely-dont-belong-in-a-URL-fragment' - .replace(/-{2,}/g, '-') // '-Unicode-icons-are-cool-but-they-definitely-dont-belong-in-a-URL-fragment' - .substring(0, 64) // '-Unicode-icons-are-cool-but-they-definitely-dont-belong-in-a-URL' - .replace(/^-+|-+$/gm, '') // 'Unicode-icons-are-cool-but-they-definitely-dont-belong-in-a-URL' - .toLowerCase(); // 'unicode-icons-are-cool-but-they-definitely-dont-belong-in-a-url' - - // Compare our generated ID to existing IDs (and increment it if needed) - // before we add it to the page. - newTidyText = tidyText; - count = 0; - do { - if (index !== undefined) { - newTidyText = tidyText + '-' + count; - } - // .indexOf is supported in IE9+. - index = idList.indexOf(newTidyText); - count += 1; - } while (index !== -1); - index = undefined; - idList.push(newTidyText); - - // Assign it to our element. - // Currently the setAttribute element is only supported in IE9 and above. - elements[i].setAttribute('id', newTidyText); - - elementID = newTidyText; - } - - readableID = elementID.replace(/-/g, ' '); - - // The following code builds the following DOM structure in a more effiecient (albeit opaque) way. - // ''; - anchor = document.createElement('a'); - anchor.className = 'anchorjs-link ' + this.options.class; - anchor.href = '#' + elementID; - anchor.setAttribute('aria-label', 'Anchor link for: ' + readableID); - anchor.setAttribute('data-anchorjs-icon', this.options.icon); - - if (this.options.visible === 'always') { - anchor.style.opacity = '1'; - } - - if (this.options.icon === '\ue9cb') { - anchor.style.fontFamily = 'anchorjs-icons'; - anchor.style.fontStyle = 'normal'; - anchor.style.fontVariant = 'normal'; - anchor.style.fontWeight = 'normal'; - anchor.style.lineHeight = 1; - } - - if (this.options.placement === 'left') { - anchor.style.position = 'absolute'; - anchor.style.marginLeft = '-1em'; - anchor.style.paddingRight = '0.5em'; - elements[i].insertBefore(anchor, elements[i].firstChild); - } else { // if the option provided is `right` (or anything else). - anchor.style.paddingLeft = '0.375em'; - elements[i].appendChild(anchor); - } - } - - return this; - }; - - this.remove = function(selector) { - var domAnchor, - elements = document.querySelectorAll(selector); - for (var i = 0; i < elements.length; i++) { - domAnchor = elements[i].querySelector('.anchorjs-link'); - if (domAnchor) { - elements[i].removeChild(domAnchor); - } - } - return this; - }; - - this._addBaselineStyles = function() { - // We don't want to add global baseline styles if they've been added before. - if (document.head.querySelector('style.anchorjs') !== null) { - return; - } - - var style = document.createElement('style'), - linkRule = - ' .anchorjs-link {' + - ' opacity: 0;' + - ' text-decoration: none;' + - ' -webkit-font-smoothing: antialiased;' + - ' -moz-osx-font-smoothing: grayscale;' + - ' }', - hoverRule = - ' *:hover > .anchorjs-link,' + - ' .anchorjs-link:focus {' + - ' opacity: 1;' + - ' }', - anchorjsLinkFontFace = - ' @font-face {' + - ' font-family: "anchorjs-icons";' + - ' font-style: normal;' + - ' font-weight: normal;' + // Icon from icomoon; 10px wide & 10px tall; 2 empty below & 4 above - ' src: url(data:application/x-font-ttf;charset=utf-8;base64,AAEAAAALAIAAAwAwT1MvMg8SBTUAAAC8AAAAYGNtYXAWi9QdAAABHAAAAFRnYXNwAAAAEAAAAXAAAAAIZ2x5Zgq29TcAAAF4AAABNGhlYWQEZM3pAAACrAAAADZoaGVhBhUDxgAAAuQAAAAkaG10eASAADEAAAMIAAAAFGxvY2EAKACuAAADHAAAAAxtYXhwAAgAVwAAAygAAAAgbmFtZQ5yJ3cAAANIAAAB2nBvc3QAAwAAAAAFJAAAACAAAwJAAZAABQAAApkCzAAAAI8CmQLMAAAB6wAzAQkAAAAAAAAAAAAAAAAAAAABEAAAAAAAAAAAAAAAAAAAAABAAADpywPA/8AAQAPAAEAAAAABAAAAAAAAAAAAAAAgAAAAAAADAAAAAwAAABwAAQADAAAAHAADAAEAAAAcAAQAOAAAAAoACAACAAIAAQAg6cv//f//AAAAAAAg6cv//f//AAH/4xY5AAMAAQAAAAAAAAAAAAAAAQAB//8ADwABAAAAAAAAAAAAAgAANzkBAAAAAAEAAAAAAAAAAAACAAA3OQEAAAAAAQAAAAAAAAAAAAIAADc5AQAAAAACADEARAJTAsAAKwBUAAABIiYnJjQ/AT4BMzIWFxYUDwEGIicmND8BNjQnLgEjIgYPAQYUFxYUBw4BIwciJicmND8BNjIXFhQPAQYUFx4BMzI2PwE2NCcmNDc2MhcWFA8BDgEjARQGDAUtLXoWOR8fORYtLTgKGwoKCjgaGg0gEhIgDXoaGgkJBQwHdR85Fi0tOAobCgoKOBoaDSASEiANehoaCQkKGwotLXoWOR8BMwUFLYEuehYXFxYugC44CQkKGwo4GkoaDQ0NDXoaShoKGwoFBe8XFi6ALjgJCQobCjgaShoNDQ0NehpKGgobCgoKLYEuehYXAAEAAAABAACiToc1Xw889QALBAAAAAAA0XnFFgAAAADRecUWAAAAAAJTAsAAAAAIAAIAAAAAAAAAAQAAA8D/wAAABAAAAAAAAlMAAQAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAACAAAAAoAAMQAAAAAACgAUAB4AmgABAAAABQBVAAIAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAADgCuAAEAAAAAAAEADgAAAAEAAAAAAAIABwCfAAEAAAAAAAMADgBLAAEAAAAAAAQADgC0AAEAAAAAAAUACwAqAAEAAAAAAAYADgB1AAEAAAAAAAoAGgDeAAMAAQQJAAEAHAAOAAMAAQQJAAIADgCmAAMAAQQJAAMAHABZAAMAAQQJAAQAHADCAAMAAQQJAAUAFgA1AAMAAQQJAAYAHACDAAMAAQQJAAoANAD4YW5jaG9yanMtaWNvbnMAYQBuAGMAaABvAHIAagBzAC0AaQBjAG8AbgBzVmVyc2lvbiAxLjAAVgBlAHIAcwBpAG8AbgAgADEALgAwYW5jaG9yanMtaWNvbnMAYQBuAGMAaABvAHIAagBzAC0AaQBjAG8AbgBzYW5jaG9yanMtaWNvbnMAYQBuAGMAaABvAHIAagBzAC0AaQBjAG8AbgBzUmVndWxhcgBSAGUAZwB1AGwAYQByYW5jaG9yanMtaWNvbnMAYQBuAGMAaABvAHIAagBzAC0AaQBjAG8AbgBzRm9udCBnZW5lcmF0ZWQgYnkgSWNvTW9vbi4ARgBvAG4AdAAgAGcAZQBuAGUAcgBhAHQAZQBkACAAYgB5ACAASQBjAG8ATQBvAG8AbgAuAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==) format("truetype");' + - ' }', - pseudoElContent = - ' [data-anchorjs-icon]::after {' + - ' content: attr(data-anchorjs-icon);' + - ' }', - firstStyleEl; - - style.className = 'anchorjs'; - style.appendChild(document.createTextNode('')); // Necessary for Webkit. - - // We place it in the head with the other style tags, if possible, so as to - // not look out of place. We insert before the others so these styles can be - // overridden if necessary. - firstStyleEl = document.head.querySelector('[rel="stylesheet"], style'); - if (firstStyleEl === undefined) { - document.head.appendChild(style); - } else { - document.head.insertBefore(style, firstStyleEl); - } - - style.sheet.insertRule(linkRule, style.sheet.cssRules.length); - style.sheet.insertRule(hoverRule, style.sheet.cssRules.length); - style.sheet.insertRule(pseudoElContent, style.sheet.cssRules.length); - style.sheet.insertRule(anchorjsLinkFontFace, style.sheet.cssRules.length); - }; -} - -var anchors = new AnchorJS(); diff --git a/docs/reference/assets/bass-addons.css b/docs/reference/assets/bass-addons.css deleted file mode 100644 index c27e96d861..0000000000 --- a/docs/reference/assets/bass-addons.css +++ /dev/null @@ -1,12 +0,0 @@ -.input { - font-family: inherit; - display: block; - width: 100%; - height: 2rem; - padding: .5rem; - margin-bottom: 1rem; - border: 1px solid #ccc; - font-size: .875rem; - border-radius: 3px; - box-sizing: border-box; -} diff --git a/docs/reference/assets/bass.css b/docs/reference/assets/bass.css deleted file mode 100644 index 15e0dc9a4c..0000000000 --- a/docs/reference/assets/bass.css +++ /dev/null @@ -1,543 +0,0 @@ -/*! Basscss | http://basscss.com | MIT License */ - -.h1{ font-size: 2rem } -.h2{ font-size: 1.5rem } -.h3{ font-size: 1.25rem } -.h4{ font-size: 1rem } -.h5{ font-size: .875rem } -.h6{ font-size: .75rem } - -.font-family-inherit{ font-family:inherit } -.font-size-inherit{ font-size:inherit } -.text-decoration-none{ text-decoration:none } - -.bold{ font-weight: bold; font-weight: bold } -.regular{ font-weight:normal } -.italic{ font-style:italic } -.caps{ text-transform:uppercase; letter-spacing: .2em; } - -.left-align{ text-align:left } -.center{ text-align:center } -.right-align{ text-align:right } -.justify{ text-align:justify } - -.nowrap{ white-space:nowrap } -.break-word{ word-wrap:break-word } - -.line-height-1{ line-height: 1 } -.line-height-2{ line-height: 1.125 } -.line-height-3{ line-height: 1.25 } -.line-height-4{ line-height: 1.5 } - -.list-style-none{ list-style:none } -.underline{ text-decoration:underline } - -.truncate{ - max-width:100%; - overflow:hidden; - text-overflow:ellipsis; - white-space:nowrap; -} - -.list-reset{ - list-style:none; - padding-left:0; -} - -.inline{ display:inline } -.block{ display:block } -.inline-block{ display:inline-block } -.table{ display:table } -.table-cell{ display:table-cell } - -.overflow-hidden{ overflow:hidden } -.overflow-scroll{ overflow:scroll } -.overflow-auto{ overflow:auto } - -.clearfix:before, -.clearfix:after{ - content:" "; - display:table -} -.clearfix:after{ clear:both } - -.left{ float:left } -.right{ float:right } - -.fit{ max-width:100% } - -.max-width-1{ max-width: 24rem } -.max-width-2{ max-width: 32rem } -.max-width-3{ max-width: 48rem } -.max-width-4{ max-width: 64rem } - -.border-box{ box-sizing:border-box } - -.align-baseline{ vertical-align:baseline } -.align-top{ vertical-align:top } -.align-middle{ vertical-align:middle } -.align-bottom{ vertical-align:bottom } - -.m0{ margin:0 } -.mt0{ margin-top:0 } -.mr0{ margin-right:0 } -.mb0{ margin-bottom:0 } -.ml0{ margin-left:0 } -.mx0{ margin-left:0; margin-right:0 } -.my0{ margin-top:0; margin-bottom:0 } - -.m1{ margin: .5rem } -.mt1{ margin-top: .5rem } -.mr1{ margin-right: .5rem } -.mb1{ margin-bottom: .5rem } -.ml1{ margin-left: .5rem } -.mx1{ margin-left: .5rem; margin-right: .5rem } -.my1{ margin-top: .5rem; margin-bottom: .5rem } - -.m2{ margin: 1rem } -.mt2{ margin-top: 1rem } -.mr2{ margin-right: 1rem } -.mb2{ margin-bottom: 1rem } -.ml2{ margin-left: 1rem } -.mx2{ margin-left: 1rem; margin-right: 1rem } -.my2{ margin-top: 1rem; margin-bottom: 1rem } - -.m3{ margin: 2rem } -.mt3{ margin-top: 2rem } -.mr3{ margin-right: 2rem } -.mb3{ margin-bottom: 2rem } -.ml3{ margin-left: 2rem } -.mx3{ margin-left: 2rem; margin-right: 2rem } -.my3{ margin-top: 2rem; margin-bottom: 2rem } - -.m4{ margin: 4rem } -.mt4{ margin-top: 4rem } -.mr4{ margin-right: 4rem } -.mb4{ margin-bottom: 4rem } -.ml4{ margin-left: 4rem } -.mx4{ margin-left: 4rem; margin-right: 4rem } -.my4{ margin-top: 4rem; margin-bottom: 4rem } - -.mxn1{ margin-left: -.5rem; margin-right: -.5rem; } -.mxn2{ margin-left: -1rem; margin-right: -1rem; } -.mxn3{ margin-left: -2rem; margin-right: -2rem; } -.mxn4{ margin-left: -4rem; margin-right: -4rem; } - -.ml-auto{ margin-left:auto } -.mr-auto{ margin-right:auto } -.mx-auto{ margin-left:auto; margin-right:auto; } - -.p0{ padding:0 } -.pt0{ padding-top:0 } -.pr0{ padding-right:0 } -.pb0{ padding-bottom:0 } -.pl0{ padding-left:0 } -.px0{ padding-left:0; padding-right:0 } -.py0{ padding-top:0; padding-bottom:0 } - -.p1{ padding: .5rem } -.pt1{ padding-top: .5rem } -.pr1{ padding-right: .5rem } -.pb1{ padding-bottom: .5rem } -.pl1{ padding-left: .5rem } -.py1{ padding-top: .5rem; padding-bottom: .5rem } -.px1{ padding-left: .5rem; padding-right: .5rem } - -.p2{ padding: 1rem } -.pt2{ padding-top: 1rem } -.pr2{ padding-right: 1rem } -.pb2{ padding-bottom: 1rem } -.pl2{ padding-left: 1rem } -.py2{ padding-top: 1rem; padding-bottom: 1rem } -.px2{ padding-left: 1rem; padding-right: 1rem } - -.p3{ padding: 2rem } -.pt3{ padding-top: 2rem } -.pr3{ padding-right: 2rem } -.pb3{ padding-bottom: 2rem } -.pl3{ padding-left: 2rem } -.py3{ padding-top: 2rem; padding-bottom: 2rem } -.px3{ padding-left: 2rem; padding-right: 2rem } - -.p4{ padding: 4rem } -.pt4{ padding-top: 4rem } -.pr4{ padding-right: 4rem } -.pb4{ padding-bottom: 4rem } -.pl4{ padding-left: 4rem } -.py4{ padding-top: 4rem; padding-bottom: 4rem } -.px4{ padding-left: 4rem; padding-right: 4rem } - -.col{ - float:left; - box-sizing:border-box; -} - -.col-right{ - float:right; - box-sizing:border-box; -} - -.col-1{ - width:8.33333%; -} - -.col-2{ - width:16.66667%; -} - -.col-3{ - width:25%; -} - -.col-4{ - width:33.33333%; -} - -.col-5{ - width:41.66667%; -} - -.col-6{ - width:50%; -} - -.col-7{ - width:58.33333%; -} - -.col-8{ - width:66.66667%; -} - -.col-9{ - width:75%; -} - -.col-10{ - width:83.33333%; -} - -.col-11{ - width:91.66667%; -} - -.col-12{ - width:100%; -} -@media (min-width: 40em){ - - .sm-col{ - float:left; - box-sizing:border-box; - } - - .sm-col-right{ - float:right; - box-sizing:border-box; - } - - .sm-col-1{ - width:8.33333%; - } - - .sm-col-2{ - width:16.66667%; - } - - .sm-col-3{ - width:25%; - } - - .sm-col-4{ - width:33.33333%; - } - - .sm-col-5{ - width:41.66667%; - } - - .sm-col-6{ - width:50%; - } - - .sm-col-7{ - width:58.33333%; - } - - .sm-col-8{ - width:66.66667%; - } - - .sm-col-9{ - width:75%; - } - - .sm-col-10{ - width:83.33333%; - } - - .sm-col-11{ - width:91.66667%; - } - - .sm-col-12{ - width:100%; - } - -} -@media (min-width: 52em){ - - .md-col{ - float:left; - box-sizing:border-box; - } - - .md-col-right{ - float:right; - box-sizing:border-box; - } - - .md-col-1{ - width:8.33333%; - } - - .md-col-2{ - width:16.66667%; - } - - .md-col-3{ - width:25%; - } - - .md-col-4{ - width:33.33333%; - } - - .md-col-5{ - width:41.66667%; - } - - .md-col-6{ - width:50%; - } - - .md-col-7{ - width:58.33333%; - } - - .md-col-8{ - width:66.66667%; - } - - .md-col-9{ - width:75%; - } - - .md-col-10{ - width:83.33333%; - } - - .md-col-11{ - width:91.66667%; - } - - .md-col-12{ - width:100%; - } - -} -@media (min-width: 64em){ - - .lg-col{ - float:left; - box-sizing:border-box; - } - - .lg-col-right{ - float:right; - box-sizing:border-box; - } - - .lg-col-1{ - width:8.33333%; - } - - .lg-col-2{ - width:16.66667%; - } - - .lg-col-3{ - width:25%; - } - - .lg-col-4{ - width:33.33333%; - } - - .lg-col-5{ - width:41.66667%; - } - - .lg-col-6{ - width:50%; - } - - .lg-col-7{ - width:58.33333%; - } - - .lg-col-8{ - width:66.66667%; - } - - .lg-col-9{ - width:75%; - } - - .lg-col-10{ - width:83.33333%; - } - - .lg-col-11{ - width:91.66667%; - } - - .lg-col-12{ - width:100%; - } - -} -.flex{ display:-webkit-box; display:-webkit-flex; display:-ms-flexbox; display:flex } - -@media (min-width: 40em){ - .sm-flex{ display:-webkit-box; display:-webkit-flex; display:-ms-flexbox; display:flex } -} - -@media (min-width: 52em){ - .md-flex{ display:-webkit-box; display:-webkit-flex; display:-ms-flexbox; display:flex } -} - -@media (min-width: 64em){ - .lg-flex{ display:-webkit-box; display:-webkit-flex; display:-ms-flexbox; display:flex } -} - -.flex-column{ -webkit-box-orient:vertical; -webkit-box-direction:normal; -webkit-flex-direction:column; -ms-flex-direction:column; flex-direction:column } -.flex-wrap{ -webkit-flex-wrap:wrap; -ms-flex-wrap:wrap; flex-wrap:wrap } - -.items-start{ -webkit-box-align:start; -webkit-align-items:flex-start; -ms-flex-align:start; -ms-grid-row-align:flex-start; align-items:flex-start } -.items-end{ -webkit-box-align:end; -webkit-align-items:flex-end; -ms-flex-align:end; -ms-grid-row-align:flex-end; align-items:flex-end } -.items-center{ -webkit-box-align:center; -webkit-align-items:center; -ms-flex-align:center; -ms-grid-row-align:center; align-items:center } -.items-baseline{ -webkit-box-align:baseline; -webkit-align-items:baseline; -ms-flex-align:baseline; -ms-grid-row-align:baseline; align-items:baseline } -.items-stretch{ -webkit-box-align:stretch; -webkit-align-items:stretch; -ms-flex-align:stretch; -ms-grid-row-align:stretch; align-items:stretch } - -.self-start{ -webkit-align-self:flex-start; -ms-flex-item-align:start; align-self:flex-start } -.self-end{ -webkit-align-self:flex-end; -ms-flex-item-align:end; align-self:flex-end } -.self-center{ -webkit-align-self:center; -ms-flex-item-align:center; align-self:center } -.self-baseline{ -webkit-align-self:baseline; -ms-flex-item-align:baseline; align-self:baseline } -.self-stretch{ -webkit-align-self:stretch; -ms-flex-item-align:stretch; align-self:stretch } - -.justify-start{ -webkit-box-pack:start; -webkit-justify-content:flex-start; -ms-flex-pack:start; justify-content:flex-start } -.justify-end{ -webkit-box-pack:end; -webkit-justify-content:flex-end; -ms-flex-pack:end; justify-content:flex-end } -.justify-center{ -webkit-box-pack:center; -webkit-justify-content:center; -ms-flex-pack:center; justify-content:center } -.justify-between{ -webkit-box-pack:justify; -webkit-justify-content:space-between; -ms-flex-pack:justify; justify-content:space-between } -.justify-around{ -webkit-justify-content:space-around; -ms-flex-pack:distribute; justify-content:space-around } - -.content-start{ -webkit-align-content:flex-start; -ms-flex-line-pack:start; align-content:flex-start } -.content-end{ -webkit-align-content:flex-end; -ms-flex-line-pack:end; align-content:flex-end } -.content-center{ -webkit-align-content:center; -ms-flex-line-pack:center; align-content:center } -.content-between{ -webkit-align-content:space-between; -ms-flex-line-pack:justify; align-content:space-between } -.content-around{ -webkit-align-content:space-around; -ms-flex-line-pack:distribute; align-content:space-around } -.content-stretch{ -webkit-align-content:stretch; -ms-flex-line-pack:stretch; align-content:stretch } -.flex-auto{ - -webkit-box-flex:1; - -webkit-flex:1 1 auto; - -ms-flex:1 1 auto; - flex:1 1 auto; - min-width:0; - min-height:0; -} -.flex-none{ -webkit-box-flex:0; -webkit-flex:none; -ms-flex:none; flex:none } - -.order-0{ -webkit-box-ordinal-group:1; -webkit-order:0; -ms-flex-order:0; order:0 } -.order-1{ -webkit-box-ordinal-group:2; -webkit-order:1; -ms-flex-order:1; order:1 } -.order-2{ -webkit-box-ordinal-group:3; -webkit-order:2; -ms-flex-order:2; order:2 } -.order-3{ -webkit-box-ordinal-group:4; -webkit-order:3; -ms-flex-order:3; order:3 } -.order-last{ -webkit-box-ordinal-group:100000; -webkit-order:99999; -ms-flex-order:99999; order:99999 } - -.relative{ position:relative } -.absolute{ position:absolute } -.fixed{ position:fixed } - -.top-0{ top:0 } -.right-0{ right:0 } -.bottom-0{ bottom:0 } -.left-0{ left:0 } - -.z1{ z-index: 1 } -.z2{ z-index: 2 } -.z3{ z-index: 3 } -.z4{ z-index: 4 } - -.border{ - border-style:solid; - border-width: 1px; -} - -.border-top{ - border-top-style:solid; - border-top-width: 1px; -} - -.border-right{ - border-right-style:solid; - border-right-width: 1px; -} - -.border-bottom{ - border-bottom-style:solid; - border-bottom-width: 1px; -} - -.border-left{ - border-left-style:solid; - border-left-width: 1px; -} - -.border-none{ border:0 } - -.rounded{ border-radius: 3px } -.circle{ border-radius:50% } - -.rounded-top{ border-radius: 3px 3px 0 0 } -.rounded-right{ border-radius: 0 3px 3px 0 } -.rounded-bottom{ border-radius: 0 0 3px 3px } -.rounded-left{ border-radius: 3px 0 0 3px } - -.not-rounded{ border-radius:0 } - -.hide{ - position:absolute !important; - height:1px; - width:1px; - overflow:hidden; - clip:rect(1px, 1px, 1px, 1px); -} - -@media (max-width: 40em){ - .xs-hide{ display:none !important } -} - -@media (min-width: 40em) and (max-width: 52em){ - .sm-hide{ display:none !important } -} - -@media (min-width: 52em) and (max-width: 64em){ - .md-hide{ display:none !important } -} - -@media (min-width: 64em){ - .lg-hide{ display:none !important } -} - -.display-none{ display:none !important } - diff --git a/docs/reference/assets/fonts/EOT/SourceCodePro-Bold.eot b/docs/reference/assets/fonts/EOT/SourceCodePro-Bold.eot deleted file mode 100755 index d24cc39f47..0000000000 Binary files a/docs/reference/assets/fonts/EOT/SourceCodePro-Bold.eot and /dev/null differ diff --git a/docs/reference/assets/fonts/EOT/SourceCodePro-Regular.eot b/docs/reference/assets/fonts/EOT/SourceCodePro-Regular.eot deleted file mode 100755 index 09e94730db..0000000000 Binary files a/docs/reference/assets/fonts/EOT/SourceCodePro-Regular.eot and /dev/null differ diff --git a/docs/reference/assets/fonts/LICENSE.txt b/docs/reference/assets/fonts/LICENSE.txt deleted file mode 100755 index d154618a7d..0000000000 --- a/docs/reference/assets/fonts/LICENSE.txt +++ /dev/null @@ -1,93 +0,0 @@ -Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries. - -This Font Software is licensed under the SIL Open Font License, Version 1.1. - -This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL - - ------------------------------------------------------------ -SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 ------------------------------------------------------------ - -PREAMBLE -The goals of the Open Font License (OFL) are to stimulate worldwide -development of collaborative font projects, to support the font creation -efforts of academic and linguistic communities, and to provide a free and -open framework in which fonts may be shared and improved in partnership -with others. - -The OFL allows the licensed fonts to be used, studied, modified and -redistributed freely as long as they are not sold by themselves. The -fonts, including any derivative works, can be bundled, embedded, -redistributed and/or sold with any software provided that any reserved -names are not used by derivative works. The fonts and derivatives, -however, cannot be released under any other type of license. The -requirement for fonts to remain under this license does not apply -to any document created using the fonts or their derivatives. - -DEFINITIONS -"Font Software" refers to the set of files released by the Copyright -Holder(s) under this license and clearly marked as such. This may -include source files, build scripts and documentation. - -"Reserved Font Name" refers to any names specified as such after the -copyright statement(s). - -"Original Version" refers to the collection of Font Software components as -distributed by the Copyright Holder(s). - -"Modified Version" refers to any derivative made by adding to, deleting, -or substituting -- in part or in whole -- any of the components of the -Original Version, by changing formats or by porting the Font Software to a -new environment. - -"Author" refers to any designer, engineer, programmer, technical -writer or other person who contributed to the Font Software. - -PERMISSION & CONDITIONS -Permission is hereby granted, free of charge, to any person obtaining -a copy of the Font Software, to use, study, copy, merge, embed, modify, -redistribute, and sell modified and unmodified copies of the Font -Software, subject to the following conditions: - -1) Neither the Font Software nor any of its individual components, -in Original or Modified Versions, may be sold by itself. - -2) Original or Modified Versions of the Font Software may be bundled, -redistributed and/or sold with any software, provided that each copy -contains the above copyright notice and this license. These can be -included either as stand-alone text files, human-readable headers or -in the appropriate machine-readable metadata fields within text or -binary files as long as those fields can be easily viewed by the user. - -3) No Modified Version of the Font Software may use the Reserved Font -Name(s) unless explicit written permission is granted by the corresponding -Copyright Holder. This restriction only applies to the primary font name as -presented to the users. - -4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font -Software shall not be used to promote, endorse or advertise any -Modified Version, except to acknowledge the contribution(s) of the -Copyright Holder(s) and the Author(s) or with their explicit written -permission. - -5) The Font Software, modified or unmodified, in part or in whole, -must be distributed entirely under this license, and must not be -distributed under any other license. The requirement for fonts to -remain under this license does not apply to any document created -using the Font Software. - -TERMINATION -This license becomes null and void if any of the above conditions are -not met. - -DISCLAIMER -THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT -OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE -COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL -DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM -OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/docs/reference/assets/fonts/OTF/SourceCodePro-Bold.otf b/docs/reference/assets/fonts/OTF/SourceCodePro-Bold.otf deleted file mode 100755 index f4e576cecf..0000000000 Binary files a/docs/reference/assets/fonts/OTF/SourceCodePro-Bold.otf and /dev/null differ diff --git a/docs/reference/assets/fonts/OTF/SourceCodePro-Regular.otf b/docs/reference/assets/fonts/OTF/SourceCodePro-Regular.otf deleted file mode 100755 index 4e3b9d0bcd..0000000000 Binary files a/docs/reference/assets/fonts/OTF/SourceCodePro-Regular.otf and /dev/null differ diff --git a/docs/reference/assets/fonts/TTF/SourceCodePro-Bold.ttf b/docs/reference/assets/fonts/TTF/SourceCodePro-Bold.ttf deleted file mode 100755 index e0c576f1b0..0000000000 Binary files a/docs/reference/assets/fonts/TTF/SourceCodePro-Bold.ttf and /dev/null differ diff --git a/docs/reference/assets/fonts/TTF/SourceCodePro-Regular.ttf b/docs/reference/assets/fonts/TTF/SourceCodePro-Regular.ttf deleted file mode 100755 index 437f47280b..0000000000 Binary files a/docs/reference/assets/fonts/TTF/SourceCodePro-Regular.ttf and /dev/null differ diff --git a/docs/reference/assets/fonts/WOFF/OTF/SourceCodePro-Bold.otf.woff b/docs/reference/assets/fonts/WOFF/OTF/SourceCodePro-Bold.otf.woff deleted file mode 100755 index cf960992f6..0000000000 Binary files a/docs/reference/assets/fonts/WOFF/OTF/SourceCodePro-Bold.otf.woff and /dev/null differ diff --git a/docs/reference/assets/fonts/WOFF/OTF/SourceCodePro-Regular.otf.woff b/docs/reference/assets/fonts/WOFF/OTF/SourceCodePro-Regular.otf.woff deleted file mode 100755 index 395436eb84..0000000000 Binary files a/docs/reference/assets/fonts/WOFF/OTF/SourceCodePro-Regular.otf.woff and /dev/null differ diff --git a/docs/reference/assets/fonts/WOFF/TTF/SourceCodePro-Bold.ttf.woff b/docs/reference/assets/fonts/WOFF/TTF/SourceCodePro-Bold.ttf.woff deleted file mode 100755 index c65ba841a7..0000000000 Binary files a/docs/reference/assets/fonts/WOFF/TTF/SourceCodePro-Bold.ttf.woff and /dev/null differ diff --git a/docs/reference/assets/fonts/WOFF/TTF/SourceCodePro-Regular.ttf.woff b/docs/reference/assets/fonts/WOFF/TTF/SourceCodePro-Regular.ttf.woff deleted file mode 100755 index 0af792a1e4..0000000000 Binary files a/docs/reference/assets/fonts/WOFF/TTF/SourceCodePro-Regular.ttf.woff and /dev/null differ diff --git a/docs/reference/assets/fonts/WOFF2/OTF/SourceCodePro-Bold.otf.woff2 b/docs/reference/assets/fonts/WOFF2/OTF/SourceCodePro-Bold.otf.woff2 deleted file mode 100755 index cbe383538a..0000000000 Binary files a/docs/reference/assets/fonts/WOFF2/OTF/SourceCodePro-Bold.otf.woff2 and /dev/null differ diff --git a/docs/reference/assets/fonts/WOFF2/OTF/SourceCodePro-Regular.otf.woff2 b/docs/reference/assets/fonts/WOFF2/OTF/SourceCodePro-Regular.otf.woff2 deleted file mode 100755 index 65cd591bd8..0000000000 Binary files a/docs/reference/assets/fonts/WOFF2/OTF/SourceCodePro-Regular.otf.woff2 and /dev/null differ diff --git a/docs/reference/assets/fonts/WOFF2/TTF/SourceCodePro-Bold.ttf.woff2 b/docs/reference/assets/fonts/WOFF2/TTF/SourceCodePro-Bold.ttf.woff2 deleted file mode 100755 index b78d5235e6..0000000000 Binary files a/docs/reference/assets/fonts/WOFF2/TTF/SourceCodePro-Bold.ttf.woff2 and /dev/null differ diff --git a/docs/reference/assets/fonts/WOFF2/TTF/SourceCodePro-Regular.ttf.woff2 b/docs/reference/assets/fonts/WOFF2/TTF/SourceCodePro-Regular.ttf.woff2 deleted file mode 100755 index 18d2199ea4..0000000000 Binary files a/docs/reference/assets/fonts/WOFF2/TTF/SourceCodePro-Regular.ttf.woff2 and /dev/null differ diff --git a/docs/reference/assets/fonts/source-code-pro.css b/docs/reference/assets/fonts/source-code-pro.css deleted file mode 100755 index 3abb4f0904..0000000000 --- a/docs/reference/assets/fonts/source-code-pro.css +++ /dev/null @@ -1,23 +0,0 @@ -@font-face{ - font-family: 'Source Code Pro'; - font-weight: 400; - font-style: normal; - font-stretch: normal; - src: url('EOT/SourceCodePro-Regular.eot') format('embedded-opentype'), - url('WOFF2/TTF/SourceCodePro-Regular.ttf.woff2') format('woff2'), - url('WOFF/OTF/SourceCodePro-Regular.otf.woff') format('woff'), - url('OTF/SourceCodePro-Regular.otf') format('opentype'), - url('TTF/SourceCodePro-Regular.ttf') format('truetype'); -} - -@font-face{ - font-family: 'Source Code Pro'; - font-weight: 700; - font-style: normal; - font-stretch: normal; - src: url('EOT/SourceCodePro-Bold.eot') format('embedded-opentype'), - url('WOFF2/TTF/SourceCodePro-Bold.ttf.woff2') format('woff2'), - url('WOFF/OTF/SourceCodePro-Bold.otf.woff') format('woff'), - url('OTF/SourceCodePro-Bold.otf') format('opentype'), - url('TTF/SourceCodePro-Bold.ttf') format('truetype'); -} diff --git a/docs/reference/assets/github.css b/docs/reference/assets/github.css deleted file mode 100644 index 8852abb4c6..0000000000 --- a/docs/reference/assets/github.css +++ /dev/null @@ -1,123 +0,0 @@ -/* - -github.com style (c) Vasily Polovnyov - -*/ - -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - color: #333; - background: #f8f8f8; - -webkit-text-size-adjust: none; -} - -.hljs-comment, -.diff .hljs-header, -.hljs-javadoc { - color: #998; - font-style: italic; -} - -.hljs-keyword, -.css .rule .hljs-keyword, -.hljs-winutils, -.nginx .hljs-title, -.hljs-subst, -.hljs-request, -.hljs-status { - color: #1184CE; -} - -.hljs-number, -.hljs-hexcolor, -.ruby .hljs-constant { - color: #ed225d; -} - -.hljs-string, -.hljs-tag .hljs-value, -.hljs-phpdoc, -.hljs-dartdoc, -.tex .hljs-formula { - color: #ed225d; -} - -.hljs-title, -.hljs-id, -.scss .hljs-preprocessor { - color: #900; - font-weight: bold; -} - -.hljs-list .hljs-keyword, -.hljs-subst { - font-weight: normal; -} - -.hljs-class .hljs-title, -.hljs-type, -.vhdl .hljs-literal, -.tex .hljs-command { - color: #458; - font-weight: bold; -} - -.hljs-tag, -.hljs-tag .hljs-title, -.hljs-rules .hljs-property, -.django .hljs-tag .hljs-keyword { - color: #000080; - font-weight: normal; -} - -.hljs-attribute, -.hljs-variable, -.lisp .hljs-body { - color: #008080; -} - -.hljs-regexp { - color: #009926; -} - -.hljs-symbol, -.ruby .hljs-symbol .hljs-string, -.lisp .hljs-keyword, -.clojure .hljs-keyword, -.scheme .hljs-keyword, -.tex .hljs-special, -.hljs-prompt { - color: #990073; -} - -.hljs-built_in { - color: #0086b3; -} - -.hljs-preprocessor, -.hljs-pragma, -.hljs-pi, -.hljs-doctype, -.hljs-shebang, -.hljs-cdata { - color: #999; - font-weight: bold; -} - -.hljs-deletion { - background: #fdd; -} - -.hljs-addition { - background: #dfd; -} - -.diff .hljs-change { - background: #0086b3; -} - -.hljs-chunk { - color: #aaa; -} diff --git a/docs/reference/assets/site.js b/docs/reference/assets/site.js deleted file mode 100644 index 559c65e5fe..0000000000 --- a/docs/reference/assets/site.js +++ /dev/null @@ -1,108 +0,0 @@ -/* global anchors */ - -// add anchor links to headers -anchors.options.placement = 'left'; -anchors.add('h3'); - -// Filter UI -var tocElements = document.getElementById('toc') - .getElementsByTagName('li'); - -document.getElementById('filter-input') - .addEventListener('keyup', function (e) { - - var i, element, children; - - // enter key - if (e.keyCode === 13) { - // go to the first displayed item in the toc - for (i = 0; i < tocElements.length; i++) { - element = tocElements[i]; - if (!element.classList.contains('display-none')) { - location.replace(element.firstChild.href); - return e.preventDefault(); - } - } - } - - var match = function () { - return true; - }; - - var value = this.value.toLowerCase(); - - if (!value.match(/^\s*$/)) { - match = function (element) { - return element.firstChild.innerHTML.toLowerCase().indexOf(value) !== -1; - }; - } - - for (i = 0; i < tocElements.length; i++) { - element = tocElements[i]; - children = Array.from(element.getElementsByTagName('li')); - if (match(element) || children.some(match)) { - element.classList.remove('display-none'); - } else { - element.classList.add('display-none'); - } - } - }); - -var toggles = document.getElementsByClassName('toggle-step-sibling'); -for (var i = 0; i < toggles.length; i++) { - toggles[i].addEventListener('click', toggleStepSibling); -} - -function toggleStepSibling() { - var stepSibling = this.parentNode.parentNode.parentNode.getElementsByClassName('toggle-target')[0]; - var klass = 'display-none'; - if (stepSibling.classList.contains(klass)) { - stepSibling.classList.remove(klass); - stepSibling.innerHTML = '▾'; - } else { - stepSibling.classList.add(klass); - stepSibling.innerHTML = '▸'; - } -} - -var items = document.getElementsByClassName('toggle-sibling'); -for (var j = 0; j < items.length; j++) { - items[j].addEventListener('click', toggleSibling); -} - -function toggleSibling() { - var stepSibling = this.parentNode.getElementsByClassName('toggle-target')[0]; - var icon = this.getElementsByClassName('icon')[0]; - var klass = 'display-none'; - if (stepSibling.classList.contains(klass)) { - stepSibling.classList.remove(klass); - icon.innerHTML = '▾'; - } else { - stepSibling.classList.add(klass); - icon.innerHTML = '▸'; - } -} - -function showHashTarget(targetId) { - var hashTarget = document.getElementById(targetId); - // new target is hidden - if (hashTarget && hashTarget.offsetHeight === 0 && - hashTarget.parentNode.parentNode.classList.contains('display-none')) { - hashTarget.parentNode.parentNode.classList.remove('display-none'); - } -} - -window.addEventListener('hashchange', function() { - showHashTarget(location.hash.substring(1)); -}); - -showHashTarget(location.hash.substring(1)); - -var toclinks = document.getElementsByClassName('pre-open'); -for (var k = 0; k < toclinks.length; k++) { - toclinks[k].addEventListener('mousedown', preOpen, false); -} - -function preOpen() { - showHashTarget(this.hash.substring(1)); -} diff --git a/docs/reference/assets/style.css b/docs/reference/assets/style.css deleted file mode 100644 index d7e56e0427..0000000000 --- a/docs/reference/assets/style.css +++ /dev/null @@ -1,136 +0,0 @@ -.documentation { - font-family: Helvetica, sans-serif; - color: #666; - line-height: 1.5; - background: #f5f5f5; -} - -.black { - color: #666; -} - -.bg-white { - background-color: #fff; -} - -h4 { - margin: 20px 0 10px 0; -} - -.documentation h3 { - color: #000; -} - -.border-bottom { - border-color: #ddd; -} - -a { - color: #1184CE; - text-decoration: none; -} - -.documentation a[href]:hover { - text-decoration: underline; -} - -a:hover { - cursor: pointer; -} - -.py1-ul li { - padding: 5px 0; -} - -.max-height-100 { - max-height: 100%; -} - -section:target h3 { - font-weight:700; -} - -.documentation td, -.documentation th { - padding: .25rem .25rem; -} - -h1:hover .anchorjs-link, -h2:hover .anchorjs-link, -h3:hover .anchorjs-link, -h4:hover .anchorjs-link { - opacity: 1; -} - -.fix-3 { - width: 25%; - max-width: 244px; -} - -.fix-3 { - width: 25%; - max-width: 244px; -} - -@media (min-width: 52em) { - .fix-margin-3 { - margin-left: 25%; - } -} - -.pre, pre, code, .code { - font-family: Source Code Pro,Menlo,Consolas,Liberation Mono,monospace; - font-size: 14px; -} - -.fill-light { - background: #F9F9F9; -} - -.width2 { - width: 1rem; -} - -.input { - font-family: inherit; - display: block; - width: 100%; - height: 2rem; - padding: .5rem; - margin-bottom: 1rem; - border: 1px solid #ccc; - font-size: .875rem; - border-radius: 3px; - box-sizing: border-box; -} - -table { - border-collapse: collapse; -} - -.prose table th, -.prose table td { - text-align: left; - padding:8px; - border:1px solid #ddd; -} - -.prose table th:nth-child(1) { border-right: none; } -.prose table th:nth-child(2) { border-left: none; } - -.prose table { - border:1px solid #ddd; -} - -.prose-big { - font-size: 18px; - line-height: 30px; -} - -.quiet { - opacity: 0.7; -} - -.minishadow { - box-shadow: 2px 2px 10px #f3f3f3; -} diff --git a/docs/reference/index.html b/docs/reference/index.html deleted file mode 100644 index c2556d2acd..0000000000 --- a/docs/reference/index.html +++ /dev/null @@ -1,10401 +0,0 @@ - - - - - | Documentation - - - - - - -
-
-
-
-

-
- -
- -
- -
-
-
- - -
- - -
-

- utils/source-editor -

- -
- - -

CodeMirror source editor utils

- - -
utils/source-editor
- - - - - - - - - - - - - - - - - - - - -
Static Members
-
- -
-
-
- - replaceDocument(doc) -
-
- -
- -
-
-
- - createDocument() -
-
- -
- -
-
-
- - alignLine(line, align) -
-
- -
- -
-
-
- - setFirstVisibleLine(line) -
-
- -
- -
- - - - - - -
- - - - -
- - -
-

- utils/sources-tree -

- -
- - -

Utils for Sources Tree Component

- - -
utils/sources-tree
- - - - - - - - - - - - - - - - - - - - -
Static Members
-
- -
-
-
- - TmpSource -
-
- -
- -
-
-
- - Node -
-
- -
- -
-
-
- - nodeHasChildren(item) -
-
- -
- -
-
-
- - createNode(name, path, contents) -
-
- -
- -
-
-
- - createParentMap(tree) -
-
- -
- -
-
-
- - getURL(source) -
-
- -
- -
-
-
- - addToTree(tree, source) -
-
- -
- -
-
-
- - determineFileSortOrder(nodes, pathPart, isLastPart) -
-
- -
- -
-
-
- - collapseTree(node, [depth]) -
-
- -
- -
-
-
- - createTree(sources) -
-
- -
- -
- - - - - - -
- - - - -
- - -
-

- utils/source -

- -
- - -

Utils for working with Source URLs

- - -
utils/source
- - - - - - - - - - - - - - - - - - - - -
Static Members
-
- -
-
-
- - trimUrlQuery(url) -
-
- -
- -
-
-
- - isJavaScript(url, [contentType]) -
-
- -
- -
-
-
- - isPretty(source) -
-
- -
- -
-
-
- - getFilename(source) -
-
- -
- -
- - - - - - -
- - - - -
- - -
-

- utils/test-head -

- -
- - -

Utils for mochitest

- - -
utils/test-head
- - - - - - - - - - - - - - - - - - - - -
Static Members
-
- -
-
-
- - createStore(client, [initialState]) -
-
- -
- -
-
-
- - commonLog(msg, [data]) -
-
- -
- -
-
-
- - makeSource(name, [props]) -
-
- -
- -
-
-
- - waitForState(store, predicate) -
-
- -
- -
- - - - - - -
- - - - -
- - -
-

- utils/text -

- -
- - -

Utils for keyboard command strings

- - -
utils/text
- - - - - - - - - - - - - - - - - - - - -
Static Members
-
- -
-
-
- - cmdString() -
-
- -
- -
- - - - - - -
- - - - -
- - -
-

- utils/source-map-worker -

- -
- - -

Source Map Worker

- - -
utils/source-map-worker
- - - - - - - - - - - - - - - - - - - - -
Static Members
-
- -
-
-
- - _setSourceMapRoot(sourceMap, absSourceMapURL, source) -
-
- -
- -
- - - - - - -
- - - - -
- - -
-

- reducers/ui -

- -
- - -

UI reducer

- - -
reducers/ui
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - -
- - -
-

- utils/fromJS -

- -
- - -

Immutable JS conversion utils

- - -
utils/fromJS
- - - - - - - - - - - - - - - - - - - - -
Static Members
-
- -
-
-
- - fromJS(value) -
-
- -
- -
- - - - - - -
- - - - -
- - -
-

- Task -

- -
- - -

This object provides the public module functions.

- - -
Task
- - - - - - - - - - - - - - - - - - - - -
Static Members
-
- -
-
-
- - spawn(task) -
-
- -
- -
- - - - - - -
- - - - -
- - -
-

- reducers/sources -

- -
- - -

Sources reducer

- - -
reducers/sources
- - - - - - - - - - - - - - - - - - - - -
Static Members
-
- -
-
-
- - updateTabList(state, source, tabIndex) -
-
- -
- -
-
-
- - getNewSelectedSourceId(state, id) -
-
- -
- -
- - - - - - -
- - - - -
- - -
-

- reducers/breakpoints -

- -
- - -

Breakpoints reducer

- - -
reducers/breakpoints
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - -
- - -
-

- utils/makeRecord -

- -
- - -

When Flow 0.29 is released (very soon), we can use this Record type -instead of the builtin immutable.js Record type. This is better -because all the fields are actually typed, unlike the builtin one. -This depends on a performance fix that will go out in 0.29 though;

- - -
utils/makeRecord
- - - - - - - - - - - - - - - - - - - - -
Static Members
-
- -
-
-
- - Record -
-
- -
- -
-
-
- - makeRecord(spec) -
-
- -
- -
- - - - - - -
- - - - -
- - -
-

- actions/breakpoints -

- -
- - -

Redux actions for breakpoints

- - -
actions/breakpoints
- - - - - - - - - - - - - - - - - - - - -
Static Members
-
- -
-
-
- - ThunkArgs -
-
- -
- -
-
-
- - enableBreakpoint(location) -
-
- -
- -
-
-
- - addBreakpoint(location, $1) -
-
- -
- -
-
-
- - disableBreakpoint(location) -
-
- -
- -
-
-
- - removeBreakpoint(location) -
-
- -
- -
-
-
- - toggleAllBreakpoints(shouldDisableBreakpoints) -
-
- -
- -
-
-
- - setBreakpointCondition(location, condition, $1) -
-
- -
- -
- - - - - - -
- - - - -
- - -
-

- actions/sources -

- -
- - -

Redux actions for the sources state

- - -
actions/sources
- - - - - - - - - - - - - - - - - - - - -
Static Members
-
- -
-
-
- - newSource(source) -
-
- -
- -
-
-
- - loadSourceMap(generatedSource) -
-
- -
- -
-
-
- - selectSourceURL(url, [options]) -
-
- -
- -
-
-
- - selectSource(id, [options]) -
-
- -
- -
-
-
- - closeTab(id) -
-
- -
- -
-
-
- - togglePrettyPrint(string, sourceId) -
-
- -
- -
-
-
- - loadSourceText(source) -
-
- -
- -
-
-
- - getTextForSources(array, actors) -
-
- -
- -
- - - - - - -
- - - - -
- - -
-

- actions/event-listeners -

- -
- - -

Redux actions for the event listeners state

- - -
actions/event-listeners
- - - - - - - - - - - - - - - - - - - - -
Static Members
-
- -
-
-
- - fetchEventListeners() -
-
- -
- -
-
-
- - updateEventBreakpoints(eventNames) -
-
- -
- -
- - - - - - -
- - - - -
- - -
-

- utils/create-store -

- -
- - -

Redux store utils

- - -
utils/create-store
- - - - - - - - - - - - - - - - - - - - -
Static Members
-
- -
-
-
- - ReduxStoreOptions -
-
- -
- -
-
-
- - configureStore -
-
- -
- -
- - - - - - -
- - - - -
- - -
-

- utils/utils -

- -
- - -

Utils for utils, by utils

- - -
utils/utils
- - - - - - - - - - - - - - - - - - - - -
Static Members
-
- -
-
-
- - asPaused(client, func) -
-
- -
- -
-
-
- - handleError(err) -
-
- -
- -
-
-
- - promisify(context, method, args) -
-
- -
- -
-
-
- - truncateStr(str, size) -
-
- -
- -
-
-
- - endTruncateStr(str, size) -
-
- -
- -
-
-
- - workerTask(worker, method) -
-
- -
- -
-
-
- - zip(Array, Array, a, b) -
-
- -
- -
-
-
- - entries(obj) -
-
- -
- -
-
-
- - mapObject(obj, iteratee) -
-
- -
- -
-
-
- - toObject(arr) -
-
- -
- -
-
-
- - -
-
- -
- -
-
-
- - updateObj(obj, fields) -
-
- -
- -
-
-
- - throttle(func, ms) -
-
- -
- -
- - - - - - -
- - - - -
- - -
-

- actions/navigation -

- -
- - -

Redux actions for the navigation state

- - -
actions/navigation
- - - - - - - - - - - - - - - - - - - - -
Static Members
-
- -
-
-
- - willNavigate() -
-
- -
- -
-
-
- - navigated() -
-
- -
- -
- - - - - - -
- - - - -
- - -
- - -
- - -

These functions implement search within the debugger. Since -search in the debugger is different from other components, -we can't use search.js CodeMirror addon. This is a slightly -modified version of that addon. Depends on searchcursor.js.

- - -
utils/source-search
- - - - - - - - - - - - - - - - - - - - -
Static Members
-
- -
-
-
- - new SearchState() -
-
- -
- -
-
-
- - getSearchState(cm) -
-
- -
- -
-
-
- - getSearchCursor(cm, query, pos) -
-
- -
- -
-
-
- - ignoreWhiteSpace(str) -
-
- -
- -
-
-
- - searchOverlay(query) -
-
- -
- -
-
-
- - startSearch(cm, state, query) -
-
- -
- -
-
-
- - doSearch(ctx, rev, query) -
-
- -
- -
-
-
- - searchNext(ctx, rev) -
-
- -
- -
-
-
- - clearSearch(cm) -
-
- -
- -
-
-
- - find(ctx, query) -
-
- -
- -
-
-
- - findNext(ctx, query) -
-
- -
- -
-
-
- - findPrev(ctx, query) -
-
- -
- -
- - - - - - -
- - - - -
- - -
-

- types -

- -
- - -

Flow types

- - -
types
- - - - - - - - - - - - - - - - - - - - -
Static Members
-
- -
-
-
- - Source -
-
- -
- -
- - - - - - -
- - - - -
- - -
-

- actions/types -

- -
- - -

Flow types

- - -
actions/types
- - - - - - - - - - - - - - - - - - - - -
Static Members
-
- -
-
-
- - Location -
-
- -
- -
-
-
- - AsyncStatus -
-
- -
- -
-
-
- - Breakpoint -
-
- -
- -
-
-
- - SourceText -
-
- -
- -
-
-
- - Action -
-
- -
- -
- - - - - - -
- - - - -
- - -
-

- actions/pause -

- -
- - -

Redux actions for the pause state

- - -
actions/pause
- - - - - - - - - - - - - - - - - - - - -
Static Members
-
- -
-
-
- - resumed() -
-
- -
- -
-
-
- - paused(pauseInfo) -
-
- -
- -
-
-
- - pauseOnExceptions(shouldPauseOnExceptions, shouldIgnoreCaughtExceptions) -
-
- -
- -
-
-
- - command(string, $0) -
-
- -
- -
-
-
- - stepIn() -
-
- -
- -
-
-
- - stepOver() -
-
- -
- -
-
-
- - stepOut() -
-
- -
- -
-
-
- - resume() -
-
- -
- -
-
-
- - breakOnNext() -
-
- -
- -
-
-
- - selectFrame(frame) -
-
- -
- -
-
-
- - loadObjectProperties(grip) -
-
- -
- -
-
-
- - addExpression(expression) -
-
- -
- -
-
-
- - updateExpression(expression) -
-
- -
- -
-
-
- - deleteExpression(expression) -
-
- -
- -
-
-
- - evaluateExpressions() -
-
- -
- -
- - - - - - -
- - - - -
- - -
-

- mochitest/asserts -

- -
- - -

The mochitest API predefined asserts.

- - -
mochitest/asserts
- - - - - - - - - - - - - - - - - - - - -
Static Members
-
- -
-
-
- - assertPausedLocation(dbg, source, line) -
-
- -
- -
-
-
- - assertHighlightLocation(dbg, source, line) -
-
- -
- -
-
-
- - isPaused(dbg) -
-
- -
- -
- - - - - - -
- - - - -
- - -
-

- mochitest/waits -

- -
- - -

The mochitest API to wait for certain events.

- - -
mochitest/waits
- - - - - - - - - - - - - - - - - - - - -
Static Members
-
- -
-
-
- - waitForDispatch(dbg, type, [eventRepeat]) -
-
- -
- -
-
-
- - waitForThreadEvents(dbg, eventName) -
-
- -
- -
-
-
- - waitForState(dbg, predicate) -
-
- -
- -
-
-
- - waitForSources(dbg, sources) -
-
- -
- -
-
-
- - waitForPaused(dbg) -
-
- -
- -
- - - - - - -
- - - - -
- - -
-

- mochitest/actions -

- -
- - -

The mochitest API for interacting with the debugger.

- - -
mochitest/actions
- - - - - - - - - - - - - - - - - - - - -
Static Members
-
- -
-
-
- - findSource(dbg, url) -
-
- -
- -
-
-
- - selectSource(dbg, url, line) -
-
- -
- -
-
-
- - stepOver(dbg) -
-
- -
- -
-
-
- - stepIn(dbg) -
-
- -
- -
-
-
- - stepOut(dbg) -
-
- -
- -
-
-
- - resume(dbg) -
-
- -
- -
-
-
- - reload(dbg, sources) -
-
- -
- -
-
-
- - navigate(dbg, url, sources) -
-
- -
- -
-
-
- - addBreakpoint(dbg, source, line, col) -
-
- -
- -
-
-
- - removeBreakpoint(dbg, source, sourceId, line, col) -
-
- -
- -
-
-
- - togglePauseOnExceptions(dbg, pauseOnExceptions, ignoreCaughtExceptions) -
-
- -
- -
-
-
- - toggleCallStack(dbg) -
-
- -
- -
- - - - - - -
- - - - -
- - -
-

- mochitest/helpers -

- -
- - -

Helper methods for the mochitest API.

- - -
mochitest/helpers
- - - - - - - - - - - - - - - - - - - - -
Static Members
-
- -
-
-
- - invokeInTab(fnc) -
-
- -
- -
-
-
- - pressKey(dbg, keyName) -
-
- -
- -
-
-
- - clickElement(dbg, elementName, args) -
-
- -
- -
- - - - - - -
- - - - -
- - -
-

- mochitest -

- -
- - -

The Mochitest API documentation

- - -
mochitest
- - - - - - - - - - - - - - - - - - - - -
Static Members
-
- -
-
-
- - initDebugger(url, sources) -
-
- -
- -
-
-
- - pauseTest() -
-
- -
- -
- - - - - - -
- - - -
-
-
- - - - diff --git a/docs/remotely-debuggable-browsers.md b/docs/remotely-debuggable-browsers.md deleted file mode 100644 index 7c0d8651e9..0000000000 --- a/docs/remotely-debuggable-browsers.md +++ /dev/null @@ -1,179 +0,0 @@ -## Remotely debuggable browsers - -#### Table Of Contents - -[Firefox](#firefox) - * [MacOS](#macos) - * [Firefox](#firefox-release) - * [Firefox Nightly](#firefox-nightly) - * [Windows](#windows) - * [Firefox (all versions)](#firefox-all-versions) - * [Firefox (64 bit)](#firefox-64-bit) - * [Android](#android) - -[Chrome](#chrome) - * [MacOS](#macos-1) - * [Chrome (release)](#chrome-release) - * [Chrome Canary](#chrome-canary) - * [Windows](#windows-1) - * [Chrome (all versions)](#chrome-all-versions) - * [Chrome (64 bit)](#chrome-64-bit) - -[Safari](#safari) - * [iOS Simulator](#ios-simulator-mac-only) - -Here are quick instructions for getting the Firefox and Chrome web browsers running in a remotely debuggable state. - -On the Mac all instructions assume you've opened a window in the Terminal application. On Windows all instructions assume you've opened the `cmd` application. - -### Firefox - -Here are the instructions for starting a new profile of Firefox on MacOS and Windows. Please file issues or make pull requests for any errors you encounter. - -**Required Flags** - -Running the Firefox profile you intended to debug navigate to `about:config` and use the search to find the following preferences. Double clicking the boolean preferences is the fastest way to toggle them. **You must restart Firefox** once you've made these changes. - -* `devtools.debugger.remote-enabled` to `true` -* `devtools.chrome.enabled` to `true` -* `devtools.debugger.prompt-connection` to `false` - -> **Already running Firefox?** If you would like to make your current Firefox remotely debuggable; press `shift+F2` and type `listen` in the command bar. Make sure you have enabled the required preferences above. - -#### MacOS - -On the Mac Firefox installs different application names for each release channel (release, beta, aurora, nightly) instead of overwriting the existing application. - -**Flags** - -These are the flags necessary to start the remote debug server and use an alternate profile. - -* debug server `--start-debugger-server 6080` -* separate profile `-P development` (not required) - * **Note**: if you are prompted with the profile manager you will need to create a profile named `development` - * **Note**: in windows replace `--start-debugger-server 6080` with `-start-debugger-server 6080` - -##### Firefox (release) - -``` -$ /Applications/Firefox.app/Contents/MacOS/firefox-bin --start-debugger-server 6080 -P development -``` - -> For Firefox Beta or Developer Edition (Aurora) replace the `Firefox.app` from the command above with the following app names -> * FirefoxBeta.app -> * FirefoxDeveloperEdition.app - -##### Firefox Nightly - -``` -$ /Applications/FirefoxNightly.app/Contents/MacOS/firefox-bin --start-debugger-server 6080 -P development -``` - -#### Windows - -**Flags** - -* debug server `-start-debugger-server 6080` -* separate profile `-P development` - -**64 bit Windows** - -For users with a 64 bit machine Firefox may have installed in the: `C:\Program Files (x86)` folder. - -##### Firefox (all versions) - -``` -$ "C:\Program Files\Mozilla Firefox\firefox.exe" -start-debugger-server 6080 -P development -``` - -##### Firefox (64 bit) - -``` -$ "C:\Program Files (x86)\Mozilla Firefox\firefox.exe" -start-debugger-server 6080 -P development -``` - -#### Android - -Firefox for Android creates a Unix socket and listens there for debugger connections. To connect to it, use the [adb](https://developer.android.com/studio/command-line/adb.html) tool's port forwarding feature: - -``` -adb forward tcp:6080 localfilesystem:/data/data/org.mozilla.fennec/firefox-debugger-socket -``` - -The exact path to the socket differs based on release channel. You can find the right value in Firefox on Android by loading about:config and checking the value of the preference ``devtools.debugger.unix-domain-socket``. - -### Chrome - -Here are the instructions for starting a new temporary profile of Chrome on MacOS and Windows. Please file issues or make pull requests for any errors you encounter. - -#### MacOS - -**Flags** - -* debug server `--remote-debugging-port=9222` -* ignore first run setup `--no-first-run` -* use temporary profile `--user-data-dir=/tmp/chrome-dev-profile` - -##### Chrome (release) - -``` -/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --remote-debugging-port=9222 --no-first-run --user-data-dir=/tmp/chrome-dev-profile -``` - -##### Chrome Canary - -``` -/Applications/Google\ Chrome\ Canary.app/Contents/MacOS/Google\ Chrome\ Canary --remote-debugging-port=9222 --no-first-run --user-data-dir=/tmp/chrome-dev-profile -``` - -#### Windows - -**Flags** - -* debug server `--remote-debugging-port=9222` -* ignore first run setup `--no-first-run` -* use temporary profile `--user-data-dir=%TEMP%\chrome-dev-profile` - -##### Chrome (all versions) - -``` -$ "C:\Program Files\Google\Chrome\Application\chrome.exe" --remote-debugging-port=9222 --no-first-run --user-data-dir=%TEMP%\chrome-dev-profile -``` - -##### Chrome (64 bit) - -``` -$ "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --remote-debugging-port=9222 --no-first-run --user-data-dir=%TEMP%\chrome-dev-profile -``` - -### Safari - -These are the instructions for getting the debugger.html project to connect to and debug Safari on various platforms. Please file issues or make pull requests for any errors you encounter. - -#### iOS Simulator (Mac only) - -**Requirements** - -* Xcode - * Download and install [Xcode](https://developer.apple.com/xcode/) from Apple -* [ios-webkit-debug-proxy](https://github.com/google/ios-webkit-debug-proxy) - * `brew install ios-webkit-debug-proxy` - -##### Safari - -* Start the iOS Simulator - * Launch Xcode and then launch the simulator using the following instructions - -![xcode-start-simulator](https://cloud.githubusercontent.com/assets/2134/18512759/debce848-7a8a-11e6-981f-1a0017eb098e.png) - - -* Run the proxy in a terminal - -```shell -ios_webkit_debug_proxy -``` - -* Run the [debugger.html](https://github.com/devtools-html/debugger.html) - * `npm start` -* Connect using the following URL - * [http://localhost:8000/?ws=localhost:9222/devtools/page/1](http://localhost:8000/?ws=localhost:9222/devtools/page/1) diff --git a/docs/screenshots/active.png b/docs/screenshots/active.png deleted file mode 100644 index b8dfcb2da4..0000000000 Binary files a/docs/screenshots/active.png and /dev/null differ diff --git a/docs/screenshots/cypress-runner.png b/docs/screenshots/cypress-runner.png deleted file mode 100644 index 02b1a664a0..0000000000 Binary files a/docs/screenshots/cypress-runner.png and /dev/null differ diff --git a/docs/screenshots/paused.png b/docs/screenshots/paused.png deleted file mode 100644 index 669523e89e..0000000000 Binary files a/docs/screenshots/paused.png and /dev/null differ diff --git a/lerna.json b/lerna.json deleted file mode 100644 index ce9aa5f6fd..0000000000 --- a/lerna.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "lerna": "2.0.0-beta.30", - "version": "0.0.0" -} diff --git a/mocha-runner.html b/mocha-runner.html deleted file mode 100644 index af0c30c7b1..0000000000 --- a/mocha-runner.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - Mocha Tests - - - -
- - - - - - - - - - - diff --git a/package.json b/package.json deleted file mode 100644 index e1199717fe..0000000000 --- a/package.json +++ /dev/null @@ -1,95 +0,0 @@ -{ - "name": "debugger.html", - "version": "0.0.8", - "license": "MPL-2.0", - "repository": { - "url": "git://github.com/devtools-html/debugger.html.git", - "type": "git" - }, - "bugs": { - "url": "https://github.com/devtools-html/debugger.html/issues" - }, - "homepage": "https://github.com/devtools-html/debugger.html#readme", - "engineStrict": true, - "engines": { - "node": ">=6.9.0" - }, - "scripts": { - "start": "node bin/dev-server", - "start-app": "TARGET=application node bin/dev-server", - "flow": "flow", - "lint": "npm run lint-css -s; npm run lint-js -s", - "lint-css": "stylelint src/components/*.css packages/devtools-local-toolbox/**/*.css", - "lint-js": "eslint src/**/*.js packages/devtools-local-toolbox/src/**/*.js", - "lint-fix": "npm run lint-js -- --fix", - "test": "node src/test/node-unit-tests.js", - "test-all": "npm run test; npm run lint; npm run flow; npm run firefox-unit-test", - "mocha-server": "node bin/mocha-server.js", - "firefox-unit-test": "node bin/firefox-driver --test", - "firefox": "node bin/firefox-driver --start", - "mochitests-watch": "MOCHITESTS=true TARGET=firefox-panel webpack --watch", - "build-docs": "documentation build --format html --sort-order alpha --shallow --document-exported --output docs/reference/ src/types.js src/utils/ src/reducers/ src/actions/ src/test/mochitest/head.js", - "prepush": "npm run lint; node src/test/node-unit-tests.js --dots", - "flow-coverage": "flow-coverage-report -i 'src/actions/*.js' -i 'src/reducers/*.js' -i 'src/utils/*.js' -t html -t text", - "postinstall": "lerna bootstrap" - }, - "dependencies": { - "classnames": "^2.2.5", - "co": "=4.6.0", - "codemirror": "^5.1.0", - "devtools-config": "^0.0.9", - "devtools-local-toolbox": "^0.0.10", - "devtools-modules": "^0.0.9", - "devtools-network-request": "^0.0.9", - "devtools-sham-modules": "^0.0.9", - "devtools-client-adapters": "0.0.1", - "documentation": "^4.0.0-beta11", - "eslint": "^3.10.0", - "expect.js": "^0.3.1", - "firefox-profile": "^0.4.0", - "flow-bin": "^0.35.0", - "flow-coverage-report": "^0.2.0", - "fuzzaldrin-plus": "^0.3.1", - "geckodriver": "^1.2.0", - "glob": "^7.0.3", - "husky": "^0.11.7", - "immutable": "^3.7.6", - "invariant": "^2.2.1", - "lodash": "^4.13.1", - "md5": "^2.2.1", - "minimist": "^1.2.0", - "mocha": "^3.1.2", - "mocha-circleci-reporter": "0.0.1", - "mock-require": "^2.0.0", - "pretty-fast": "^0.2.0", - "react": "=0.14.7", - "react-dom": "=0.14.7", - "react-inlinesvg": "^0.5.3", - "react-redux": "4.4.5", - "redux": "3.5.2", - "selenium-webdriver": "^3.0.1", - "source-map": "^0.5.6", - "stylelint": "^7.4.2", - "svg-inline-react": "^1.0.2", - "serve-index": "^1.8.0", - "webpack": "1.13.1", - "workerjs": "github:jlongster/workerjs", - "ws": "^1.0.1", - "lerna": "jasonlaster/lerna" - }, - "files": [ - "src", - "assets" - ], - "greenkeeper": { - "ignore": [ - "react", - "react-dom", - "react-redux", - "redux", - "codemirror" - ] - }, - "main": "src/main.js", - "author": "Jason Laster " -} diff --git a/packages/devtools-client-adapters/README.md b/packages/devtools-client-adapters/README.md deleted file mode 100644 index 638effe7d3..0000000000 --- a/packages/devtools-client-adapters/README.md +++ /dev/null @@ -1,46 +0,0 @@ -### DevTools Client Adapters - -DevTools Client Adapters provides a common interface for: - -1. getting firefox, chrome, and node tabs -2. connecting to a tab -3. communicating with the tab over RDP - -##### get Firefox, Chrome, and Node tabs - -```js -client.firefox.connectClient().then(tabs => { - console.log(tabs) -}); - -client.chrome.connectClient().then(tabs => { - console.log(tabs) -}); - -client.chrome.connectNodeClient().then(tabs => { - console.log(tabs) -}); - - -client.chrome.connectClient().then(tabs => { - console.log(tabs) -}); -``` - -##### connect to either Firefox, Chrome, or Node -```js -client.startDebuggingTab(tab) -client.startDebuggingNode(tab) -``` - -##### send commands to the process -```js -tab.setBreakpoint({ sourceId: 23, line: 2, column: 0 }) -tab.resume() -``` - -##### receive events from the process - -```js -tab.on("paused", pauseData => console.log(pauseData)) -``` diff --git a/packages/devtools-client-adapters/index.js b/packages/devtools-client-adapters/index.js deleted file mode 100644 index 2a903e6a12..0000000000 --- a/packages/devtools-client-adapters/index.js +++ /dev/null @@ -1,57 +0,0 @@ -const { Task } = require("./src/utils/task"); -const firefox = require("./src/firefox"); -const chrome = require("./src/chrome"); -const { createSource } = require("./src/firefox/create"); - -let clientType = null; -function getClient() { - if (clientType === "chrome" || clientType === "node") { - return chrome.clientCommands; - } - - return firefox.clientCommands; -} - -function startDebugging(connTarget, actions) { - if (connTarget.type === "node") { - return startDebuggingNode(connTarget.param, actions); - } - - const target = connTarget.type === "chrome" ? chrome : firefox; - return startDebuggingTab(target, connTarget.param, actions); -} - -function startDebuggingNode(tabId, actions) { - return Task.spawn(function* () { - clientType = "node"; - - const tabs = yield chrome.connectNodeClient(); - const tab = tabs.find(t => t.id.indexOf(tabId) !== -1); - - yield chrome.connectNode(tab.tab); - chrome.initPage(actions, { clientType }); - - return { tabs, tab, client: chrome }; - }); -} - -function startDebuggingTab(targetEnv, tabId, actions) { - return Task.spawn(function* () { - const tabs = yield targetEnv.connectClient(); - const tab = tabs.find(t => t.id.indexOf(tabId) !== -1); - yield targetEnv.connectTab(tab.tab); - - clientType = targetEnv === firefox ? "firefox" : "chrome"; - targetEnv.initPage(actions, { clientType }); - - return { tabs, tab, client: targetEnv }; - }); -} - -module.exports = { - getClient, - startDebugging, - firefox, - chrome, - createSource -}; diff --git a/packages/devtools-client-adapters/package.json b/packages/devtools-client-adapters/package.json deleted file mode 100644 index e688a42f5e..0000000000 --- a/packages/devtools-client-adapters/package.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "name": "devtools-client-adapters", - "version": "0.0.1", - "description": "Devtools Client Adapters", - "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "dependencies": { - "chrome-remote-debugging-protocol": "0.0.11", - "devtools-sham-modules": "^0.0.9", - "devtools-config": "^0.0.9", - "devtools-modules": "^0.0.9" - }, - "files": [ - "indes.js", - "src" - ], - "author": "", - "license": "ISC" -} diff --git a/packages/devtools-client-adapters/src/chrome.js b/packages/devtools-client-adapters/src/chrome.js deleted file mode 100644 index d3662f499c..0000000000 --- a/packages/devtools-client-adapters/src/chrome.js +++ /dev/null @@ -1,123 +0,0 @@ -/* eslint-disable */ - -const { connect } = require("chrome-remote-debugging-protocol"); -const defer = require("./utils/defer"); -const { Tab } = require("./tcomb-types"); -const { isEnabled, getValue } = require("devtools-config"); -const networkRequest = require("devtools-network-request"); -const { setupCommands, clientCommands } = require("./chrome/commands"); -const { setupEvents, clientEvents, pageEvents } = require("./chrome/events"); - -// TODO: figure out a way to avoid patching native prototypes. -// Unfortunately the Chrome client requires it to work. -Array.prototype.peekLast = function() { - return this[this.length - 1]; -}; - -let connection; - -function createTabs(tabs, {type, clientType} = {}) { - return tabs - .filter(tab => { - return tab.type == type; - }) - .map(tab => { - return Tab({ - title: tab.title, - url: tab.url, - id: tab.id, - tab, - clientType - }); - }); -} - -function connectClient() { - const deferred = defer(); - - if(!getValue("chrome.debug")) { - return Promise.resolve(createTabs([])) - } - - const port = getValue("chrome.port"); - const host = getValue("chrome.host"); - const url = `http://${host}:${port}/json/list`; - - networkRequest(url).then(res => { - deferred.resolve(createTabs( - JSON.parse(res.content), - {clientType: "chrome", type: "page"} - )) - }).catch(err => deferred.reject()); - - return deferred.promise; -} - - -function connectNodeClient() { - const deferred = defer(); - - if(!getValue("node.debug")) { - return Promise.resolve(createTabs([])) - } - - const host = getValue("node.host"); - const port = getValue("node.port"); - const url = `http://${host}:${port}/json/list`; - - networkRequest(url).then(res => { - deferred.resolve(createTabs( - JSON.parse(res.content), - {clientType: "node", type: "node"} - )) - }).catch(err => { - console.log(err); - deferred.reject(); - }); - - return deferred.promise; -} - -function connectTab(tab) { - return connect(tab.webSocketDebuggerUrl, {type: "browser"}) - .then(conn => { connection = conn }); -} - -function connectNode(tab) { - return connect(tab.webSocketDebuggerUrl, {type: "node"}) - .then(conn => { connection = conn }); -} - -function initPage(actions, { clientType }) { - const agents = connection._agents; - - setupCommands({ agents, clientType }); - setupEvents({ actions, agents, clientType }) - - agents.Debugger.enable(); - agents.Debugger.setPauseOnExceptions("none"); - agents.Debugger.setAsyncCallStackDepth(0); - - agents.Runtime.enable(); - - if (clientType == "node") { - agents.Runtime.runIfWaitingForDebugger() - } - - if (clientType == "chrome") { - agents.Page.enable(); - } - - - connection.registerDispatcher("Debugger", clientEvents); - connection.registerDispatcher("Page", pageEvents); -} - -module.exports = { - connectClient, - connectNodeClient, - clientCommands, - connectNode, - connectTab, - initPage -}; diff --git a/packages/devtools-client-adapters/src/chrome/commands.js b/packages/devtools-client-adapters/src/chrome/commands.js deleted file mode 100644 index 10afe690d8..0000000000 --- a/packages/devtools-client-adapters/src/chrome/commands.js +++ /dev/null @@ -1,113 +0,0 @@ -const { BreakpointResult, Location } = require("../tcomb-types"); - -let debuggerAgent; -let runtimeAgent; -let pageAgent; - -function setupCommands({ agents }) { - debuggerAgent = agents.Debugger; - runtimeAgent = agents.Runtime; - pageAgent = agents.Page; -} - -function resume() { - return debuggerAgent.resume(); -} - -function stepIn() { - return debuggerAgent.stepInto(); -} - -function stepOver() { - return debuggerAgent.stepOver(); -} - -function stepOut() { - return debuggerAgent.stepOut(); -} - -function pauseOnExceptions(toggle) { - const state = toggle ? "uncaught" : "none"; - return debuggerAgent.setPauseOnExceptions(state); -} - -function breakOnNext() { - return debuggerAgent.pause(); -} - -function sourceContents(sourceId) { - return debuggerAgent.getScriptSource(sourceId, (err, contents) => ({ - source: contents, - contentType: null - })); -} - -function setBreakpoint(location, condition) { - return new Promise((resolve, reject) => { - return debuggerAgent.setBreakpoint({ - scriptId: location.sourceId, - lineNumber: location.line - 1, - columnNumber: location.column - }, (err, breakpointId, actualLocation) => { - if (err) { - reject(err); - return; - } - - actualLocation = actualLocation ? { - sourceId: actualLocation.scriptId, - line: actualLocation.lineNumber + 1, - column: actualLocation.columnNumber - } : location; - - resolve(BreakpointResult({ - id: breakpointId, - actualLocation: Location(actualLocation) - })); - }); - }); -} - -function removeBreakpoint(breakpointId) { - // TODO: resolve promise when request is completed. - return new Promise((resolve, reject) => { - resolve(debuggerAgent.removeBreakpoint(breakpointId)); - }); -} - -function evaluate(script) { - return runtimeAgent.evaluate(script, (_, result) => { - return result; - }); -} - -function debuggeeCommand(script) { - evaluate(script); - return Promise.resolve(); -} - -function navigate(url) { - return pageAgent.navigate(url, (_, result) => { - return result; - }); -} - -const clientCommands = { - resume, - stepIn, - stepOut, - stepOver, - pauseOnExceptions, - breakOnNext, - sourceContents, - setBreakpoint, - removeBreakpoint, - evaluate, - debuggeeCommand, - navigate -}; - -module.exports = { - setupCommands, - clientCommands -}; diff --git a/packages/devtools-client-adapters/src/chrome/events.js b/packages/devtools-client-adapters/src/chrome/events.js deleted file mode 100644 index 1422829aed..0000000000 --- a/packages/devtools-client-adapters/src/chrome/events.js +++ /dev/null @@ -1,107 +0,0 @@ -const { Source, Location, Frame } = require("../tcomb-types"); - -let actions; -let pageAgent; - -function setupEvents(dependencies) { - actions = dependencies.actions; - pageAgent = dependencies.agents.Page; - clientType = dependencies.clientType; -} - -// Debugger Events -function scriptParsed(scriptId, url, startLine, startColumn, - endLine, endColumn, executionContextId, hash, - isContentScript, isInternalScript, isLiveEdit, - sourceMapURL, hasSourceURL, deprecatedCommentWasUsed) { - if (isContentScript) { - return; - } - - if (clientType == "node") { - sourceMapURL = undefined; - } - - actions.newSource(Source({ - id: scriptId, - url, - sourceMapURL, - isPrettyPrinted: false - })); -} - -function scriptFailedToParse() {} - -async function paused( - callFrames, reason, data, hitBreakpoints, asyncStackTrace) { - const frames = callFrames.map(frame => { - return Frame({ - id: frame.callFrameId, - displayName: frame.functionName, - location: Location({ - sourceId: frame.location.scriptId, - line: frame.location.lineNumber + 1, - column: frame.location.columnNumber - }) - }); - }); - - const frame = frames[0]; - const why = Object.assign({}, { - type: reason - }, data); - - if (clientType == "chrome") { - pageAgent.setOverlayMessage("Paused in debugger.html"); - } - - await actions.paused({ frame, why, frames }); -} - -function resumed() { - if (clientType == "chrome") { - pageAgent.setOverlayMessage(undefined); - } - - actions.resumed(); -} - -function globalObjectCleared() { -} - -// Page Events -function frameNavigated(frame) { - actions.navigate(); -} - -function frameStartedLoading() { - actions.willNavigate(); -} - -function domContentEventFired() {} - -function loadEventFired() {} - -function frameStoppedLoading() {} - -const clientEvents = { - scriptParsed, - scriptFailedToParse, - paused, - resumed, - globalObjectCleared, -}; - -const pageEvents = { - frameNavigated, - frameStartedLoading, - domContentEventFired, - loadEventFired, - frameStoppedLoading -}; - -module.exports = { - setupEvents, - pageEvents, - clientEvents -}; diff --git a/packages/devtools-client-adapters/src/firefox.js b/packages/devtools-client-adapters/src/firefox.js deleted file mode 100644 index 347490233a..0000000000 --- a/packages/devtools-client-adapters/src/firefox.js +++ /dev/null @@ -1,111 +0,0 @@ -const { DebuggerClient, DebuggerTransport, - TargetFactory, WebsocketTransport } = require("devtools-sham-modules"); -const defer = require("./utils/defer"); -const { getValue } = require("devtools-config"); -const { Tab } = require("./tcomb-types"); -const { setupCommands, clientCommands } = require("./firefox/commands"); -const { setupEvents, clientEvents } = require("./firefox/events"); - -let debuggerClient = null; -let threadClient = null; -let tabTarget = null; - -function getThreadClient() { - return threadClient; -} - -function setThreadClient(client) { - threadClient = client; -} - -function getTabTarget() { - return tabTarget; -} - -function setTabTarget(target) { - tabTarget = target; -} - -function lookupTabTarget(tab) { - const options = { client: debuggerClient, form: tab, chrome: false }; - return TargetFactory.forRemoteTab(options); -} - -function createTabs(tabs) { - return tabs.map(tab => { - return Tab({ - title: tab.title, - url: tab.url, - id: tab.actor, - tab, - clientType: "firefox" - }); - }); -} - -function connectClient() { - const deferred = defer(); - const useProxy = !getValue("firefox.webSocketConnection"); - const firefoxHost = getValue( - useProxy ? "firefox.proxyHost" : "firefox.webSocketHost" - ); - - const socket = new WebSocket(`ws://${firefoxHost}`); - const transport = useProxy ? - new DebuggerTransport(socket) : new WebsocketTransport(socket); - debuggerClient = new DebuggerClient(transport); - - debuggerClient.connect().then(() => { - return debuggerClient.listTabs().then(response => { - deferred.resolve(createTabs(response.tabs)); - }); - }).catch(err => { - console.log(err); - deferred.resolve([]); - }); - - return deferred.promise; -} - -function connectTab(tab) { - return new Promise((resolve, reject) => { - window.addEventListener("beforeunload", () => { - getTabTarget() && getTabTarget().destroy(); - }); - - lookupTabTarget(tab).then(target => { - tabTarget = target; - target.activeTab.attachThread({}, (res, _threadClient) => { - threadClient = _threadClient; - threadClient.resume(); - resolve(); - }); - }); - }); -} - -function initPage(actions) { - tabTarget = getTabTarget(); - threadClient = getThreadClient(); - setupCommands({ threadClient, tabTarget, debuggerClient }); - - if (actions) { - // Listen to all the requested events. - setupEvents({ threadClient, actions }); - Object.keys(clientEvents).forEach(eventName => { - threadClient.addListener(eventName, clientEvents[eventName]); - }); - } -} - -module.exports = { - connectClient, - connectTab, - clientCommands, - clientEvents, - getThreadClient, - setThreadClient, - getTabTarget, - setTabTarget, - initPage -}; diff --git a/packages/devtools-client-adapters/src/firefox/commands.js b/packages/devtools-client-adapters/src/firefox/commands.js deleted file mode 100644 index 0d611060c3..0000000000 --- a/packages/devtools-client-adapters/src/firefox/commands.js +++ /dev/null @@ -1,170 +0,0 @@ -const { BreakpointResult, Location } = require("../tcomb-types"); -const defer = require("../utils/defer"); - -let bpClients; -let threadClient; -let tabTarget; -let debuggerClient; - -function setupCommands(dependencies) { - threadClient = dependencies.threadClient; - tabTarget = dependencies.tabTarget; - debuggerClient = dependencies.debuggerClient; - bpClients = {}; -} - -function resume() { - return new Promise(resolve => { - threadClient.resume(resolve); - }); -} - -function stepIn() { - return new Promise(resolve => { - threadClient.stepIn(resolve); - }); -} - -function stepOver() { - return new Promise(resolve => { - threadClient.stepOver(resolve); - }); -} - -function stepOut() { - return new Promise(resolve => { - threadClient.stepOut(resolve); - }); -} - -function breakOnNext() { - return threadClient.breakOnNext(); -} - -function sourceContents(sourceId) { - const sourceClient = threadClient.source({ actor: sourceId }); - return sourceClient.source(); -} - -function setBreakpoint(location, condition, noSliding) { - const sourceClient = threadClient.source({ actor: location.sourceId }); - - return sourceClient.setBreakpoint({ - line: location.line, - column: location.column, - condition, - noSliding - }).then((res) => onNewBreakpoint(location, res)); -} - -function onNewBreakpoint(location, res) { - const bpClient = res[1]; - let actualLocation = res[0].actualLocation; - bpClients[bpClient.actor] = bpClient; - - // Firefox only returns `actualLocation` if it actually changed, - // but we want it always to exist. Format `actualLocation` if it - // exists, otherwise use `location`. - actualLocation = actualLocation ? { - sourceId: actualLocation.source.actor, - line: actualLocation.line, - column: actualLocation.column - } : location; - - return BreakpointResult({ - id: bpClient.actor, - actualLocation: Location(actualLocation) - }); -} - -function removeBreakpoint(breakpointId) { - const bpClient = bpClients[breakpointId]; - bpClients[breakpointId] = null; - return bpClient.remove(); -} - -function setBreakpointCondition(breakpointId, location, condition, noSliding) { - let bpClient = bpClients[breakpointId]; - bpClients[breakpointId] = null; - - return bpClient.setCondition(threadClient, condition, noSliding) - .then(_bpClient => onNewBreakpoint(location, [{}, _bpClient])); -} - -function evaluate(script, { frameId }) { - const params = frameId ? { frameActor: frameId } : {}; - const deferred = defer(); - - tabTarget.activeConsole.evaluateJS(script, (result) => { - deferred.resolve(result); - }, params); - - return deferred.promise; -} - -function debuggeeCommand(script) { - tabTarget.activeConsole.evaluateJS(script, () => {}); - - const consoleActor = tabTarget.form.consoleActor; - const request = debuggerClient._activeRequests.get(consoleActor); - request.emit("json-reply", {}); - debuggerClient._activeRequests.delete(consoleActor); - - return Promise.resolve(); -} - -function navigate(url) { - return tabTarget.activeTab.navigateTo(url); -} - -function reload() { - return tabTarget.activeTab.reload(); -} - -function getProperties(grip) { - const objClient = threadClient.pauseGrip(grip); - return objClient.getPrototypeAndProperties(); -} - -function pauseOnExceptions( - shouldPauseOnExceptions, shouldIgnoreCaughtExceptions) { - return threadClient.pauseOnExceptions( - shouldPauseOnExceptions, - shouldIgnoreCaughtExceptions - ); -} - -function prettyPrint(sourceId, indentSize) { - const sourceClient = threadClient.source({ actor: sourceId }); - return sourceClient.prettyPrint(indentSize); -} - -function disablePrettyPrint(sourceId) { - const sourceClient = threadClient.source({ actor: sourceId }); - return sourceClient.disablePrettyPrint(); -} - -const clientCommands = { - resume, - stepIn, - stepOut, - stepOver, - breakOnNext, - sourceContents, - setBreakpoint, - removeBreakpoint, - setBreakpointCondition, - evaluate, - debuggeeCommand, - navigate, - reload, - getProperties, - pauseOnExceptions, - prettyPrint, - disablePrettyPrint -}; - -module.exports = { - setupCommands, - clientCommands -}; diff --git a/packages/devtools-client-adapters/src/firefox/create.js b/packages/devtools-client-adapters/src/firefox/create.js deleted file mode 100644 index e759e53b1c..0000000000 --- a/packages/devtools-client-adapters/src/firefox/create.js +++ /dev/null @@ -1,34 +0,0 @@ -const { Source, Frame, Location } = require("../tcomb-types"); - -function createFrame(frame) { - let title; - if (frame.type == "call") { - let c = frame.callee; - title = c.name || c.userDisplayName || c.displayName || "(anonymous)"; - } else { - title = `(${ frame.type })`; - } - - return Frame({ - id: frame.actor, - displayName: title, - location: Location({ - sourceId: frame.where.source.actor, - line: frame.where.line, - column: frame.where.column - }), - this: frame.this, - scope: frame.environment - }); -} - -function createSource(source) { - return Source({ - id: source.actor, - url: source.url, - isPrettyPrinted: false, - sourceMapURL: source.sourceMapURL - }); -} - -module.exports = { createFrame, createSource }; diff --git a/packages/devtools-client-adapters/src/firefox/events.js b/packages/devtools-client-adapters/src/firefox/events.js deleted file mode 100644 index 2b2ff30f91..0000000000 --- a/packages/devtools-client-adapters/src/firefox/events.js +++ /dev/null @@ -1,50 +0,0 @@ -const { createFrame, createSource } = require("./create"); - -const CALL_STACK_PAGE_SIZE = 1000; - -let threadClient; -let actions; - -function setupEvents(dependencies) { - threadClient = dependencies.threadClient; - actions = dependencies.actions; -} - -async function paused(_, packet) { - // If paused by an explicit interrupt, which are generated by the - // slow script dialog and internal events such as setting - // breakpoints, ignore the event. - if (packet.why.type === "interrupted" && !packet.why.onNext) { - return; - } - - // Eagerly fetch the frames - const response = await threadClient.getFrames(0, CALL_STACK_PAGE_SIZE); - const frames = response.frames.map(createFrame); - - const pause = Object.assign({}, packet, { - frame: createFrame(packet.frame), - frames: frames - }); - - actions.paused(pause); -} - -function resumed(_, packet) { - actions.resumed(packet); -} - -function newSource(_, { source }) { - actions.newSource(createSource(source)); -} - -const clientEvents = { - paused, - resumed, - newSource -}; - -module.exports = { - setupEvents, - clientEvents -}; diff --git a/packages/devtools-client-adapters/src/tcomb-types.js b/packages/devtools-client-adapters/src/tcomb-types.js deleted file mode 100644 index a81ed88e0b..0000000000 --- a/packages/devtools-client-adapters/src/tcomb-types.js +++ /dev/null @@ -1,58 +0,0 @@ -const t = require("tcomb"); - -const Tab = t.struct({ - title: t.String, - url: t.String, - id: t.String, - tab: t.Object, - clientType: t.enums.of(["chrome", "firefox", "node"]) -}, "Tab"); - -const SourceText = t.struct({ - text: t.String, - contentType: t.String -}); - -const Source = t.struct({ - id: t.String, - url: t.union([t.String, t.Nil]), - isPrettyPrinted: t.Boolean, - sourceMapURL: t.union([t.String, t.Nil]) -}, "Source"); - -const Location = t.struct({ - sourceId: t.String, - line: t.Number, - column: t.union([t.Number, t.Nil]) -}, "Location"); - -const Breakpoint = t.struct({ - id: t.String, - loading: t.Boolean, - disabled: t.Boolean, - text: t.String, - condition: t.union([t.String, t.Nil]) -}); - -const BreakpointResult = t.struct({ - id: t.String, - actualLocation: Location -}); - -const Frame = t.struct({ - id: t.String, - displayName: t.String, - location: Location, - this: t.union([t.Object, t.Nil]), - scope: t.union([t.Object, t.Nil]) -}, "Frame"); - -module.exports = { - Tab, - Source, - SourceText, - Location, - Breakpoint, - BreakpointResult, - Frame -}; diff --git a/packages/devtools-client-adapters/src/utils/defer.js b/packages/devtools-client-adapters/src/utils/defer.js deleted file mode 100644 index c8d2651eb8..0000000000 --- a/packages/devtools-client-adapters/src/utils/defer.js +++ /dev/null @@ -1,12 +0,0 @@ -module.exports = function defer() { - let resolve, reject; - let promise = new Promise(function() { - resolve = arguments[0]; - reject = arguments[1]; - }); - return { - resolve: resolve, - reject: reject, - promise: promise - }; -}; diff --git a/packages/devtools-client-adapters/src/utils/task.js b/packages/devtools-client-adapters/src/utils/task.js deleted file mode 100644 index 5cfcd19ee7..0000000000 --- a/packages/devtools-client-adapters/src/utils/task.js +++ /dev/null @@ -1,48 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ts=2 et sw=2 tw=80 filetype=javascript: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/** - * This object provides the public module functions. - */ -const Task = { - // XXX: Not sure if this works in all cases... - async: function(task) { - return function() { - return Task.spawn(task, this, arguments); - }; - }, - - /** - * Creates and starts a new task. - * @param task A generator function - * @return A promise, resolved when the task terminates - */ - spawn: function(task, scope, args) { - return new Promise(function(resolve, reject) { - const iterator = task.apply(scope, args); - - const callNext = lastValue => { - const iteration = iterator.next(lastValue); - Promise.resolve(iteration.value) - .then(value => { - if (iteration.done) { - resolve(value); - } else { - callNext(value); - } - }) - .catch(error => { - reject(error); - iterator.throw(error); - }); - }; - - callNext(undefined); - }); - }, -}; - -module.exports = { Task }; diff --git a/packages/devtools-config/README.md b/packages/devtools-config/README.md deleted file mode 100644 index ff36322430..0000000000 --- a/packages/devtools-config/README.md +++ /dev/null @@ -1,42 +0,0 @@ -## Configuration - -All default config values are in [`config/development.json`](./development.json), to override these values you need to [create a local config file](#create-a-local-config-file). - -* *logging* - * `client` Enables logging the Firefox protocol in the devtools console of the debugger - * `firefoxProxy` Enables logging the Firefox protocol in the terminal running `npm start` - * `actions` Enables logging the redux actions -* *features* debugger related features - * `tabs` Enables source view tabs in the editor (CodeMirror) - * `sourceMaps` Enables source map loading when available - * `watchExpressions` Enables accordion component for working with watch expressions -* *chrome* Chrome browser related flags - * `debug` Enables listening for remotely debuggable Chrome browsers - * `port` web socket port specified when launching Chrome from the command line - * `host` host specified when launching Chrome from the command line -* *node* Node related flags - * `debug` Enables listening for remotely debuggable Node processes - * `port` web socket port specified when connecting to node - * `host` host specified when connecting to node -* *firefox* Firefox browser related flags - * `proxyHost` Host used by the development server run with `npm start` - * `websocketHost` Host used by the client when establishing a websocket connection with Firefox. - * `webSocketConnection` Favours Firefox WebSocket connection over the [firefox-proxy](../bin/firefox-proxy), :warning: Experimental feature and requires [bug 1286281](https://bugzilla.mozilla.org/show_bug.cgi?id=1286281) - * `geckoDir` Local location of Firefox source code _only needed by project maintainers_ -* *development* Development server related settings - * `serverPort` Listen Port used by the development server - * `examplesPort` Listen Port used to serve examples -* `hotReloading` enables [Hot Reloading](../docs/local-development.md#hot-reloading) of CSS and React -* `baseWorkerURL` Location for where the worker bundles exist -* `host` Location for where the debugger bundles exist - - -### Local config - -You can create a `configs/local.json` file to override development configs. This is great for enabling features locally or changing the theme. Copy the `local-sample` to get started. - -```bash -cp configs/local-sample.json configs/local-sample.json -``` - -> The `local.json` will be ignored by git so any changes you make won't be published, only make changes to the `development.json` file when related to features removed or added to the project. diff --git a/packages/devtools-config/flow-interface.js b/packages/devtools-config/flow-interface.js deleted file mode 100644 index 34eb071a33..0000000000 --- a/packages/devtools-config/flow-interface.js +++ /dev/null @@ -1,12 +0,0 @@ -declare module "devtools-config" { - declare module.exports: { - isDevelopment: () => boolean; - getValue: (key: string) => any; - isEnabled: () => boolean; - isTesting: () => boolean; - isFirefoxPanel: () => boolean; - isFirefox: () => boolean; - setConfig: (value: Object) => void; - getConfig: () => Object; - } -} diff --git a/packages/devtools-config/index.js b/packages/devtools-config/index.js deleted file mode 100644 index a3656b5af9..0000000000 --- a/packages/devtools-config/index.js +++ /dev/null @@ -1,3 +0,0 @@ -const feature = require("./src/feature"); - -module.exports = feature; diff --git a/packages/devtools-config/package.json b/packages/devtools-config/package.json deleted file mode 100644 index 473ae49004..0000000000 --- a/packages/devtools-config/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "devtools-config", - "version": "0.0.9", - "description": "Devtools Local Configuration System", - "main": "index.js", - "directories": { - "test": "tests" - }, - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "", - "license": "ISC" -} diff --git a/packages/devtools-config/registerConfig.js b/packages/devtools-config/registerConfig.js deleted file mode 100644 index 799bb8945a..0000000000 --- a/packages/devtools-config/registerConfig.js +++ /dev/null @@ -1,11 +0,0 @@ -const getConfig = require("./src/config").getConfig; -const setConfig = require("./src/feature").setConfig; - -function registerConfig() { - setConfig(getConfig()); -} - -module.exports = { - getConfig, - registerConfig -}; diff --git a/packages/devtools-config/src/feature.js b/packages/devtools-config/src/feature.js deleted file mode 100644 index 2fbb069aec..0000000000 --- a/packages/devtools-config/src/feature.js +++ /dev/null @@ -1,60 +0,0 @@ -const pick = require("lodash/get"); -let config; - -const flag = require("./test-flag"); - -/** - * Gets a config value for a given key - * e.g "chrome.webSocketPort" - */ -function getValue(key) { - return pick(config, key); -} - -function isEnabled(key) { - return config.features && config.features[key]; -} - -function isDevelopment() { - if (isFirefoxPanel()) { - // Default to production if compiling for the Firefox panel - return process.env.NODE_ENV === "development"; - } - return process.env.NODE_ENV !== "production"; -} - -function isTesting() { - return flag.testing; -} - -function isFirefoxPanel() { - return process.env.TARGET == "firefox-panel"; -} - -function isApplication() { - return process.env.TARGET == "application"; -} - -function isFirefox() { - return /firefox/i.test(navigator.userAgent); -} - -function setConfig(value) { - config = value; -} - -function getConfig() { - return config; -} - -module.exports = { - isEnabled, - getValue, - isDevelopment, - isTesting, - isFirefoxPanel, - isApplication, - isFirefox, - getConfig, - setConfig -}; diff --git a/packages/devtools-config/src/test-flag.js b/packages/devtools-config/src/test-flag.js deleted file mode 100644 index 5e7f287859..0000000000 --- a/packages/devtools-config/src/test-flag.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = { testing: false }; diff --git a/packages/devtools-config/tests/.eslintrc b/packages/devtools-config/tests/.eslintrc deleted file mode 100644 index e39b7d0071..0000000000 --- a/packages/devtools-config/tests/.eslintrc +++ /dev/null @@ -1,32 +0,0 @@ -{ - "globals": { - "after": true, - "afterEach": true, - "before": true, - "beforeEach": true, - "context": true, - "describe": true, - "it": true, - "mocha": true, - "setup": true, - "specify": true, - "suite": true, - "suiteSetup": true, - "suiteTeardown": true, - "teardown": true, - "test": true, - "xcontext": true, - "xdescribe": true, - "xit": true, - "xspecify": true, - "assert": true, - "expect": true, - "equal": true, - "ok": true - }, - "rules": { - "camelcase": 0, - "no-unused-vars": [2, {"vars": "all", "args": "none", "varsIgnorePattern": "run_test"}], - "max-nested-callbacks": [2, 4], - } -} diff --git a/packages/devtools-config/tests/feature.js b/packages/devtools-config/tests/feature.js deleted file mode 100644 index 7976f5b43c..0000000000 --- a/packages/devtools-config/tests/feature.js +++ /dev/null @@ -1,39 +0,0 @@ -const { isDevelopment, getValue, isEnabled, setConfig } = require("../feature"); -const expect = require("expect.js"); - -describe("feature", () => { - it("isDevelopment", () => { - setConfig({ development: true }); - expect(isDevelopment()).to.be.truthy; - }); - - it("isDevelopment - not defined", () => { - setConfig({ }); - expect(isDevelopment()).to.be.falsey; - }); - - it("getValue - enabled", function() { - setConfig({ featureA: true }); - expect(getValue("featureA")).to.be.truthy; - }); - - it("getValue - disabled", function() { - setConfig({ featureA: false }); - expect(getValue("featureA")).to.be.falsey; - }); - - it("getValue - not present", function() { - setConfig({}); - expect(getValue("featureA")).to.be.undefined; - }); - - it("isEnabled - enabled", function() { - setConfig({ features: { featureA: true }}); - expect(isEnabled("featureA")).to.be.truthy; - }); - - it("isEnabled - disabled", function() { - setConfig({ features: { featureA: false }}); - expect(isEnabled("featureA")).to.be.falsey; - }); -}); diff --git a/packages/devtools-local-toolbox/.eslintignore b/packages/devtools-local-toolbox/.eslintignore deleted file mode 100644 index 8a07ecfe8c..0000000000 --- a/packages/devtools-local-toolbox/.eslintignore +++ /dev/null @@ -1,2 +0,0 @@ -src/lib/** -bin/** diff --git a/packages/devtools-local-toolbox/README.md b/packages/devtools-local-toolbox/README.md deleted file mode 100644 index 0318cae44e..0000000000 --- a/packages/devtools-local-toolbox/README.md +++ /dev/null @@ -1,88 +0,0 @@ -# Local Toolbox - -debugger-screenshot - -The local toolbox makes it easy to build a developer tool for Firefox, Chrome, and Node. - -[Debugger.html](../../README.md) and [Console.html](https://github.com/jasonlaster/console.html) are a good examples of tools built on top of the toolbox. - - -**Features** -* *Dev Server* - local development environment to run your tool -* *Webpack Base* - webpack config to build on top of -* *Landing Page* - see available connections -* *Bootstrap function* - hook to start your tool with a debuggee connection -* *Configs* - config system to add additional runtime configuration - -#### Dev Server - -* serve an `index.html` root -* serve JS bundles with incremental builds and hot-reloading -* handle cross origin requests from the client -* runs firefox's tcp-ws proxy - -Example [dev-server.js](https://github.com/jasonLaster/console.html/blob/master/bin/dev-server.js) - -```js -toolbox.startDevServer(envConfig, webpackConfig); -``` - -#### Webpack Config - -The webpack [base config](./webpack.config.js) makes it easy to use the toolbox out of the box. - -**Features** - -* transpiles source: strips flow types, convert async to generators -* loads JSON files for L10N strings and Configs -* loads SVGs for inlining assets -* ignore modules that should be excluded (fs) -* CSS & JS hot reloading -* map shimmed modules to privileged modules when bundling for the panel -* bundles CSS into one file when building for the panel - -Here's an example tool [webpack.config.js](https://github.com/jasonLaster/console.html/blob/master/webpack.config.js). - - -#### Landing Page - -The [Landing Page](./src/index.js) shows the available Chrome, Firefox, and Node tabs to debug. - -**Features** -* shows available connections -* has tools title -* sets up L10N -* loads the light, dark, and firebug themes - -[Screenshot ](https://cloud.githubusercontent.com/assets/254562/20671763/a749acfa-b54c-11e6-9a4a-6b0fc4f45589.png) - -#### Bootstrap function - -The bootstrap function starts the toolbox and provides a connection hook for doing post-connect setup with the debuggee connection. - -**Features** -* checks for a connection id i.e. `firefox-tab=child1/tab1` -* gets available tabs -* connects to a debuggee tab -* renders either the Landing Page or tool root component - -```js -bootstrap(React, ReactDOM, App, actions, store) - .then(conn => onConnect(conn, actions)); -``` - - -#### Configs - -The toolbox has a [config system](../devtools-config/README.md) for adding runtime configs. - -**Features** -* *target configs* - firefox, chrome, node configuration -* *feature flags* toggle features in the build -* *themes* - enable light, dark, firebug -* *hot-reloading* - toggle hot Reloading -* *logging* - enable different logging support -* *environments* - different configs for development, ci, panel -* *local override* - local config overrides - -Here's an example [config](https://github.com/jasonLaster/console.html/blob/master/configs/development.json). diff --git a/packages/devtools-local-toolbox/bin/development-server.js b/packages/devtools-local-toolbox/bin/development-server.js deleted file mode 100755 index da63d72653..0000000000 --- a/packages/devtools-local-toolbox/bin/development-server.js +++ /dev/null @@ -1,118 +0,0 @@ -#!/usr/bin/env node - -"use strict"; - -require("babel-register"); - -const path = require("path"); -const fs = require("fs"); -const Mustache = require("mustache"); -const webpack = require("webpack"); -const express = require("express"); -const webpackDevMiddleware = require("webpack-dev-middleware"); -const webpackHotMiddleware = require("webpack-hot-middleware"); -const http = require("http"); -const checkNode = require("check-node-version"); -const getValue = require("devtools-config").getValue; -const setConfig = require("devtools-config").setConfig; -const isDevelopment = require("devtools-config").isDevelopment; - -function httpGet(url, onResponse) { - return http.get(url, (response) => { - if (response.statusCode !== 200) { - console.error(`error response: ${response.statusCode} to ${url}`); - response.emit("statusCode", new Error(response.statusCode)); - return onResponse("{}"); - } - let body = ""; - response.on("data", function(d) { - body += d; - }); - response.on("end", () => onResponse(body)); - }); -} - -function serveRoot(req, res) { - const tplPath = path.join(__dirname, "../index.html"); - const tplFile = fs.readFileSync(tplPath, "utf8"); - res.send(Mustache.render(tplFile, { isDevelopment: isDevelopment() })); -} - -function handleNetworkRequest(req, res) { - const url = req.query.url; - if (url.indexOf("file://") === 0) { - const path = url.replace("file://", ""); - res.json(JSON.parse(fs.readFileSync(path, "utf8"))); - } - else { - const httpReq = httpGet( - req.query.url, - body => { - try { - res.send(body); - } catch (e) { - res.status(500).send("Malformed json"); - } - } - ); - - httpReq.on("error", err => res.status(500).send(err.code)); - httpReq.on("statusCode", err => res.status(err.message).send(err.message)); - } -} - -function onRequest(err, result) { - const serverPort = getValue("development.serverPort"); - - if (err) { - console.log(err); - } else { - console.log(`Development Server Listening at http://localhost:${serverPort}`); - } -} - -function startDevServer(devConfig, webpackConfig) { - setConfig(devConfig); - checkNode(">=6.9.0", function(_, opts) { - if (!opts.nodeSatisfied) { - const version = opts.node.raw; - console.log(`Sorry, Your version of node is ${version}.`); - console.log("The minimum requirement is >=6.9.0"); - exit(); - } - }); - - if (!getValue("firefox.webSocketConnection")) { - const firefoxProxy = require("./firefox-proxy"); - firefoxProxy({ logging: getValue("logging.firefoxProxy") }); - } - - // setup app - const app = express(); - app.use(express.static("assets/build")); - if (!getValue("development.customIndex")) { - app.get("/", serveRoot); - } - app.get("/get", handleNetworkRequest); - const serverPort = getValue("development.serverPort"); - app.listen(serverPort, "0.0.0.0", onRequest); - - const compiler = webpack(webpackConfig); - app.use(webpackDevMiddleware(compiler, { - publicPath: webpackConfig.output.publicPath, - noInfo: true, - stats: { colors: true } - })); - - if (getValue("hotReloading")) { - app.use(webpackHotMiddleware(compiler)); - } else { - console.log("Hot Reloading - https://github.com/devtools-html/debugger.html/blob/master/docs/local-development.md#hot-reloading"); - } - - return { express, app } -} - -module.exports = { - startDevServer -} diff --git a/packages/devtools-local-toolbox/bin/firefox-proxy b/packages/devtools-local-toolbox/bin/firefox-proxy deleted file mode 100755 index 6d4bc5b5a8..0000000000 --- a/packages/devtools-local-toolbox/bin/firefox-proxy +++ /dev/null @@ -1,77 +0,0 @@ -#!/usr/bin/env node -"use strict"; - -const minimist = require("minimist"); -const ws = require("ws"); -const net = require("net"); - -function proxy(webSocketPort, tcpPort, logging) { - console.log("Listening for WS on *:" + webSocketPort); - console.log("Will proxy to TCP on *:" + tcpPort + " on first WS connection"); - if (!logging) { - console.log("Protocol messages can be logged by enabling " + - "logging.firefoxProtocol in your local.json config"); - } - let wsServer = new ws.Server({ port: webSocketPort }); - wsServer.on("connection", function onConnection(wsConnection) { - let tcpClient = net.connect({ port: tcpPort }); - tcpClient.setEncoding("utf8"); - - tcpClient.on("connect", () => { - console.log("TCP connection succeeded"); - }); - - tcpClient.on("error", e => { - wsConnection.close(); - console.log("TCP connection failed: " + e); - }); - - tcpClient.on("data", data => { - if (logging) { - console.log("TCP -> WS: " + data); - } - try { - wsConnection.send(data); - } catch (e) { - tcpClient.end(); - console.log("WS send failed, disconnected from TCP"); - } - }); - - wsConnection.on("message", msg => { - if (logging) { - console.log("WS -> TCP: " + msg); - } - tcpClient.write(msg); - }); - - wsConnection.on("close", () => { - tcpClient.end(); - console.log("WS connection closed, disconnected from TCP"); - }); - - wsConnection.on("error", () => { - tcpClient.end(); - console.log("WS connection error, disconnected from TCP"); - }); - }); -} - -const args = minimist(process.argv.slice(2)); - -const WEB_SOCKET_PORT = args["web-socket-port"] || 9000; -const TCP_PORT = args["tcp-port"] || 6080; -const shouldStart = args.start; - -function start(options) { - const webSocketPort = options.webSocketPort || 9000; - const tcpPort = options.tcpPort || 6080; - const logging = !!options.logging; - proxy(webSocketPort, tcpPort, logging); -} - -if (shouldStart) { - start({ webSocketPort: WEB_SOCKET_PORT, tcpPort: TCP_PORT }); -} else { - module.exports = start; -} diff --git a/packages/devtools-local-toolbox/index.html b/packages/devtools-local-toolbox/index.html deleted file mode 100644 index eba3487424..0000000000 --- a/packages/devtools-local-toolbox/index.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - Firefox Debugger - - - {{^isDevelopment}} - - {{/isDevelopment}} - - - - -
- - - diff --git a/packages/devtools-local-toolbox/index.js b/packages/devtools-local-toolbox/index.js deleted file mode 100644 index 8843240d88..0000000000 --- a/packages/devtools-local-toolbox/index.js +++ /dev/null @@ -1,7 +0,0 @@ -const developmentServer = require("./bin/development-server"); -const toolboxConfig = require("./webpack.config"); - -module.exports = { - startDevServer: developmentServer.startDevServer, - toolboxConfig -}; diff --git a/packages/devtools-local-toolbox/package.json b/packages/devtools-local-toolbox/package.json deleted file mode 100644 index d2785dc763..0000000000 --- a/packages/devtools-local-toolbox/package.json +++ /dev/null @@ -1,86 +0,0 @@ -{ - "name": "devtools-local-toolbox", - "version": "0.0.10", - "license": "MPL-2.0", - "repository": { - "type": "git", - "url": "git://github.com/devtools-html/debugger.html.git" - }, - "bugs": { - "url": "https://github.com/devtools-html/debugger.html/issues" - }, - "homepage": "https://github.com/devtools-html/debugger.html#readme", - "scripts": {}, - "main": "src/index.js", - "bin": { - "start-dev-server": "./bin/development-server.js" - }, - "engineStrict": true, - "engines": { - "node": ">=6.9.0" - }, - "dependencies": { - "amd-loader": "0.0.5", - "babel-cli": "^6.7.5", - "babel-core": "^6.17.0", - "babel-eslint": "^7.1.0", - "babel-loader": "^6.2.4", - "babel-plugin-module-resolver": "^2.2.0", - "babel-plugin-transform-async-to-generator": "^6.16.0", - "babel-plugin-transform-es2015-block-scoping": "^6.7.1", - "babel-plugin-transform-es2015-destructuring": "^6.6.5", - "babel-plugin-transform-es2015-parameters": "^6.7.0", - "babel-plugin-transform-es2015-spread": "^6.6.5", - "babel-plugin-transform-flow-strip-types": "^6.14.0", - "babel-plugin-transform-runtime": "^6.7.5", - "babel-plugin-webpack-alias": "^2.1.1", - "babel-polyfill": "^6.7.4", - "babel-register": "^6.18.0", - "body-parser": "^1.15.0", - "check-node-version": "^1.1.2", - "classnames": "^2.2.5", - "co": "=4.6.0", - "css-loader": "^0.25.0", - "devtools-config": "^0.0.9", - "devtools-client-adapters": "^0.0.1", - "devtools-modules": "^0.0.9", - "devtools-network-request": "^0.0.9", - "devtools-sham-modules": "^0.0.9", - "eslint": "^3.10.0", - "eslint-plugin-babel": "^3.3.0", - "eslint-plugin-flowtype": "^2.20.0", - "eslint-plugin-mozilla": "0.2.3", - "eslint-plugin-react": "^6.7.1", - "express": "^4.13.4", - "extract-text-webpack-plugin": "^1.0.1", - "immutable": "^3.7.6", - "json-loader": "^0.5.4", - "minimist": "^1.2.0", - "mustache": "^2.2.1", - "node-static": "^0.7.7", - "react": "=0.14.7", - "react-dom": "=0.14.7", - "react-hot-loader": "^1.3.1", - "react-immutable-proptypes": "^1.7.1", - "react-inlinesvg": "^0.5.3", - "react-redux": "4.4.5", - "redux": "3.5.2", - "serve-index": "^1.8.0", - "style-loader": "^0.13.1", - "svg-inline-loader": "^0.7.1", - "tcomb": "^3.1.0", - "webpack": "1.13.1", - "webpack-dev-middleware": "^1.6.1", - "webpack-env-loader-plugin": "^0.1.4", - "webpack-hot-middleware": "^2.12.0", - "ws": "^1.0.1" - }, - "files": [ - "bin", - "src", - "index.html", - "index.js", - "webpack.config.js", - "webpack.config.devtools.js" - ] -} diff --git a/packages/devtools-local-toolbox/src/actions/index.js b/packages/devtools-local-toolbox/src/actions/index.js deleted file mode 100644 index c516f3468e..0000000000 --- a/packages/devtools-local-toolbox/src/actions/index.js +++ /dev/null @@ -1,4 +0,0 @@ - -const tabs = require("./tabs"); - -module.exports = (Object.assign({}, tabs)); diff --git a/packages/devtools-local-toolbox/src/actions/tabs.js b/packages/devtools-local-toolbox/src/actions/tabs.js deleted file mode 100644 index 9d50f25fce..0000000000 --- a/packages/devtools-local-toolbox/src/actions/tabs.js +++ /dev/null @@ -1,50 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - /* global window */ - -/** - * Redux actions for the pause state - * @module actions/tabs - */ - -const constants = require("../constants"); - -/** - * @typedef {Object} TabAction - * @memberof actions/tabs - * @static - * @property {number} type The type of Action - * @property {number} value The payload of the Action - */ - -/** - * @memberof actions/tabs - * @static - * @param {Array} tabs - * @returns {TabAction} with type constants.ADD_TABS and tabs as value - */ -function newTabs(tabs) { - return { - type: constants.ADD_TABS, - value: tabs - }; -} - -/** - * @memberof actions/tabs - * @static - * @param {String} $0.id Unique ID of the tab to select - * @returns {TabAction} - */ -function selectTab({ id }) { - return { - type: constants.SELECT_TAB, - id: id, - }; -} - -module.exports = { - newTabs, - selectTab -}; diff --git a/packages/devtools-local-toolbox/src/components/LandingPage.css b/packages/devtools-local-toolbox/src/components/LandingPage.css deleted file mode 100644 index 8c88e850e1..0000000000 --- a/packages/devtools-local-toolbox/src/components/LandingPage.css +++ /dev/null @@ -1,132 +0,0 @@ -.landing-page { - flex: 1; - display: flex; - width: 100%; - height: 100%; - flex-direction: row; -} - -.landing-page .sidebar { - display: flex; - background-color: var(--theme-tab-toolbar-background); - width: 200px; - height: 100%; - flex-direction: column; -} - -.landing-page .sidebar h1 { - color: var(--theme-body-color); - font-size: 24px; - margin: 0; - line-height: 30px; - font-weight: normal; - padding: 40px 20px; -} - -.landing-page .sidebar ul { - list-style: none; - padding: 0; - line-height: 30px; - font-size: 18px; -} - -.landing-page .sidebar li { - padding: 5px 20px; -} - -.landing-page .sidebar li.selected { - background: var(--theme-search-overlays-semitransparent); - transition: all 0.25s ease; -} - -.landing-page .sidebar li:hover { - background: var(--theme-selection-background); - cursor: pointer; -} - -.landing-page .sidebar li a { - color: var(--theme-body-color); -} - -.landing-page .sidebar li:hover a { - color: var(--theme-selection-color); -} - -.landing-page .panel { - display: flex; - flex: 1; - height: 100%; - overflow: auto; - flex-direction: column; -} - -.landing-page .panel .title { - margin: 20px 40px; - width: calc(100% - 80px); - font-size: 16px; - border-bottom: 1px solid var(--theme-splitter-color); - height: 54px; -} - -.landing-page .panel h2 { - color: var(--theme-body-color); - font-weight: normal; -} - -.landing-page .panel .center { - flex: 1; - display: flex; - flex-direction: column; -} - -.landing-page .panel .center .center-message { - margin: 40px; - font-size: 16px; - line-height: 25px; - padding: 10px; -} - -.landing-page .center a { - color: var(--theme-highlight-bluegrey); - text-decoration: none; -} - -.landing-page .tab-group { - margin: 40px; -} - -.landing-page .tab-list { - list-style: none; - padding: 0px; - margin: 0px; -} - -.landing-page .tab { - border-bottom: 1px solid var(--theme-splitter-color); - padding: 10px; - font-family: sans-serif; -} - -.landing-page .tab:hover { - background-color: var(--theme-toolbar-background); - cursor: pointer; -} - -.landing-page .tab-title { - line-height: 25px; - font-size: 16px; - color: var(--theme-highlight-bluegrey); -} - -.landing-page .tab-url { - color: var(--theme-comment); -} - -.landing-page .panel .center .footer-note { - flex: 1; - padding: 50px; - font-size: 14px; - color: var(--theme-comment); - bottom: 0; - position: absolute; -} diff --git a/packages/devtools-local-toolbox/src/components/LandingPage.js b/packages/devtools-local-toolbox/src/components/LandingPage.js deleted file mode 100644 index 2b2084d6da..0000000000 --- a/packages/devtools-local-toolbox/src/components/LandingPage.js +++ /dev/null @@ -1,160 +0,0 @@ -const React = require("react"); -const { connect } = require("react-redux"); -const classnames = require("classnames"); -const { getTabs } = require("../selectors"); -const { getValue } = require("devtools-config"); - -require("./LandingPage.css"); -const { DOM: dom } = React; -const ImPropTypes = require("react-immutable-proptypes"); - -const githubUrl = "https://github.com/devtools-html/debugger.html/blob/master"; - -function getTabsByClientType(tabs, clientType) { - return tabs.valueSeq() - .filter(tab => tab.get("clientType") == clientType); -} - -function firstTimeMessage(title, urlPart) { - return dom.div( - { className: "footer-note" }, - `First time connecting to ${title}? Checkout out the `, - dom.a({ href: `${githubUrl}/CONTRIBUTING.md#${urlPart}` }, "docs"), - "." - ); -} - -function getTabURL(tab, paramName) { - const hostURL = getValue("host"); - const tabID = tab.get("id"); - return `${hostURL}?${paramName}=${tabID}`; -} - -const LandingPage = React.createClass({ - propTypes: { - tabs: ImPropTypes.map.isRequired - }, - - displayName: "LandingPage", - - getInitialState() { - return { - selectedPane: "Firefox" - }; - }, - - renderTabs(tabTitle, tabs, paramName) { - if (!tabs || tabs.count() == 0) { - return dom.div({}, ""); - } - - return dom.div( - { className: "tab-group" }, - dom.ul( - { className: "tab-list" }, - tabs.valueSeq().map(tab => dom.li( - { "className": "tab", - "key": tab.get("id"), - "onClick": () => { - window.location = getTabURL(tab, paramName); - } - }, - dom.div({ className: "tab-title" }, tab.get("title")), - dom.div({ className: "tab-url" }, tab.get("url")) - )) - ) - ); - }, - - renderFirefoxPanel() { - const targets = getTabsByClientType(this.props.tabs, "firefox"); - return dom.div( - { className: "center" }, - this.renderTabs("", targets, "firefox-tab"), - firstTimeMessage("Firefox", "firefox") - ); - }, - - renderChromePanel() { - const targets = getTabsByClientType(this.props.tabs, "chrome"); - return dom.div( - { className: "center" }, - this.renderTabs("", targets, "chrome-tab"), - firstTimeMessage("Chrome", "chrome") - ); - }, - - renderNodePanel() { - const targets = getTabsByClientType(this.props.tabs, "node"); - return dom.div( - { className: "center" }, - this.renderTabs("", targets, "node-tab"), - firstTimeMessage("Node", "node") - ); - }, - - renderPanel() { - const panels = { - Firefox: this.renderFirefoxPanel, - Chrome: this.renderChromePanel, - Node: this.renderNodePanel - }; - - return dom.div( - { - className: "panel" - }, - dom.div( - { className: "title" }, - dom.h2({}, this.state.selectedPane) - ), - panels[this.state.selectedPane]() - ); - }, - - renderSidebar() { - let connections = []; - - if (getValue("firefox")) { - connections.push("Firefox"); - } - - if (getValue("chrome")) { - connections.push("Chrome", "Node"); - } - - return dom.div( - { - className: "sidebar" - }, - dom.h1({}, getValue("title")), - dom.ul( - {}, - connections.map(title => dom.li( - { - className: classnames({ - selected: title == this.state.selectedPane - }), - key: title, - - onClick: () => this.setState({ selectedPane: title }) - }, - dom.a({}, title) - ))) - ); - }, - - render() { - return dom.div( - { - className: "landing-page" - }, - this.renderSidebar(), - this.renderPanel() - ); - } -}); - -module.exports = connect( - state => ({ tabs: getTabs(state) }) -)(LandingPage); diff --git a/packages/devtools-local-toolbox/src/components/Root.css b/packages/devtools-local-toolbox/src/components/Root.css deleted file mode 100644 index 3006f48345..0000000000 --- a/packages/devtools-local-toolbox/src/components/Root.css +++ /dev/null @@ -1,41 +0,0 @@ -:root.theme-light, -:root .theme-light { - --theme-search-overlays-semitransparent: rgba(221, 225, 228, 0.66); -} - -* { - box-sizing: border-box; -} - -html, -body { - height: 100%; - margin: 0; - padding: 0; - width: 100%; -} - -#mount { - display: flex; - height: 100%; -} - -::-webkit-scrollbar { - width: 8px; - height: 8px; - background: transparent; -} - -::-webkit-scrollbar-track { - border-radius: 8px; - background: transparent; -} - -::-webkit-scrollbar-thumb { - border-radius: 8px; - background: rgba(113, 113, 113, 0.5); -} - -:root.theme-dark .CodeMirror-scrollbar-filler { - background: transparent; -} diff --git a/packages/devtools-local-toolbox/src/components/Root.js b/packages/devtools-local-toolbox/src/components/Root.js deleted file mode 100644 index a98319e8a4..0000000000 --- a/packages/devtools-local-toolbox/src/components/Root.js +++ /dev/null @@ -1,18 +0,0 @@ -const classnames = require("classnames"); -const { getValue, isDevelopment } = require("devtools-config"); - -require("./Root.css"); - -function themeClass() { - const theme = getValue("theme"); - return `theme-${theme}`; -} - -const rootClass = classnames("theme-body", { [themeClass()]: isDevelopment() }); - -module.exports = function() { - const root = document.createElement("div"); - root.className = rootClass; - root.style.setProperty("flex", 1); - return root; -}; diff --git a/packages/devtools-local-toolbox/src/constants.js b/packages/devtools-local-toolbox/src/constants.js deleted file mode 100644 index 30172e9999..0000000000 --- a/packages/devtools-local-toolbox/src/constants.js +++ /dev/null @@ -1,8 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -exports.ADD_TABS = "ADD_TABS"; -exports.SELECT_TAB = "SELECT_TAB"; diff --git a/packages/devtools-local-toolbox/src/feature.js b/packages/devtools-local-toolbox/src/feature.js deleted file mode 100644 index 21a1ca105a..0000000000 --- a/packages/devtools-local-toolbox/src/feature.js +++ /dev/null @@ -1,7 +0,0 @@ -/** - * This module maps to the config/feature.js to enable - * feature checking within the context of the debugger - */ -const { feature } = require("devtools-config"); - -module.exports = feature; diff --git a/packages/devtools-local-toolbox/src/index.js b/packages/devtools-local-toolbox/src/index.js deleted file mode 100644 index a1dd65c5ec..0000000000 --- a/packages/devtools-local-toolbox/src/index.js +++ /dev/null @@ -1,130 +0,0 @@ -/* global window, document, DebuggerConfig */ - -const { bindActionCreators, combineReducers } = require("redux"); -const { Provider } = require("react-redux"); - -const { DevToolsUtils, AppConstants } = require("devtools-sham-modules"); -const { injectGlobals, debugGlobal } = require("./utils/debug"); -const { setConfig, isEnabled, getValue, isDevelopment } = require("devtools-config"); -const L10N = require("./utils/L10N"); - -setConfig(DebuggerConfig); - -// Set various flags before requiring app code. -if (isEnabled("logging.client")) { - DevToolsUtils.dumpn.wantLogging = true; -} - -const client = require("devtools-client-adapters"); -const { getClient, firefox, chrome, startDebugging } = require("devtools-client-adapters"); - -const Root = require("./components/Root"); - -// Using this static variable allows webpack to know at compile-time -// to avoid this require and not include it at all in the output. -if (process.env.TARGET !== "firefox-panel") { - const theme = getValue("theme"); - switch (theme) { - case "dark": require("./lib/themes/dark-theme.css"); break; - case "light": require("./lib/themes/light-theme.css"); break; - case "firebug": require("./lib/themes/firebug-theme.css"); break; - } - document.body.parentNode.classList.add(`theme-${theme}`); -} - -function initApp() { - const configureStore = require("./utils/create-store"); - const reducers = require("./reducers"); - const LandingPage = require("./components/LandingPage"); - - const createStore = configureStore({ - log: getValue("logging.actions"), - makeThunkArgs: (args, state) => { - return Object.assign({}, args, { client: getClient(state) }); - } - }); - - const store = createStore(combineReducers(reducers)); - const actions = bindActionCreators(require("./actions"), store.dispatch); - - if (isDevelopment()) { - AppConstants.DEBUG_JS_MODULES = true; - injectGlobals({ store }); - } - - return { store, actions, LandingPage }; -} - -function renderRoot(_React, _ReactDOM, component, _store) { - const { createElement } = _React; - const mount = document.querySelector("#mount"); - - // bail in test environments that do not have a mount - if (!mount) { - return; - } - - const root = Root(); - mount.appendChild(root); - - if (component.props || component.propTypes) { - _ReactDOM.render( - createElement(Provider, { store: _store }, createElement(component)), - root - ); - } else { - root.appendChild(component); - } -} - -function getTargetFromQuery() { - const href = window.location.href; - const nodeMatch = href.match(/node-tab=([^&#]*)/); - const firefoxMatch = href.match(/firefox-tab=([^&#]*)/); - const chromeMatch = href.match(/chrome-tab=([^&#]*)/); - - if (nodeMatch) { - return { type: "node", param: nodeMatch[1] }; - } else if (firefoxMatch) { - return { type: "firefox", param: firefoxMatch[1] }; - } else if (chromeMatch) { - return { type: "chrome", param: chromeMatch[1] }; - } - - return null; -} - -function bootstrap(React, ReactDOM, App, appActions, appStore) { - const connTarget = getTargetFromQuery(); - if (connTarget) { - return startDebugging(connTarget, appActions) - .then(({ tab, client }) => { - debugGlobal("client", client.clientCommands); - renderRoot(React, ReactDOM, App, appStore); - return { tab, connTarget, client }; - }); - } else { - const { store, actions, LandingPage } = initApp(); - renderRoot(React, ReactDOM, LandingPage, store); - chrome.connectClient().then(tabs => { - actions.newTabs(tabs); - }).catch(e => { - console.log("Connect to chrome:"); - console.log("https://github.com/devtools-html/debugger.html/blob/master/CONTRIBUTING.md#chrome"); - }); - chrome.connectNodeClient().then(tabs => { - actions.newTabs(tabs); - }); - return firefox.connectClient().then(tabs => { - actions.newTabs(tabs); - }); - } -} - -module.exports = { - bootstrap, - renderRoot, - debugGlobal, - client, - L10N -}; diff --git a/packages/devtools-local-toolbox/src/lib/themes/common.css b/packages/devtools-local-toolbox/src/lib/themes/common.css deleted file mode 100644 index 49c77ae26a..0000000000 --- a/packages/devtools-local-toolbox/src/lib/themes/common.css +++ /dev/null @@ -1,235 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -@import url("splitters.css"); - -:root { - font: message-box; - --monospace-font-family: Menlo, monospace; -} - -:root[platform="mac"] { - --monospace-font-family: Menlo, monospace; -} - -:root[platform="win"] { - --monospace-font-family: Consolas, monospace; -} - -:root[platform="linux"], -:root.theme-firebug { - --monospace-font-family: monospace; -} - -:root.theme-firebug { - --proportional-font-family: Lucida Grande, Tahoma, sans-serif; -} - -.devtools-monospace { - font-family: var(--monospace-font-family); -} - -:root[platform="linux"] .devtools-monospace { - font-size: 80%; -} - - -/* Autocomplete Popup */ - -.devtools-autocomplete-popup { - box-shadow: 0 1px 0 hsla(209,29%,72%,.25) inset; - background-color: transparent; - border-radius: 3px; - overflow-x: hidden; - max-height: 20rem; - - /* Devtools autocompletes display technical english keywords and should be displayed - using LTR direction. */ - direction: ltr !important; -} - -/* Reset list styles. */ -.devtools-autocomplete-popup ul { - list-style: none; -} - -.devtools-autocomplete-popup ul, -.devtools-autocomplete-popup li { - margin: 0; -} - -:root[platform="linux"] .devtools-autocomplete-popup { - /* Root font size is bigger on Linux, adjust rem-based values. */ - max-height: 16rem; -} - -.devtools-autocomplete-listbox { - -moz-appearance: none !important; - background-color: transparent; - border-width: 0px !important; - margin: 0; - padding: 2px; -} - -.devtools-autocomplete-listbox .autocomplete-item { - width: 100%; - background-color: transparent; - border-radius: 4px; - padding: 1px 0; -} - -.devtools-autocomplete-listbox .autocomplete-selected { - background-color: rgba(0,0,0,0.2); -} - -.devtools-autocomplete-listbox.dark-theme .autocomplete-selected, -.devtools-autocomplete-listbox.dark-theme .autocomplete-item:hover { - background-color: rgba(0,0,0,0.5); -} - -.devtools-autocomplete-listbox.dark-theme .autocomplete-selected > .autocomplete-value, -.devtools-autocomplete-listbox:focus.dark-theme .autocomplete-selected > .initial-value { - color: hsl(208,100%,60%); -} - -.devtools-autocomplete-listbox.dark-theme .autocomplete-selected > span { - color: #eee; -} - -.devtools-autocomplete-listbox.dark-theme .autocomplete-item > span { - color: #ccc; -} - -.devtools-autocomplete-listbox .autocomplete-item > .initial-value, -.devtools-autocomplete-listbox .autocomplete-item > .autocomplete-value { - margin: 0; - padding: 0; - cursor: default; -} - -.devtools-autocomplete-listbox .autocomplete-item > .autocomplete-count { - text-align: end; -} - -/* Rest of the dark and light theme */ - -.devtools-autocomplete-popup, -.theme-dark .CodeMirror-hints, -.theme-dark .CodeMirror-Tern-tooltip { - border: 1px solid hsl(210,11%,10%); - background-image: linear-gradient(to bottom, hsla(209,18%,18%,0.9), hsl(210,11%,16%)); -} - -.devtools-autocomplete-popup.light-theme, -.light-theme .CodeMirror-hints, -.light-theme .CodeMirror-Tern-tooltip { - border: 1px solid hsl(210,24%,90%); - background-image: linear-gradient(to bottom, hsla(209,18%,100%,0.9), hsl(210,24%,95%)); -} - -.devtools-autocomplete-popup.light-theme { - box-shadow: 0 1px 0 hsla(209,29%,90%,.25) inset; -} - -.theme-firebug .devtools-autocomplete-popup { - border-color: var(--theme-splitter-color); - border-radius: 5px; - font-size: var(--theme-autompletion-font-size); -} - -.devtools-autocomplete-popup.firebug-theme { - background: var(--theme-body-background); -} - -.devtools-autocomplete-listbox.firebug-theme .autocomplete-selected, -.devtools-autocomplete-listbox.firebug-theme .autocomplete-item:hover, -.devtools-autocomplete-listbox.light-theme .autocomplete-selected, -.devtools-autocomplete-listbox.light-theme .autocomplete-item:hover { - background-color: rgba(128,128,128,0.3); -} - -.devtools-autocomplete-listbox.firebug-theme .autocomplete-selected > .autocomplete-value, -.devtools-autocomplete-listbox:focus.firebug-theme .autocomplete-selected > .initial-value, -.devtools-autocomplete-listbox.light-theme .autocomplete-selected > .autocomplete-value, -.devtools-autocomplete-listbox:focus.light-theme .autocomplete-selected > .initial-value { - color: #222; -} - -.devtools-autocomplete-listbox.firebug-theme .autocomplete-item > span, -.devtools-autocomplete-listbox.light-theme .autocomplete-item > span { - color: #666; -} - -/* Autocomplete list clone used for accessibility. */ - -.devtools-autocomplete-list-aria-clone { - /* Cannot use display:none or visibility:hidden : screen readers ignore the element. */ - position: fixed; - overflow: hidden; - margin: 0; - width: 0; - height: 0; -} - -.devtools-autocomplete-list-aria-clone li { - /* Prevent screen readers from prefacing every item with 'bullet'. */ - list-style-type: none; -} - -/* links to source code, like displaying `myfile.js:45` */ - -.devtools-source-link { - font-family: var(--monospace-font-family); - color: var(--theme-highlight-blue); - cursor: pointer; - white-space: nowrap; - display: flex; - text-decoration: none; - font-size: 11px; - width: 12em; /* probably should be changed for each tool */ -} - -.devtools-source-link:hover { - text-decoration: underline; -} - -.devtools-source-link > .filename { - text-overflow: ellipsis; - text-align: end; - overflow: hidden; - margin: 2px 0px; - cursor: pointer; -} - -.devtools-source-link > .line-number { - flex: none; - margin: 2px 0px; - cursor: pointer; -} - -/* Keyboard focus highlight styles */ - -:-moz-focusring { - outline: var(--theme-focus-outline); - outline-offset: -1px; -} - -textbox[focused="true"] { - border-color: var(--theme-focus-border-color-textbox); - box-shadow: var(--theme-focus-box-shadow-textbox); - transition: all 0.2s ease-in-out -} - -textbox :-moz-focusring { - box-shadow: none; - outline: none; -} - -/* Form fields should already have box-shadow hightlight */ -select:-moz-focusring, -input[type="radio"]:-moz-focusring, -input[type="checkbox"]:-moz-focusring, -checkbox:-moz-focusring { - outline: none; -} diff --git a/packages/devtools-local-toolbox/src/lib/themes/components-h-split-box.css b/packages/devtools-local-toolbox/src/lib/themes/components-h-split-box.css deleted file mode 100644 index ad667625ef..0000000000 --- a/packages/devtools-local-toolbox/src/lib/themes/components-h-split-box.css +++ /dev/null @@ -1,31 +0,0 @@ -/* vim:set ts=2 sw=2 sts=2 et: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/** - * HSplitBox Component - * Styles for React component at `devtools/client/shared/components/h-split-box.js` - */ - -.h-split-box, -.h-split-box-pane { - overflow: auto; - margin: 0; - padding: 0; - width: 100%; - height: 100%; -} - -.h-split-box { - display: flex; - flex-direction: row; - flex: 1; -} - -.h-split-box-splitter { - -moz-border-end: 1px solid var(--theme-splitter-color); - cursor: ew-resize; - width: 3px; - -moz-margin-start: -3px; -} diff --git a/packages/devtools-local-toolbox/src/lib/themes/dark-theme.css b/packages/devtools-local-toolbox/src/lib/themes/dark-theme.css deleted file mode 100644 index a7ba8087a8..0000000000 --- a/packages/devtools-local-toolbox/src/lib/themes/dark-theme.css +++ /dev/null @@ -1,392 +0,0 @@ -/* vim:set ts=2 sw=2 sts=2 et: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -@import url(variables.css); -@import url(common.css); -@import url(toolbars.css); -@import url(tooltips.css); - -body { - margin: 0; -} - -.theme-body { - background: var(--theme-body-background); - color: var(--theme-body-color); -} - -.theme-sidebar { - background: var(--theme-sidebar-background); - color: var(--theme-content-color1); -} - -::-moz-selection { - background-color: var(--theme-selection-background); - color: var(--theme-selection-color); -} - -.theme-bg-darker { - background-color: var(--theme-selection-background-semitransparent); -} - -.theme-selected, -.CodeMirror-hint-active { - background-color: var(--theme-selection-background); - color: var(--theme-selection-color); -} - -.theme-bg-contrast, -.variable-or-property:not([overridden])[changed] { - background: var(--theme-contrast-background); -} - -.theme-link, -.cm-s-mozilla .cm-link, -.cm-s-mozilla .cm-keyword { - color: var(--theme-highlight-green); -} - -/* - * FIXME: http://bugzil.la/575675 CSS links without :visited set cause assertion - * failures in debug builds. - */ -.theme-link:visited, -.cm-s-mozilla .cm-link:visited, -.CodeMirror-Tern-type { - color: var(--theme-highlight-blue); -} - - -.theme-comment, -.cm-s-mozilla .cm-meta, -.cm-s-mozilla .cm-hr, -.cm-s-mozilla .cm-comment, -.variable-or-property .token-undefined, -.variable-or-property .token-null, -.CodeMirror-Tern-completion-unknown:before { - color: var(--theme-comment); -} - -.theme-gutter { - background-color: var(--theme-tab-toolbar-background); - color: var(--theme-content-color3); - border-color: var(--theme-splitter-color); -} - -.theme-separator { - border-color: var(--theme-splitter-color); -} - -.theme-fg-color1, -.cm-s-mozilla .cm-number, -.variable-or-property .token-number, -.variable-or-property[return] > .title > .name, -.variable-or-property[scope] > .title > .name { - color: var(--theme-highlight-red); -} - -.CodeMirror-Tern-completion-number:before { - background-color: #5c9966; -} - -.theme-fg-color2, -.cm-s-mozilla .cm-attribute, -.cm-s-mozilla .cm-def, -.cm-s-mozilla .cm-property, -.cm-s-mozilla .cm-qualifier, -.variables-view-variable > .title > .name { - color: var(--theme-highlight-purple); -} - -.CodeMirror-Tern-completion-object:before { - background-color: #3689b2; -} - -.cm-s-mozilla .cm-unused-line { - text-decoration: line-through; - text-decoration-color: #0072ab; -} - -.cm-s-mozilla .cm-executed-line { - background-color: #133c26; -} - -.theme-fg-color3, -.cm-s-mozilla .cm-builtin, -.cm-s-mozilla .cm-tag, -.cm-s-mozilla .cm-header, -.cm-s-mozilla .cm-bracket, -.variables-view-property > .title > .name { - color: var(--theme-highlight-green); -} - -.CodeMirror-Tern-completion-array:before { - background-color: var(--theme-highlight-bluegrey); -} - -.theme-fg-color4 { - color: var(--theme-highlight-purple); -} - -.theme-fg-color5 { - color: var(--theme-highlight-purple); -} - -.theme-fg-color6, -.cm-s-mozilla .cm-string, -.cm-s-mozilla .cm-string-2, -.variable-or-property .token-string, -.cm-s-mozilla .cm-variable, -.CodeMirror-Tern-farg { - color: var(--theme-highlight-gray); -} - -.CodeMirror-Tern-completion-string:before, -.CodeMirror-Tern-completion-fn:before { - background-color: #b26b47; -} - -.theme-fg-color7, -.cm-s-mozilla .cm-atom, -.cm-s-mozilla .cm-quote, -.cm-s-mozilla .cm-error, -.variable-or-property .token-boolean, -.variable-or-property .token-domnode, -.variable-or-property[exception] > .title > .name { - color: var(--theme-highlight-red); -} - -.CodeMirror-Tern-completion-bool:before { - background-color: #bf5656; -} - -.variable-or-property .token-domnode { - font-weight: bold; -} - -.theme-toolbar, -.devtools-toolbar, -.devtools-sidebar-tabs tabs, -.devtools-sidebar-alltabs, -.cm-s-mozilla .CodeMirror-dialog { /* General toolbar styling */ - color: var(--theme-body-color-alt); - background-color: var(--theme-toolbar-background); - border-color: var(--theme-splitter-color); -} - -.theme-fg-contrast { /* To be used for text on theme-bg-contrast */ - color: black; -} - -.ruleview-swatch, -.computedview-colorswatch { - box-shadow: 0 0 0 1px #818181; -} - -/* CodeMirror specific styles. - * Best effort to match the existing theme, some of the colors - * are duplicated here to prevent weirdness in the main theme. */ - -.CodeMirror.cm-s-mozilla { /* Inherit platform specific font sizing and styles */ - font-family: inherit; - font-size: inherit; - background: transparent; -} - -.CodeMirror.cm-s-mozilla pre, -.cm-s-mozilla .cm-variable-2, -.cm-s-mozilla .cm-variable-3, -.cm-s-mozilla .cm-operator, -.cm-s-mozilla .cm-special { - color: var(--theme-content-color1); -} - -.cm-s-mozilla .CodeMirror-lines .CodeMirror-cursor { - border-left: solid 1px #fff; -} - -.cm-s-mozilla.CodeMirror-focused .CodeMirror-selected { /* selected text (focused) */ - background: rgb(185, 215, 253); -} - -.cm-s-mozilla .CodeMirror-selected { /* selected text (unfocused) */ - background: rgb(255, 255, 0); -} - -.cm-s-mozilla .CodeMirror-activeline-background { /* selected color with alpha */ - background: rgba(185, 215, 253, .15); -} - -div.cm-s-mozilla span.CodeMirror-matchingbracket { /* highlight brackets */ - outline: solid 1px rgba(255, 255, 255, .25); - color: white; -} - -/* Highlight for a line that contains an error. */ -div.CodeMirror div.error-line { - background: rgba(255,0,0,0.2); -} - -/* Generic highlighted text */ -div.CodeMirror span.marked-text { - background: rgba(255,255,0,0.2); - border: 1px dashed rgba(192,192,0,0.6); - margin-inline-start: -1px; - margin-inline-end: -1px; -} - -/* Highlight for evaluating current statement. */ -div.CodeMirror span.eval-text { - background-color: #556; -} - -.cm-s-mozilla .CodeMirror-linenumber { /* line number text */ - color: var(--theme-content-color3); -} - -.cm-s-mozilla .CodeMirror-gutters { /* vertical line next to line numbers */ - border-right-color: var(--theme-toolbar-background); - background-color: var(--theme-sidebar-background); -} - -.cm-s-markup-view pre { - line-height: 1.4em; - min-height: 1.4em; -} - -/* Twisty and checkbox controls */ -.theme-twisty, .theme-checkbox { - width: 14px; - height: 14px; - background-repeat: no-repeat; - /*background-image: url("chrome://devtools/skin/images/controls.png");*/ - background-size: 56px 28px; -} - -.theme-twisty { - cursor: pointer; - background-position: -28px -14px; -} - -.theme-twisty:-moz-focusring { - outline-style: none; -} - -.theme-twisty[open], .theme-twisty.open { - background-position: -42px -14px; -} - -.theme-twisty[invisible] { - visibility: hidden; -} - -.theme-checkbox { - display: inline-block; - border: 0; - padding: 0; - outline: none; - background-position: -28px 0; -} - -.theme-checkbox[checked] { - background-position: -42px 0; -} - -@media (min-resolution: 1.1dppx) { - .theme-twisty, .theme-checkbox { - /*background-image: url("chrome://devtools/skin/images/controls@2x.png");*/ - } -} - -/* XUL panel styling (see devtools/client/shared/widgets/Tooltip.js) */ - -.theme-tooltip-panel .panel-arrowcontent { - padding: 5px; - background: rgba(19, 28, 38, .9); - border-radius: 5px; - box-shadow: none; - border: 3px solid #434850; -} - -/* Overring panel arrow images to fit with our light and dark themes */ - -.theme-tooltip-panel .panel-arrow { - --arrow-margin: -4px; -} - -:root[platform="win"] .theme-tooltip-panel .panel-arrow { - --arrow-margin: -7px; -} - -.theme-tooltip-panel .panel-arrow[side="top"], -.theme-tooltip-panel .panel-arrow[side="bottom"] { - /*list-style-image: url("chrome://devtools/skin/tooltip/arrow-vertical-dark.png");*/ - /* !important is needed to override the popup.css rules in toolkit/themes */ - width: 39px !important; - height: 16px !important; -} - -.theme-tooltip-panel .panel-arrow[side="left"], -.theme-tooltip-panel .panel-arrow[side="right"] { - /*list-style-image: url("chrome://devtools/skin/tooltip/arrow-horizontal-dark.png");*/ - /* !important is needed to override the popup.css rules in toolkit/themes */ - width: 16px !important; - height: 39px !important; -} - -.theme-tooltip-panel .panel-arrow[side="top"] { - margin-bottom: var(--arrow-margin); -} - -.theme-tooltip-panel .panel-arrow[side="bottom"] { - margin-top: var(--arrow-margin); -} - -.theme-tooltip-panel .panel-arrow[side="left"] { - margin-right: var(--arrow-margin); -} - -.theme-tooltip-panel .panel-arrow[side="right"] { - margin-left: var(--arrow-margin); -} - -@media (min-resolution: 1.1dppx) { - .theme-tooltip-panel .panel-arrow[side="top"], - .theme-tooltip-panel .panel-arrow[side="bottom"] { - /*list-style-image: url("chrome://devtools/skin/tooltip/arrow-vertical-dark@2x.png");*/ - } - - .theme-tooltip-panel .panel-arrow[side="left"], - .theme-tooltip-panel .panel-arrow[side="right"] { - /*list-style-image: url("chrome://devtools/skin/tooltip/arrow-horizontal-dark@2x.png");*/ - } -} - -.theme-tooltip-panel .devtools-tooltip-simple-text { - color: white; - border-bottom: 1px solid #434850; -} - -.theme-tooltip-panel .devtools-tooltip-simple-text:last-child { - border-bottom: 0; -} - -.devtools-textinput, -.devtools-searchinput, -.devtools-filterinput { - background-color: rgba(24, 29, 32, 1); - color: rgba(184, 200, 217, 1); -} - -.CodeMirror-Tern-fname { - color: #f7f7f7; -} - -.CodeMirror-hints, -.CodeMirror-Tern-tooltip { - box-shadow: 0 0 4px rgba(255, 255, 255, .3); - background-color: #0f171f; - color: var(--theme-body-color); -} diff --git a/packages/devtools-local-toolbox/src/lib/themes/firebug-theme.css b/packages/devtools-local-toolbox/src/lib/themes/firebug-theme.css deleted file mode 100644 index e99c411ec8..0000000000 --- a/packages/devtools-local-toolbox/src/lib/themes/firebug-theme.css +++ /dev/null @@ -1,235 +0,0 @@ -/* vim:set ts=2 sw=2 sts=2 et: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -@import url(variables.css); -@import url(common.css); -@import url(light-theme.css); - -:root { - font-size: 11px; - font-family: var(--proportional-font-family); -} - -/* CodeMirror Color Syntax */ - -.theme-firebug .cm-keyword {color: BlueViolet; font-weight: bold;} -.theme-firebug .cm-atom {color: #219;} -.theme-firebug .cm-number {color: #164;} -.theme-firebug .cm-def {color: #00f;} -.theme-firebug .cm-variable {color: black;} -.theme-firebug .cm-variable-2 {color: black;} -.theme-firebug .cm-variable-3 {color: black;} -.theme-firebug .cm-property {color: black;} -.theme-firebug .cm-operator {color: black;} -.theme-firebug .cm-comment {color: Silver;} -.theme-firebug .cm-string {color: Red;} -.theme-firebug .cm-string-2 {color: Red;} -.theme-firebug .cm-meta {color: rgb(120, 120, 120); font-style: italic;} -.theme-firebug .cm-error {color: #f00;} -.theme-firebug .cm-qualifier {color: #555;} -.theme-firebug .cm-builtin {color: #30a;} -.theme-firebug .cm-bracket {color: #997;} -.theme-firebug .cm-tag {color: blue;} -.theme-firebug .cm-attribute {color: rgb(0, 0, 136);} -.theme-firebug .cm-header {color: blue;} -.theme-firebug .cm-quote {color: #090;} -.theme-firebug .cm-hr {color: #999;} -.theme-firebug .cm-link {color: #00c;} - -.theme-firebug .theme-fg-color3, -.theme-firebug .cm-s-mozilla .kind-Object .cm-variable{ /* dark blue */ - color: #006400; - font-style: normal; - font-weight: bold; -} - -.theme-firebug .console-string { - color: #FF183C; -} - -/* Variables View */ - -.theme-firebug .variables-view-variable > .title > .name, -.theme-firebug .variables-view-variable > .title > .value { - color: var(--theme-body-color); -} - -/* Firebug theme support for tabbar and panel tabs - (both, main and side panels )*/ - -/* Only apply bottom-border for: - 1) The main tab list. - 2) The side tab list if there is no scroll-box that has its own border. - - Use !important to override even the rule in webconsole.css that uses - ID in the selector. */ -.theme-firebug .devtools-tabbar, -.theme-firebug .devtools-sidebar-tabs tabs { - background-image: linear-gradient(rgba(253, 253, 253, 0.2), rgba(253, 253, 253, 0)); - border-bottom: 1px solid rgb(170, 188, 207) !important; -} - -.theme-firebug .devtools-sidebar-tabs tabs { - background-color: var(--theme-tab-toolbar-background) !important; - background-image: linear-gradient(rgba(255, 255, 255, 0.8), rgba(255, 255, 255, 0.2)); -} - -/* Add a negative bottom margin to overlap bottom border - of the parent element (see also the next comment for 'tabs') */ -.theme-firebug .devtools-tab, -.theme-firebug .devtools-sidebar-tabs tab { - margin: 3px 0 -1px 0; - padding: 2px 0 0 0; - border: 1px solid transparent !important; - border-radius: 4px 4px 0 0; - font-weight: bold; - color: var(--theme-body-color); - -moz-box-flex: initial; - min-width: 0; -} - -/* Also add negative bottom margin for side panel tabs*/ -.theme-firebug .devtools-sidebar-tabs tab { -} - -/* In order to hide bottom-border of side panel tabs we need - to make the parent element overflow visible, so child element - can move one pixel down to hide the bottom border of the parent. */ -.theme-firebug .devtools-sidebar-tabs tabs { - overflow: visible; -} - -.theme-firebug .devtools-tab:hover, -.theme-firebug .devtools-sidebar-tabs tab:hover { - border: 1px solid #C8C8C8 !important; - border-bottom: 1px solid transparent; -} - -.theme-firebug .devtools-tab[selected], -.theme-firebug .devtools-sidebar-tabs tab[selected] { - background-color: rgb(247, 251, 254); - border: 1px solid rgb(170, 188, 207) !important; - border-bottom-width: 0 !important; - padding-bottom: 2px; - color: inherit; -} - -.theme-firebug .devtools-tab spacer, -.theme-firebug .devtools-tab image { - display: none; -} - -.theme-firebug .toolbox-tab label { - margin: 0; -} - -.theme-firebug .devtools-sidebar-tabs tab label { - margin: 2px 0 0 0; -} - -/* Use different padding for labels inside tabs on Win platform. - Make sure this overrides the default in global.css */ -:root[platform="win"].theme-firebug .devtools-sidebar-tabs tab label { - margin: 0 4px !important; -} - -.theme-firebug #panelSideBox .devtools-tab[selected], -.theme-firebug .devtools-sidebar-tabs tab[selected] { - background-color: white; -} - -.theme-firebug #panelSideBox .devtools-tab:first-child, -.theme-firebug .devtools-sidebar-tabs tab:first-child { - margin-inline-start: 5px; -} - -/* Firebug theme support for the Option (panel) tab */ - -.theme-firebug #toolbox-tab-options { - margin-inline-end: 4px; - background-color: white; -} - -.theme-firebug #toolbox-tab-options::before { - /*content: url(chrome://devtools/skin/images/firebug/tool-options.svg);*/ - display: block; - margin: 4px 7px 0; -} - -.theme-firebug #toolbox-tab-options:not([selected]):hover::before { - filter: brightness(80%); -} - -/* Toolbar */ - -.theme-firebug .theme-toolbar, -.theme-firebug toolbar, -.theme-firebug .devtools-toolbar { - border-bottom: 1px solid rgb(170, 188, 207) !important; - background-color: var(--theme-tab-toolbar-background) !important; - background-image: linear-gradient(rgba(255, 255, 255, 0.8), rgba(255, 255, 255, 0.2)); - padding-inline-end: 4px; -} - -/* The vbox for panel content also uses theme-toolbar class from some reason - but it shouldn't have the padding as defined above, so fix it here */ -.theme-firebug #toolbox-deck > .toolbox-panel.theme-toolbar { - padding-inline-end: 0; -} - -/* Space around toolbar buttons */ -.theme-firebug .devtools-toolbar { - padding: 3px; -} - -/* The height is the same for all toolbars and side panels tabs */ -.theme-firebug .theme-toolbar, -.theme-firebug .devtools-sidebar-tabs tabs, -.theme-firebug .devtools-toolbar { - height: 28px !important; -} - -/* Do not set the fixed height for rule viewtoolbar. This toolbar - is changing its height to show pseudo classes. */ -.theme-firebug #ruleview-toolbar-container { - height: auto !important; -} - -/* The Inspector panel side panels are using both - .devtools-toolbar and .theme-toolbar. We want the - proportional font for all labels in these toolbars */ -.theme-firebug .devtools-toolbar label, -.theme-firebug .devtools-toolbar .label, -.theme-firebug .theme-toolbar label, -.theme-firebug .theme-toolbar .label { - font-family: var(--proportional-font-family); -} - -/* Toolbar Buttons */ - -.theme-firebug .theme-toolbar button, -.theme-firebug .devtools-button, -.theme-firebug toolbarbutton { - margin: 1px; - border-radius: 2px; - color: var(--theme-body-color); - line-height: var(--theme-toolbar-font-size); - font-size: var(--theme-toolbar-font-size); -} - -.theme-firebug .theme-toolbar button, -.theme-firebug .devtools-button { - border-width: 1px !important; - min-width: 24px; -} - -.theme-firebug .devtools-toolbarbutton { - min-width: 24px; -} - - -.theme-firebug #element-picker { - min-height: 21px; -} diff --git a/packages/devtools-local-toolbox/src/lib/themes/light-theme.css b/packages/devtools-local-toolbox/src/lib/themes/light-theme.css deleted file mode 100644 index 2c5590b81b..0000000000 --- a/packages/devtools-local-toolbox/src/lib/themes/light-theme.css +++ /dev/null @@ -1,392 +0,0 @@ -/* vim:set ts=2 sw=2 sts=2 et: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -@import url(variables.css); -@import url(common.css); -@import url(toolbars.css); -@import url(tooltips.css); - -body { - margin: 0; -} - -.theme-body { - background: var(--theme-body-background); - color: var(--theme-body-color); -} - -.theme-sidebar { - background: var(--theme-sidebar-background); - color: var(--theme-body-color); -} - -::-moz-selection { - background-color: var(--theme-selection-background); - color: var(--theme-selection-color); -} - -.theme-bg-darker { - background: var(--theme-selection-background-semitransparent); -} - -.theme-selected, -.CodeMirror-hint-active { - background-color: var(--theme-selection-background); - color: var(--theme-selection-color); -} - -.theme-bg-contrast, -.variable-or-property:not([overridden])[changed] { - background: var(--theme-contrast-background); -} - -.theme-link, -.cm-s-mozilla .cm-link, -.CodeMirror-Tern-type { - color: var(--theme-highlight-blue); -} - -/* - * FIXME: http://bugzil.la/575675 CSS links without :visited set cause assertion - * failures in debug builds. - */ -.theme-link:visited, -.cm-s-mozilla .cm-link:visited { - color: var(--theme-highlight-blue); -} - -.theme-comment, -.cm-s-mozilla .cm-meta, -.cm-s-mozilla .cm-hr, -.cm-s-mozilla .cm-comment, -.variable-or-property .token-undefined, -.variable-or-property .token-null, -.CodeMirror-Tern-completion-unknown:before { - color: var(--theme-comment); -} - -.theme-gutter { - background-color: var(--theme-tab-toolbar-background); - color: var(--theme-content-color3); - border-color: var(--theme-splitter-color); -} - -.theme-separator { /* grey */ - border-color: #cddae5; -} - -.cm-s-mozilla .cm-unused-line { - text-decoration: line-through; - text-decoration-color: var(--theme-highlight-bluegrey); -} - -.cm-s-mozilla .cm-executed-line { - background-color: #fcfffc; -} - -.theme-fg-color1, -.cm-s-mozilla .cm-number, -.variable-or-property .token-number, -.variable-or-property[return] > .title > .name, -.variable-or-property[scope] > .title > .name { - color: var(--theme-highlight-purple); -} - -.CodeMirror-Tern-completion-number:before { - background-color: hsl(72,100%,27%); -} - -.theme-fg-color2, -.cm-s-mozilla .cm-attribute, -.cm-s-mozilla .cm-builtin, -.cm-s-mozilla .cm-property, -.variables-view-variable > .title > .name { - color: var(--theme-highlight-red); -} - -.cm-s-mozilla .cm-def { - color: var(--theme-body-color); -} - -.CodeMirror-Tern-completion-object:before { - background-color: hsl(208,56%,40%); -} - -.theme-fg-color3, -.cm-s-mozilla .cm-variable, -.cm-s-mozilla .cm-tag, -.cm-s-mozilla .cm-header, -.cm-s-mozilla .cm-bracket, -.cm-s-mozilla .cm-qualifier, -.variables-view-property > .title > .name { - color: var(--theme-highlight-blue); -} - -.CodeMirror-Tern-completion-array:before { - background-color: var(--theme-highlight-bluegrey); -} - -.theme-fg-color4 { - color: var(--theme-highlight-orange); -} - -.theme-fg-color5, -.cm-s-mozilla .cm-keyword { - color: var(--theme-highlight-red); -} - -.theme-fg-color6, -.cm-s-mozilla .cm-string, -.cm-s-mozilla .cm-string-2, -.variable-or-property .token-string, -.CodeMirror-Tern-farg { - color: var(--theme-highlight-purple); -} - -.CodeMirror-Tern-completion-string:before, -.CodeMirror-Tern-completion-fn:before { - background-color: hsl(24,85%,39%); -} - -.theme-fg-color7, -.cm-s-mozilla .cm-atom, -.cm-s-mozilla .cm-quote, -.cm-s-mozilla .cm-error, -.variable-or-property .token-boolean, -.variable-or-property .token-domnode, -.variable-or-property[exception] > .title > .name { - color: var(--theme-highlight-red); -} - -.CodeMirror-Tern-completion-bool:before { - background-color: #bf5656; -} - -.variable-or-property .token-domnode { - font-weight: bold; -} - -.theme-fg-contrast { /* To be used for text on theme-bg-contrast */ - color: black; -} - -.theme-toolbar, -.devtools-toolbar, -.devtools-sidebar-tabs tabs, -.devtools-sidebar-alltabs, -.cm-s-mozilla .CodeMirror-dialog { /* General toolbar styling */ - color: var(--theme-body-color); - background-color: var(--theme-toolbar-background); - border-color: var(--theme-splitter-color); -} - -.ruleview-swatch, -.computedview-colorswatch { - box-shadow: 0 0 0 1px #c4c4c4; -} - -/* CodeMirror specific styles. - * Best effort to match the existing theme, some of the colors - * are duplicated here to prevent weirdness in the main theme. */ - -.CodeMirror.cm-s-mozilla { /* Inherit platform specific font sizing and styles */ - font-family: inherit; - font-size: inherit; - background: transparent; -} - -.CodeMirror.cm-s-mozilla pre, -.cm-s-mozilla .cm-variable-2, -.cm-s-mozilla .cm-variable-3, -.cm-s-mozilla .cm-operator, -.cm-s-mozilla .cm-special { - color: var(--theme-body-color); -} - -.cm-s-mozilla .CodeMirror-lines .CodeMirror-cursor { - border-left: solid 1px black; -} - -.cm-s-mozilla.CodeMirror-focused .CodeMirror-selected { /* selected text (focused) */ - background: rgb(185, 215, 253); -} - -.cm-s-mozilla .CodeMirror-selected { /* selected text (unfocused) */ - background: rgb(255, 255, 0); -} - -.cm-s-mozilla .CodeMirror-activeline-background { /* selected color with alpha */ - background: rgba(185, 215, 253, .35); -} - -div.cm-s-mozilla span.CodeMirror-matchingbracket { /* highlight brackets */ - outline: solid 1px rgba(0, 0, 0, .25); - color: black; -} - -/* Highlight for a line that contains an error. */ -div.CodeMirror div.error-line { - background: rgba(255,0,0,0.2); -} - -/* Generic highlighted text */ -div.CodeMirror span.marked-text { - background: rgba(255,255,0,0.2); - border: 1px dashed rgba(192,192,0,0.6); - margin-inline-start: -1px; - margin-inline-end: -1px; -} - -/* Highlight for evaluating current statement. */ -div.CodeMirror span.eval-text { - background-color: #ccd; -} - -.cm-s-mozilla .CodeMirror-linenumber { /* line number text */ - color: var(--theme-content-color3); -} - -.cm-s-mozilla .CodeMirror-gutters { /* vertical line next to line numbers */ - border-right-color: var(--theme-splitter-color); - background-color: var(--theme-sidebar-background); -} - -.cm-s-markup-view pre { - line-height: 1.4em; - min-height: 1.4em; -} - -/* Twisty and checkbox controls */ - -.theme-twisty, .theme-checkbox { - width: 14px; - height: 14px; - background-repeat: no-repeat; - /* background-image: url("chrome://devtools/skin/images/controls.png"); */ - background-size: 56px 28px; -} - -.theme-twisty { - cursor: pointer; - background-position: 0 -14px; -} - -.theme-twisty:-moz-focusring { - outline-style: none; -} - -.theme-twisty[open], .theme-twisty.open { - background-position: -14px -14px; -} - -.theme-twisty[invisible] { - visibility: hidden; -} - -/* Use white twisty when next to a selected item in markup view */ -.theme-selected ~ .theme-twisty { - background-position: -28px -14px; -} - -.theme-selected ~ .theme-twisty[open] { - background-position: -42px -14px; -} - -.theme-checkbox { - display: inline-block; - border: 0; - padding: 0; - outline: none; - background-position: 0 0; -} - -.theme-checkbox[checked] { - background-position: -14px 0; -} - -@media (min-resolution: 1.1dppx) { - .theme-twisty, .theme-checkbox { - /* background-image: url("chrome://devtools/skin/images/controls@2x.png"); */ - } -} - -/* XUL panel styling (see devtools/client/shared/widgets/Tooltip.js) */ - -.theme-tooltip-panel .panel-arrowcontent { - padding: 4px; - background: rgba(255, 255, 255, .9); - border-radius: 5px; - box-shadow: none; - border: 3px solid #d9e1e8; -} - -/* Overring panel arrow images to fit with our light and dark themes */ - -.theme-tooltip-panel .panel-arrow { - --arrow-margin: -4px; -} - -:root[platform="win"] .theme-tooltip-panel .panel-arrow { - --arrow-margin: -7px; -} - -.theme-tooltip-panel .panel-arrow[side="top"], -.theme-tooltip-panel .panel-arrow[side="bottom"] { - /* list-style-image: url("chrome://devtools/skin/tooltip/arrow-vertical-light.png"); */ - /* !important is needed to override the popup.css rules in toolkit/themes */ - width: 39px !important; - height: 16px !important; -} - -.theme-tooltip-panel .panel-arrow[side="left"], -.theme-tooltip-panel .panel-arrow[side="right"] { - /* list-style-image: url("chrome://devtools/skin/tooltip/arrow-horizontal-light.png"); */ - /* !important is needed to override the popup.css rules in toolkit/themes */ - width: 16px !important; - height: 39px !important; -} - -.theme-tooltip-panel .panel-arrow[side="top"] { - margin-bottom: var(--arrow-margin); -} - -.theme-tooltip-panel .panel-arrow[side="bottom"] { - margin-top: var(--arrow-margin); -} - -.theme-tooltip-panel .panel-arrow[side="left"] { - margin-right: var(--arrow-margin); -} - -.theme-tooltip-panel .panel-arrow[side="right"] { - margin-left: var(--arrow-margin); -} - -@media (min-resolution: 1.1dppx) { - .theme-tooltip-panel .panel-arrow[side="top"], - .theme-tooltip-panel .panel-arrow[side="bottom"] { - /* list-style-image: url("chrome://devtools/skin/tooltip/arrow-vertical-light@2x.png"); */ - } - - .theme-tooltip-panel .panel-arrow[side="left"], - .theme-tooltip-panel .panel-arrow[side="right"] { - /* list-style-image: url("chrome://devtools/skin/tooltip/arrow-horizontal-light@2x.png"); */ - } -} - -.theme-tooltip-panel .devtools-tooltip-simple-text { - color: black; - border-bottom: 1px solid #d9e1e8; -} - -.theme-tooltip-panel .devtools-tooltip-simple-text:last-child { - border-bottom: 0; -} - -.CodeMirror-hints, -.CodeMirror-Tern-tooltip { - box-shadow: 0 0 4px rgba(128, 128, 128, .5); - background-color: var(--theme-sidebar-background); -} diff --git a/packages/devtools-local-toolbox/src/lib/themes/splitters.css b/packages/devtools-local-toolbox/src/lib/themes/splitters.css deleted file mode 100644 index ade867d524..0000000000 --- a/packages/devtools-local-toolbox/src/lib/themes/splitters.css +++ /dev/null @@ -1,80 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* This file is loaded by both browser.xul and toolbox.xul. Therefore, rules - defined here can not rely on toolbox.xul variables. */ - -/* Splitters */ - -:root { - /* Define the widths of the draggable areas on each side of a splitter. top - and bottom widths are used for horizontal splitters, inline-start and - inline-end for side splitters.*/ - - --devtools-splitter-top-width: 2px; - --devtools-splitter-bottom-width: 2px; - - /* Small draggable area on inline-start to avoid overlaps on scrollbars.*/ - --devtools-splitter-inline-start-width: 1px; - --devtools-splitter-inline-end-width: 4px; -} - -:root[devtoolstheme="light"] { - /* These variables are used in browser.xul but inside the toolbox they are overridden by --theme-splitter-color */ - --devtools-splitter-color: #dde1e4; -} - -:root[devtoolstheme="dark"], -:root[devtoolstheme="firebug"] { - --devtools-splitter-color: #42484f; -} - -.devtools-horizontal-splitter, -.devtools-side-splitter { - -moz-appearance: none; - background-image: none; - border: 0; - border-style: solid; - border-color: transparent; - background-color: var(--devtools-splitter-color); - background-clip: content-box; - position: relative; - - box-sizing: border-box; - - /* Positive z-index positions the splitter on top of its siblings and makes - it clickable on both sides. */ - z-index: 1; -} - -.devtools-horizontal-splitter { - min-height: calc(var(--devtools-splitter-top-width) + - var(--devtools-splitter-bottom-width) + 1px); - - border-top-width: var(--devtools-splitter-top-width); - border-bottom-width: var(--devtools-splitter-bottom-width); - - margin-top: calc(-1 * var(--devtools-splitter-top-width) - 1px); - margin-bottom: calc(-1 * var(--devtools-splitter-bottom-width)); - - cursor: n-resize; -} - -.devtools-side-splitter { - min-width: calc(var(--devtools-splitter-inline-start-width) + - var(--devtools-splitter-inline-end-width) + 1px); - - border-inline-start-width: var(--devtools-splitter-inline-start-width); - border-inline-end-width: var(--devtools-splitter-inline-end-width); - - margin-inline-start: calc(-1 * var(--devtools-splitter-inline-start-width) - 1px); - margin-inline-end: calc(-1 * var(--devtools-splitter-inline-end-width)); - - cursor: e-resize; -} - -.devtools-horizontal-splitter.disabled, -.devtools-side-splitter.disabled { - pointer-events: none; -} diff --git a/packages/devtools-local-toolbox/src/lib/themes/toolbars.css b/packages/devtools-local-toolbox/src/lib/themes/toolbars.css deleted file mode 100644 index ded2d0f15b..0000000000 --- a/packages/devtools-local-toolbox/src/lib/themes/toolbars.css +++ /dev/null @@ -1,693 +0,0 @@ -/* vim:set ts=2 sw=2 sts=2 et: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* CSS Variables specific to the devtools toolbar that aren't defined by the themes */ -.theme-light { - --toolbar-tab-hover: rgba(170, 170, 170, .2); - --toolbar-tab-hover-active: rgba(170, 170, 170, .4); - --searchbox-background-color: #ffee99; - --searchbox-border-color: #ffbf00; - --searcbox-no-match-background-color: #ffe5e5; - --searcbox-no-match-border-color: #e52e2e; - /* --magnifying-glass-image: url(images/search.svg); */ - /* --filter-image: url(images/filter.svg); */ - /* --tool-options-image: url(images/tool-options.svg); */ - --icon-filter: none; - /* --checked-icon-filter: url(images/filters.svg#checked-icon-state); */ - --toolbar-button-border-color: rgba(170, 170, 170, .5); -} - -.theme-dark { - --toolbar-tab-hover: hsla(206, 37%, 4%, .2); - --toolbar-tab-hover-active: hsla(206, 37%, 4%, .4); - --searchbox-background-color: #4d4222; - --searchbox-border-color: #d99f2b; - --searcbox-no-match-background-color: #402325; - --searcbox-no-match-border-color: #cc3d3d; - /* --magnifying-glass-image: url(images/search.svg); */ - /* --filter-image: url(images/filter.svg); */ - /* --tool-options-image: url(images/tool-options.svg); */ - --icon-filter: invert(1); - /* --checked-icon-filter: url(images/filters.svg#dark-theme-checked-icon-state); */ - --toolbar-button-border-color: rgba(0, 0, 0, .4); -} - -.theme-firebug { - /* --magnifying-glass-image: url(images/search.svg); */ - /* --tool-options-image: url(images/firebug/tool-options.svg); */ - --icon-filter: none; - --checked-icon-filter: none; - --toolbar-button-border-color: rgba(170, 170, 170, .5); -} - - -/* Toolbars */ -.devtools-toolbar, -.devtools-sidebar-tabs tabs { - -moz-appearance: none; - padding: 0; - border-width: 0; - border-bottom-width: 1px; - border-style: solid; - height: 24px; - line-height: 24px; - box-sizing: border-box; -} - -.devtools-toolbar { - padding: 0 3px; -} - -.devtools-toolbar checkbox { - margin: 0 2px; - padding: 0; - line-height: -moz-block-height; -} -.devtools-toolbar checkbox .checkbox-check { - margin: 0; - padding: 0; - vertical-align: bottom; -} -.devtools-toolbar checkbox .checkbox-label-box { - border: none !important; /* overrides .checkbox-label-box from checkbox.css */ -} -.devtools-toolbar checkbox .checkbox-label-box .checkbox-label { - margin: 0 6px !important; /* overrides .checkbox-label from checkbox.css */ - padding: 0; -} - -.devtools-separator { - margin: 0 2px; - width: 2px; - background-image: linear-gradient(transparent 15%, var(--theme-splitter-color) 15%, var(--theme-splitter-color) 85%, transparent 85%); - background-size: 1px 100%; - background-repeat: no-repeat; - background-position: 0, 1px, 2px; -} - -/* Toolbar buttons */ - -.devtools-menulist, -.devtools-toolbarbutton, -.devtools-button { - -moz-appearance: none; - background: transparent; - min-height: 18px; - text-shadow: none; - border: none; - border-radius: 0; - color: var(--theme-body-color); - transition: background 0.05s ease-in-out; -} - -.devtools-menulist, -.devtools-toolbarbutton { - -moz-box-align: center; - min-width: 78px; - padding: 1px; - margin: 2px 1px; -} - -.devtools-toolbarbutton:not([label]) > .toolbarbutton-icon, -.devtools-button::before { - width: 16px; - height: 16px; - transition: opacity 0.05s ease-in-out; -} - -/* HTML buttons */ -.devtools-button { - margin: 2px 1px; - padding: 1px; - min-width: 32px; - /* The icon is absolutely positioned in the button using ::before */ - position: relative; -} - -.devtools-button::before { - content: ""; - display: block; - position: absolute; - left: 50%; - top: 50%; - margin: -8px 0 0 -8px; - background-size: cover; - background-repeat: no-repeat; - transition: opacity 0.05s ease-in-out; -} - -.devtools-button:-moz-focusring { - outline: none; -} - -/* Standalone buttons */ -.devtools-button[standalone], -.devtools-button[data-standalone], -.devtools-toolbarbutton[standalone], -.devtools-toolbarbutton[data-standalone] { - border-width: 1px; - border-style: solid; - min-height: 32px; - background-color: var(--theme-toolbar-background); -} - -.devtools-toolbarbutton[standalone], .devtools-toolbarbutton[data-standalone] { - margin-inline-end: 5px; -} - -.devtools-toolbarbutton[label][standalone] { - min-height: 2em; -} - -.devtools-menulist, -.devtools-toolbarbutton, -.devtools-button { - border-color: var(--toolbar-button-border-color); -} - -/* Icon button styles */ -.devtools-toolbarbutton:not([label]), -.devtools-toolbarbutton[text-as-image] { - min-width: 32px; -} - -/* Set flex attribute to Toolbox buttons and Picker container so, - they don't overlapp with the tab bar */ -#toolbox-buttons { - display: flex; -} - -#toolbox-picker-container { - display: flex; -} - -.devtools-toolbarbutton:not([label]) > .toolbarbutton-text { - display: none; -} - -.devtools-toolbarbutton > .toolbarbutton-icon { - margin: 0; -} - -/* Menu button styles (eg. web console filters) */ -.devtools-toolbarbutton[type=menu-button] > .toolbarbutton-menubutton-button { - -moz-appearance: none; - color: inherit; - border-width: 0; - -moz-box-orient: horizontal; - padding: 0; -} - -.devtools-toolbarbutton[type=menu-button] { - padding: 0 1px; - -moz-box-align: stretch; -} - -.devtools-toolbarbutton > .toolbarbutton-menubutton-button > .toolbarbutton-icon { - margin-inline-end: 4px; -} - -.devtools-menulist > .menulist-dropmarker { - -moz-appearance: none; - display: -moz-box; - /* list-style-image: url("chrome://devtools/skin/images/dropmarker.svg"); */ - -moz-box-align: center; - min-width: 16px; -} - -.devtools-toolbarbutton[type=menu] > .toolbarbutton-menu-dropmarker, -.devtools-toolbarbutton[type=menu-button] > .toolbarbutton-menubutton-dropmarker { - -moz-appearance: none !important; - /* list-style-image: url("chrome://devtools/skin/images/dropmarker.svg"); */ - -moz-box-align: center; - padding: 0 3px; -} - -/* Icon-only buttons */ -.devtools-button:empty::before, -.devtools-toolbarbutton:not([label]):not([disabled]) > image { - opacity: 0.8; -} - -.devtools-button:hover:empty::before, -.devtools-button[checked]:empty::before, -.devtools-button[open]:empty::before, -.devtools-toolbarbutton:not([label]):hover > image, -.devtools-toolbarbutton:not([label])[checked=true] > image, -.devtools-toolbarbutton:not([label])[open=true] > image { - opacity: 1; -} - -.devtools-button:disabled, -.devtools-button[disabled], -.devtools-toolbarbutton[disabled] { - opacity: 0.5 !important; -} - -.devtools-button[checked]:empty::before, -.devtools-button[open]:empty::before, -.devtools-button.checked::before, -.devtools-toolbarbutton:not([label])[checked=true] > image, -.devtools-toolbarbutton:not([label])[open=true] > image { - filter: var(--checked-icon-filter); -} - -/* Icon-and-text buttons */ -.devtools-toolbarbutton.icon-and-text .toolbarbutton-text { - margin-inline-start: .5em !important; - font-weight: 600; -} - -/* Text-only buttons */ -.theme-light .devtools-toolbarbutton[label]:not([text-as-image]):not([type=menu-button]), -.theme-light .devtools-toolbarbutton[data-text-only] { - background-color: var(--toolbar-tab-hover); -} -.theme-dark .devtools-toolbarbutton[label]:not([text-as-image]):not([type=menu-button]), -.theme-dark .devtools-toolbarbutton[data-text-only] { - background-color: rgba(0, 0, 0, .2); /* Splitter */ -} - -/* Text-only button states */ -.theme-dark .devtools-button:not(:empty):not([disabled]):hover, -.theme-dark .devtools-toolbarbutton:not(:-moz-any([checked=true],[disabled],[text-as-image]))[label]:hover { - background: rgba(0, 0, 0, .3); /* Splitters */ -} -.theme-light .devtools-button:not(:empty):not([disabled]):hover, -.theme-light .devtools-toolbarbutton:not(:-moz-any([checked=true],[disabled],[text-as-image]))[label]:hover { - background: rgba(170, 170, 170, .3); /* Splitters */ -} - -.theme-dark .devtools-button:not(:empty):not([disabled]):hover:active, -.theme-dark .devtools-toolbarbutton:not(:-moz-any([checked=true],[disabled],[text-as-image]))[label]:hover:active { - background: rgba(0, 0, 0, .4); /* Splitters */ -} -.theme-light .devtools-button:not(:empty):not([disabled]):hover:active, -.theme-light .devtools-toolbarbutton:not(:-moz-any([checked=true],[disabled],[text-as-image]))[label]:hover:active { - background: var(--toolbar-tab-hover-active); -} - -.theme-dark .devtools-toolbarbutton:not([disabled])[label][checked=true], -.theme-dark .devtools-toolbarbutton:not([disabled])[label][open], -.theme-dark .devtools-button:not(:empty)[checked=true] { - background: var(--theme-selection-background-semitransparent); - color: var(--theme-selection-color); -} -.theme-light .devtools-toolbarbutton:not([disabled])[label][checked=true], -.theme-light .devtools-toolbarbutton:not([disabled])[label][open], -.theme-light .devtools-button:not(:empty)[checked=true] { - background: rgba(76, 158, 217, .3); /* Select highlight blue */ -} - -:root { - /* --clear-icon-url: url("chrome://devtools/skin/images/clear.svg"); */ -} - -.devtools-button.devtools-clear-icon::before { - background-image: var(--clear-icon-url); -} - -.devtools-button.devtools-filter-icon::before { - background-image: var(--filter-image); -} - -.devtools-toolbarbutton.devtools-clear-icon { - list-style-image: var(--clear-icon-url); -} - -.devtools-option-toolbarbutton { - list-style-image: var(--tool-options-image); -} - -.devtools-toolbarbutton-group > .devtools-toolbarbutton:last-child { - margin-inline-end: 0; -} - -.devtools-toolbarbutton-group + .devtools-toolbarbutton { - margin-inline-start: 3px; -} - -.devtools-separator + .devtools-toolbarbutton { - margin-inline-start: 1px; -} - -/* Text input */ - -.devtools-textinput, -.devtools-searchinput, -.devtools-filterinput { - -moz-appearance: none; - margin: 1px 3px; - border: 1px solid; - border-radius: 2px; - padding: 4px 6px; - border-color: var(--theme-splitter-color); - font: message-box; -} - -:root[platform="mac"] .devtools-textinput, -:root[platform="mac"] .devtools-searchinput, -:root[platform="mac"] .devtools-filterinput { - border-radius: 20px; -} - -.devtools-searchinput, -.devtools-filterinput { - padding: 0; - padding-inline-start: 22px; - padding-inline-end: 4px; - background-position: 8px center; - background-size: 11px 11px; - background-repeat: no-repeat; - font-size: inherit; -} - -.devtools-searchinput { - background-image: var(--magnifying-glass-image); -} - -.devtools-filterinput { - /* background-image: url(images/filter.svg#filterinput); */ -} - -.devtools-searchinput:-moz-locale-dir(rtl), -.devtools-searchinput:dir(rtl), -.devtools-filterinput:-moz-locale-dir(rtl), -.devtools-filterinput:dir(rtl) { - background-position: calc(100% - 8px) center; -} - -.devtools-searchinput > .textbox-input-box > .textbox-search-icons > .textbox-search-icon, -.devtools-filterinput > .textbox-input-box > .textbox-search-icons > .textbox-search-icon { - visibility: hidden; -} - -.devtools-searchinput .textbox-input::-moz-placeholder, -.devtools-filterinput .textbox-input::-moz-placeholder { - font-style: normal; -} - -.devtools-plaininput { - border-color: transparent; - background-color: transparent; -} - -.theme-dark .devtools-plaininput { - color: var(--theme-highlight-gray); -} - -/* Searchbox is a div container element for a search input element */ -.devtools-searchbox { - display: flex; - flex: 1; - height: 23px; - position: relative; - padding: 0 3px; -} - -/* The spacing is accomplished with a padding on the searchbox */ -.devtools-searchbox > .devtools-textinput, -.devtools-searchbox > .devtools-searchinput, -.devtools-searchbox > .devtools-filterinput { - margin-left: 0; - margin-right: 0; -} - -.devtools-searchbox > .devtools-textinput:-moz-focusring, -.devtools-searchbox > .devtools-searchinput:-moz-focusring, -.devtools-searchbox > .devtools-filterinput:-moz-focusring { - border-color: var(--theme-focus-border-color-textbox); - box-shadow: var(--theme-focus-box-shadow-textbox); - transition: all 0.2s ease-in-out; - outline: none; -} - -/* Don't add 'double spacing' for inputs that are at beginning / end - of a toolbar (since the toolbar has it's own spacing). */ -.devtools-toolbar > .devtools-textinput:first-child, -.devtools-toolbar > .devtools-searchinput:first-child, -.devtools-toolbar > .devtools-filterinput:first-child { - margin-inline-start: 0; -} -.devtools-toolbar > .devtools-textinput:last-child, -.devtools-toolbar > .devtools-searchinput:last-child, -.devtools-toolbar > .devtools-filterinput:last-child { - margin-inline-end: 0; -} -.devtools-toolbar > .devtools-searchbox:first-child { - padding-inline-start: 0; -} -.devtools-toolbar > .devtools-searchbox:last-child { - padding-inline-end: 0; -} - -.devtools-rule-searchbox { - -moz-box-flex: 1; - width: 100%; -} - -.devtools-rule-searchbox[filled] { - background-color: var(--searchbox-background-color); - border-color: var(--searchbox-border-color); - padding-inline-end: 23px; -} - -.devtools-style-searchbox-no-match { - background-color: var(--searcbox-no-match-background-color) !important; - border-color: var(--searcbox-no-match-border-color) !important; -} - -.devtools-searchinput-clear { - position: absolute; - top: 3.5px; - right: 7px; - padding: 0; - border: 0; - width: 16px; - height: 16px; - background-position: 0 0; - background-repeat: no-repeat; - background-color: transparent; -} - -.devtools-searchinput-clear:dir(rtl) { - right: unset; - left: 7px; -} - -.theme-dark .devtools-searchinput-clear { - /* background-image: url("chrome://devtools/skin/images/search-clear-dark.svg"); */ -} - -.theme-light .devtools-searchinput-clear { - /* background-image: url("chrome://devtools/skin/images/search-clear-light.svg"); */ -} - -.devtools-style-searchbox-no-match + .devtools-searchinput-clear { - /* background-image: url("chrome://devtools/skin/images/search-clear-failed.svg") !important; */ -} - -.devtools-searchinput-clear:hover { - background-position: -16px 0; -} - -.theme-dark .devtools-searchinput > .textbox-input-box > .textbox-search-icons > .textbox-search-clear, -.theme-dark .devtools-filterinput > .textbox-input-box > .textbox-search-icons > .textbox-search-clear { - /* list-style-image: url("chrome://devtools/skin/images/search-clear-dark.svg"); */ - -moz-image-region: rect(0, 16px, 16px, 0); -} - -.theme-light .devtools-searchinput > .textbox-input-box > .textbox-search-icons > .textbox-search-clear, -.theme-light .devtools-filterinput > .textbox-input-box > .textbox-search-icons > .textbox-search-clear { - /* list-style-image: url("chrome://devtools/skin/images/search-clear-light.svg"); */ - -moz-image-region: rect(0, 16px, 16px, 0); -} - -.devtools-searchinput > .textbox-input-box > .textbox-search-icons > .textbox-search-clear, -.devtools-filterinput > .textbox-input-box > .textbox-search-icons > .textbox-search-clear { - margin-bottom: 0; -} - -.devtools-searchinput > .textbox-input-box > .textbox-search-icons > .textbox-search-clear:hover, -.devtools-filterinput > .textbox-input-box > .textbox-search-icons > .textbox-search-clear:hover { - -moz-image-region: rect(0, 32px, 16px, 16px); -} - -/* In-tools sidebar */ -.devtools-sidebar-tabs { - -moz-appearance: none; - margin: 0; - height: 100%; -} - -.devtools-sidebar-tabs > tabpanels { - -moz-appearance: none; - background: transparent; - padding: 0; - border: 0; -} - -.theme-light .devtools-sidebar-tabs > tabpanels { - background: var(--theme-sidebar-background); - color: var(--theme-body-color); -} - -.devtools-sidebar-tabs tabs { - position: static; - font: inherit; - margin-bottom: 0; - overflow: hidden; -} - -.devtools-sidebar-alltabs { - -moz-appearance: none; - height: 24px; - line-height: 24px; - padding: 0 4px; - margin: 0; - border-width: 0 0 1px 0; - border-inline-start-width: 1px; - border-style: solid; -} - -.devtools-sidebar-alltabs .toolbarbutton-icon { - display: none; -} - -.devtools-sidebar-tabs tabs > .tabs-right, -.devtools-sidebar-tabs tabs > .tabs-left { - display: none; -} - -.devtools-sidebar-tabs tabs > tab { - -moz-appearance: none; - /* We want to match the height of a toolbar with a toolbarbutton - * First, we need to replicated the padding of toolbar (4px), - * then we need to take the border of the buttons into account (1px). - */ - padding: 0 3px; - margin: 0; - min-width: 78px; - text-align: center; - background-color: transparent; - color: inherit; - -moz-box-flex: 1; - border-width: 0; - border-inline-start-width: 1px; - border-style: solid; - border-radius: 0; - position: static; - text-shadow: none; -} - -.devtools-sidebar-tabs tabs > tab { - border-image: linear-gradient(transparent 15%, var(--theme-splitter-color) 15%, var(--theme-splitter-color) 85%, transparent 85%) 1 1; -} - -.devtools-sidebar-tabs tabs > tab[selected], -.devtools-sidebar-tabs tabs > tab[selected] + tab { - border-image: linear-gradient(var(--theme-splitter-color), var(--theme-splitter-color)) 1 1; -} - -.devtools-sidebar-tabs tabs > tab:first-child { - border-inline-start-width: 0; -} - -.devtools-sidebar-tabs tabs > tab:hover { - background: rgba(0, 0, 0, 0.12); -} - -.devtools-sidebar-tabs tabs > tab:hover:active { - background: rgba(0, 0, 0, 0.2); -} - -.devtools-sidebar-tabs tabs > tab[selected], -.devtools-sidebar-tabs tabs > tab[selected]:hover:active { - color: var(--theme-selection-color); - background: var(--theme-selection-background); -} - -/* Invert the colors of certain light theme images for displaying - * inside of the dark theme. - */ -.devtools-tab[icon-invertable] > image, -.devtools-toolbarbutton > image, -.devtools-button::before, -#breadcrumb-separator-normal, -.scrollbutton-up > .toolbarbutton-icon, -.scrollbutton-down > .toolbarbutton-icon, -#black-boxed-message-button .button-icon, -#requests-menu-perf-notice-button .button-icon, -#canvas-debugging-empty-notice-button .button-icon, -#toggle-breakpoints[checked] > image, -.event-tooltip-debugger-icon { - filter: var(--icon-filter); -} - -.hidden-labels-box:not(.visible) > label, -.hidden-labels-box.visible ~ .hidden-labels-box > label:last-child { - display: none; -} - -.devtools-invisible-splitter { - border-color: transparent; - background-color: transparent; -} - -.devtools-horizontal-splitter, -.devtools-side-splitter { - background-color: var(--theme-splitter-color); -} - -/* Throbbers */ -.devtools-throbber::before { - content: ""; - display: inline-block; - vertical-align: bottom; - margin-inline-end: 0.5em; - width: 1em; - height: 1em; - border: 2px solid currentColor; - border-right-color: transparent; - border-radius: 50%; - animation: 1.1s linear throbber-spin infinite; -} - -@keyframes throbber-spin { - from { - transform: none; - } - to { - transform: rotate(360deg); - } -} - -/* - * Filter buttons - * @TODO : Fix when https://bugzilla.mozilla.org/show_bug.cgi?id=1255116 lands - */ -.menu-filter-button { - -moz-appearance: none; - background: rgba(128,128,128,0.1); - border: none; - border-radius: 2px; - min-width: 0; - padding: 0 5px; - margin: 2px; - color: var(--theme-body-color); -} - -.menu-filter-button:hover { - background: rgba(128,128,128,0.2); -} - -.menu-filter-button:hover:active { - background-color: var(--theme-selection-background-semitransparent); -} - -.menu-filter-button:not(:active).checked { - background-color: var(--theme-selection-background); - color: var(--theme-selection-color); -} diff --git a/packages/devtools-local-toolbox/src/lib/themes/tooltips.css b/packages/devtools-local-toolbox/src/lib/themes/tooltips.css deleted file mode 100644 index 44f3cb5484..0000000000 --- a/packages/devtools-local-toolbox/src/lib/themes/tooltips.css +++ /dev/null @@ -1,460 +0,0 @@ -/* vim:set ts=2 sw=2 sts=2 et: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* Tooltip specific theme variables */ - -.theme-dark { - --bezier-diagonal-color: #eee; - --bezier-grid-color: rgba(0, 0, 0, 0.2); -} - -.theme-light { - --bezier-diagonal-color: rgba(0, 0, 0, 0.2); - --bezier-grid-color: rgba(0, 0, 0, 0.05); -} - -/* Tooltip widget (see devtools/client/shared/widgets/Tooltip.js) */ - -.devtools-tooltip .panel-arrowcontent { - padding: 4px; -} - -.devtools-tooltip .panel-arrowcontainer { - /* Reseting the transition used when panels are shown */ - transition: none; - /* Panels slide up/down/left/right when they appear using a transform. - Since we want to remove the transition, we don't need to transform anymore - plus it can interfeer by causing mouseleave events on the underlying nodes */ - transform: none; -} - -.devtools-tooltip[clamped-dimensions] { - min-height: 100px; - max-height: 400px; - min-width: 100px; - max-width: 400px; -} -.devtools-tooltip[clamped-dimensions-no-min-height] { - min-height: 0; - max-height: 400px; - min-width: 100px; - max-width: 400px; -} -.devtools-tooltip[clamped-dimensions-no-max-or-min-height] { - min-width: 400px; - max-width: 400px; -} -.devtools-tooltip[clamped-dimensions] .panel-arrowcontent, -.devtools-tooltip[clamped-dimensions-no-min-height] .panel-arrowcontent, -.devtools-tooltip[clamped-dimensions-no-max-or-min-height] .panel-arrowcontent { - overflow: hidden; -} -.devtools-tooltip[wide] { - max-width: 600px; -} - -/* Tooltip: Simple Text */ - -.devtools-tooltip-simple-text { - max-width: 400px; - margin: 0 -4px; /* Compensate for the .panel-arrowcontent padding. */ - padding: 8px 12px; - white-space: pre-wrap; -} - -.devtools-tooltip-simple-text:first-child { - margin-top: -4px; -} - -.devtools-tooltip-simple-text:last-child { - margin-bottom: -4px; -} - -/* Tooltip: Alert Icon */ - -.devtools-tooltip-alert-icon { - width: 32px; - height: 32px; - margin: 6px; - margin-inline-end: 20px; -} - -.devtools-tooltip-alert-icon { - /* list-style-image: url("chrome://global/skin/icons/warning-32.png"); */ -} - -/* Tooltip: Variables View */ - -.devtools-tooltip-variables-view-box { - margin: -4px; /* Compensate for the .panel-arrowcontent padding. */ -} - -.devtools-tooltip-variables-view-box .variable-or-property > .title { - padding-inline-end: 6px; -} - -/* Tooltip: Tiles */ - -.devtools-tooltip-tiles { - background-color: #eee; - background-image: linear-gradient(45deg, #ccc 25%, transparent 25%, transparent 75%, #ccc 75%, #ccc), - linear-gradient(45deg, #ccc 25%, transparent 25%, transparent 75%, #ccc 75%, #ccc); - background-size: 20px 20px; - background-position: 0 0, 10px 10px; -} - -.devtools-tooltip-iframe { - border: none; - background: transparent; -} - -.tooltip-container { - display: none; - position: fixed; - z-index: 9999; - display: none; - background: transparent; - pointer-events: none; - overflow: hidden; - filter: drop-shadow(0 3px 4px var(--theme-tooltip-shadow)); -} - -.tooltip-xul-wrapper { - -moz-appearance: none; - background: transparent; - overflow: visible; - border-style: none; -} - -.tooltip-xul-wrapper .tooltip-container { - position: absolute; -} - -.tooltip-top { - flex-direction: column; -} - -.tooltip-bottom { - flex-direction: column-reverse; -} - -.tooltip-panel{ - background-color: var(--theme-tooltip-background); - pointer-events: all; - flex-grow: 1; -} - -.tooltip-visible { - display: flex; -} - -.tooltip-hidden { - display: flex; - visibility: hidden; -} - -/* Tooltip : flexible height styles */ - -.tooltip-flexible-height .tooltip-panel { - /* In flexible mode the tooltip panel should only grow according to its content. */ - flex-grow: 0; -} - -.tooltip-flexible-height .tooltip-filler { - /* In flexible mode the filler should grow as much as possible. */ - flex-grow: 1; -} - -/* type="arrow" overrides: remove arrow decorations for the xul wrapper */ - -.tooltip-xul-wrapper[type="arrow"] { - margin: 0; -} - -/* The arrow image is hidden because the panel is opened using openPopupAtScreen(). */ - -/* Remove all decorations on .panel-arrowcontent is the tooltip content container. */ -.tooltip-xul-wrapper[type="arrow"] .panel-arrowcontent { - margin: 0; - padding: 0; - background: transparent; - border: none; - box-shadow: none; -} - -/* Tooltip : arrow style */ - -.tooltip-xul-wrapper .tooltip-container { - /* When displayed in a XUL panel the drop shadow would be abruptly cut by the panel */ - filter: none; -} - -.tooltip-container[type="arrow"] > .tooltip-panel { - position: relative; - min-height: 10px; - box-sizing: border-box; - width: 100%; - - border: 3px solid var(--theme-tooltip-border); - border-radius: 5px; -} - -.tooltip-top[type="arrow"] .tooltip-panel { - top: 0; -} - -.tooltip-bottom[type="arrow"] .tooltip-panel { - bottom: 0; -} - -.tooltip-arrow { - position: relative; - height: 16px; - width: 32px; - overflow: hidden; - flex-shrink: 0; -} - -/* In RTL locales, only use RTL on the tooltip content, keep LTR for positioning */ -.tooltip-container:-moz-locale-dir(rtl) { - direction: ltr; -} - -.tooltip-panel:-moz-locale-dir(rtl) { - direction: rtl; -} - -.tooltip-top .tooltip-arrow { - margin-top: -3px; -} - -.tooltip-bottom .tooltip-arrow { - margin-bottom: -3px; -} - -.tooltip-arrow:before { - content: ""; - position: absolute; - width: 21px; - height: 21px; - margin-left: 4px; - background: linear-gradient(-45deg, - var(--theme-tooltip-background) 50%, transparent 50%); - border-color: var(--theme-tooltip-border); - border-style: solid; - border-width: 0px 3px 3px 0px; - border-radius: 3px; - pointer-events: all; -} - -.tooltip-bottom .tooltip-arrow:before { - margin-top: 4px; - transform: rotate(225deg); -} - -.tooltip-top .tooltip-arrow:before { - margin-top: -12px; - transform: rotate(45deg); -} - -/* Tooltip: Events */ - -.event-header { - display: flex; - align-items: center; - cursor: pointer; - overflow: hidden; -} - -.event-header:first-child { - border-width: 0; -} - -.event-header:not(:first-child) { - border-width: 1px 0 0 0; -} - -.devtools-tooltip-events-container { - height: 100%; - overflow-y: auto; -} - -.event-tooltip-event-type, -.event-tooltip-filename, -.event-tooltip-attributes { - margin-inline-start: 0; - flex-shrink: 0; - cursor: pointer; -} - -.event-tooltip-event-type { - font-weight: bold; - font-size: 13px; -} - -.event-tooltip-filename { - margin: 0 5px; - font-size: 100%; - flex-shrink: 1; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - /* Force ellipsis to be displayed on the left */ - direction: rtl; -} - -.event-tooltip-debugger-icon { - width: 16px; - height: 16px; - margin-inline-end: 4px; - opacity: 0.6; - flex-shrink: 0; -} - -.event-tooltip-debugger-icon:hover { - opacity: 1; -} - -.event-tooltip-content-box { - display: none; - height: 100px; - overflow: hidden; - margin-inline-end: 0; - border: 1px solid var(--theme-splitter-color); - border-width: 1px 0 0 0; -} - -.event-toolbox-content-box iframe { - height: 100%; - border-style: none; -} - -.event-tooltip-content-box[open] { - display: block; -} - -.event-tooltip-source-container { - margin-top: 5px; - margin-bottom: 10px; - margin-inline-start: 5px; - margin-inline-end: 0; -} - -.event-tooltip-source { - margin-bottom: 0; -} - -.event-tooltip-attributes-container { - display: flex; - flex-shrink: 0; - flex-grow: 1; - justify-content: flex-end; -} - -.event-tooltip-attributes-box { - display: flex; - flex-shrink: 0; - align-items: center; - height: 14px; - border-radius: 3px; - padding: 2px; - margin-inline-start: 5px; - background-color: var(--theme-body-color-alt); - color: var(--theme-toolbar-background); -} - -.event-tooltip-attributes { - margin: 0; - font-size: 9px; - padding-top: 2px; -} - -/* - * Tooltip: JS stack traces - */ - -.stack-trace-tooltip { - direction: ltr; - height: 100%; - overflow-y: auto; -} - -.stack-trace-tooltip > .stack-frame { - margin-left: 5px; - margin-right: 5px; -} - -.stack-trace-tooltip > .stack-frame:first-child { - margin-top: 5px; -} - -.stack-trace-tooltip > .stack-frame:last-child { - margin-bottom: 5px; -} - -.stack-frame-call { - color: var(--theme-body-color-alt); - cursor: pointer; - display: flex; -} - -.stack-frame-call:hover { - background-color: var(--theme-selection-background-semitransparent); -} - -.stack-frame-async { - color: var(--theme-body-color-inactive); -} - -.stack-frame-function-name { - color: var(--theme-highlight-blue); - max-width: 50%; - margin-inline-end: 1em; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} - -.stack-frame-source-name { - flex: 1 1; - /* Makes the file name truncated (and ellipsis shown) on the left side */ - direction: rtl; - text-align: right; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} - -/* Enforce LTR direction for the file name - fixes bug 1290056 */ -.stack-frame-source-name-inner { - direction: ltr; - unicode-bidi: embed; -} - -.stack-frame-line { - color: var(--theme-highlight-orange); -} - -/* Tooltip: HTML Search */ - -#searchbox-panel-listbox { - width: 250px; - max-width: 250px; - overflow-x: hidden; -} - -#searchbox-panel-listbox .autocomplete-item, -#searchbox-panel-listbox .autocomplete-item[selected] { - overflow-x: hidden; -} - -#searchbox-panel-listbox .autocomplete-item > .initial-value { - max-width: 130px; - margin-left: 15px; -} - -#searchbox-panel-listbox .autocomplete-item > .autocomplete-value { - max-width: 150px; -} diff --git a/packages/devtools-local-toolbox/src/lib/themes/variables.css b/packages/devtools-local-toolbox/src/lib/themes/variables.css deleted file mode 100644 index ae89b8803f..0000000000 --- a/packages/devtools-local-toolbox/src/lib/themes/variables.css +++ /dev/null @@ -1,211 +0,0 @@ -/* vim:set ts=2 sw=2 sts=2 et: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* Variable declarations for light and dark devtools themes. - * Colors are taken from: - * https://developer.mozilla.org/en-US/docs/Tools/DevToolsColors. - * Changes should be kept in sync with commandline.css and commandline.inc.css. - */ - -/* IMPORTANT NOTE: - * This file is parsed in js (see client/shared/theme.js) - * so the formatting should be consistent (i.e. no '}' inside a rule). - */ - -:root .theme-light { - --theme-body-background: white; - --theme-sidebar-background: white; - --theme-contrast-background: #e6b064; - - --theme-tab-toolbar-background: #fcfcfc; - --theme-toolbar-background: #fcfcfc; - --theme-toolbar-background-alt: #f5f5f5; - --theme-selection-background: #4c9ed9; - --theme-selection-background-semitransparent: rgba(76, 158, 217, 0.15); - --theme-selection-color: #f5f7fa; - --theme-splitter-color: #dde1e4; - --theme-comment: #696969; - --theme-comment-alt: #ccd1d5; - - --theme-body-color: #393f4c; - --theme-body-color-alt: #585959; - --theme-body-color-inactive: #999797; - --theme-content-color1: #292e33; - --theme-content-color2: #8fa1b2; - --theme-content-color3: #667380; - - --theme-highlight-green: #2cbb0f; - --theme-highlight-blue: #0088cc; - --theme-highlight-bluegrey: #0072ab; - --theme-highlight-purple: #5b5fff; - --theme-highlight-lightorange: #d97e00; - --theme-highlight-orange: #f13c00; - --theme-highlight-red: #ed2655; - --theme-highlight-pink: #b82ee5; - --theme-highlight-gray: #dde1e4; - - /* For accessibility purposes we want to enhance the focus styling. This - * should improve keyboard navigation usability. */ - --theme-focus-outline-color: #000000; - - /* Colors used in Graphs, like performance tools. Similar colors to Chrome's timeline. */ - --theme-graphs-green: #85d175; - --theme-graphs-blue: #83b7f6; - --theme-graphs-bluegrey: #0072ab; - --theme-graphs-purple: #b693eb; - --theme-graphs-yellow: #efc052; - --theme-graphs-orange: #d97e00; - --theme-graphs-red: #e57180; - --theme-graphs-grey: #cccccc; - --theme-graphs-full-red: #f00; - --theme-graphs-full-blue: #00f; - - /* Images */ - /* --theme-pane-collapse-image: url(chrome://devtools/skin/images/pane-collapse.svg); */ - /* --theme-pane-expand-image: url(chrome://devtools/skin/images/pane-expand.svg); */ - - /* Tooltips */ - --theme-tooltip-border: #d9e1e8; - --theme-tooltip-background: rgba(255, 255, 255, .9); - --theme-tooltip-shadow: rgba(155, 155, 155, 0.26); - - /* Command line */ - /* --theme-command-line-image: url(chrome://devtools/skin/images/commandline-icon.svg#light-theme); */ - /* --theme-command-line-image-focus: url(chrome://devtools/skin/images/commandline-icon.svg#light-theme-focus); */ -} - -:root.theme-dark { - --theme-body-background: #393f4c; - --theme-sidebar-background: #393f4c; - --theme-contrast-background: #ffb35b; - - --theme-tab-toolbar-background: #272b35; - --theme-toolbar-background: #272b35; - --theme-toolbar-background-alt: #2F343E; - --theme-selection-background: #5675B9; - --theme-selection-background-semitransparent: rgba(86, 117, 185, 0.5); - --theme-search-overlays-semitransparent: rgba(42, 46, 56, 0.66); - --theme-selection-color: #f5f7fa; - --theme-splitter-color: #454d5d; - --theme-comment: #757873; - --theme-comment-alt: #5a6375; - - --theme-body-color: #8fa1b2; - --theme-body-color-alt: #b6babf; - --theme-body-color-inactive: #8fa1b2; - --theme-content-color1: #a9bacb; - --theme-content-color2: #8fa1b2; - --theme-content-color3: #5f7387; - - --theme-highlight-green: #00ff7f; - --theme-highlight-blue: #46afe3; - --theme-highlight-bluegrey: #5e88b0; - --theme-highlight-purple: #bcb8db; - --theme-highlight-lightorange: #d99b28; - --theme-highlight-orange: #d96629; - --theme-highlight-red: #eb5368; - --theme-highlight-pink: #df80ff; - --theme-highlight-gray: #e9f4fe; - - /* For accessibility purposes we want to enhance the focus styling. This - * should improve keyboard navigation usability. */ - --theme-focus-outline-color: #ced3d9; - - /* Colors used in Graphs, like performance tools. Mostly similar to some "highlight-*" colors. */ - --theme-graphs-green: #70bf53; - --theme-graphs-blue: #46afe3; - --theme-graphs-bluegrey: #5e88b0; - --theme-graphs-purple: #df80ff; - --theme-graphs-yellow: #d99b28; - --theme-graphs-orange: #d96629; - --theme-graphs-red: #eb5368; - --theme-graphs-grey: #757873; - --theme-graphs-full-red: #f00; - --theme-graphs-full-blue: #00f; - - /* Images */ - /* --theme-pane-collapse-image: url(chrome://devtools/skin/images/pane-collapse.svg); */ - /* --theme-pane-expand-image: url(chrome://devtools/skin/images/pane-expand.svg); */ - - /* Tooltips */ - --theme-tooltip-border: #434850; - --theme-tooltip-background: rgba(19, 28, 38, .9); - --theme-tooltip-shadow: rgba(25, 25, 25, 0.76); - - /* Command line */ - /* --theme-command-line-image: url(chrome://devtools/skin/images/commandline-icon.svg#dark-theme); */ - /* --theme-command-line-image-focus: url(chrome://devtools/skin/images/commandline-icon.svg#dark-theme-focus); */ - -} - -:root.theme-firebug { - --theme-body-background: #fcfcfc; - --theme-sidebar-background: #fcfcfc; - --theme-contrast-background: #e6b064; - - --theme-tab-toolbar-background: #ebeced; - --theme-toolbar-background: #f0f1f2; - --theme-selection-background: #3399ff; - --theme-selection-background-semitransparent: rgba(128,128,128,0.2); - --theme-search-overlays-semitransparent: rgba(221, 225, 228, 0.66); - --theme-selection-color: white; - --theme-splitter-color: #aabccf; - --theme-comment: green; - --theme-comment-alt: #ccd1d5; - - --theme-body-color: #18191a; - --theme-body-color-alt: #585959; - --theme-content-color1: #292e33; - --theme-content-color2: #8fa1b2; - --theme-content-color3: #667380; - - --theme-highlight-green: #2cbb0f; - --theme-highlight-blue: #3455db; - --theme-highlight-bluegrey: #0072ab; - --theme-highlight-purple: #887ce6; - --theme-highlight-lightorange: #d97e00; - --theme-highlight-orange: #f13c00; - --theme-highlight-red: #e22f6f; - --theme-highlight-pink: #b82ee5; - --theme-highlight-gray: #dde1e4; - - /* Colors used in Graphs, like performance tools. Similar colors to Chrome's timeline. */ - --theme-graphs-green: #85d175; - --theme-graphs-blue: #83b7f6; - --theme-graphs-bluegrey: #0072ab; - --theme-graphs-purple: #b693eb; - --theme-graphs-yellow: #efc052; - --theme-graphs-orange: #d97e00; - --theme-graphs-red: #e57180; - --theme-graphs-grey: #cccccc; - --theme-graphs-full-red: #f00; - --theme-graphs-full-blue: #00f; - - /* Images */ - /* --theme-pane-collapse-image: url(chrome://devtools/skin/images/firebug/pane-collapse.svg); */ - /* --theme-pane-expand-image: url(chrome://devtools/skin/images/firebug/pane-expand.svg); */ - - /* Font size */ - --theme-toolbar-font-size: 12px; - - /* Header */ - --theme-header-background: #F0F0F0 linear-gradient(to top, - rgba(0, 0, 0, 0.1), - transparent) repeat-x; - - /* Command line */ - /* --theme-command-line-image: url(chrome://devtools/skin/images/firebug/commandline-icon.svg); */ - /* --theme-command-line-image-focus: url(chrome://devtools/skin/images/firebug/commandline-icon.svg#focus); */ -} - -:root { - --theme-focus-border-color-textbox: #0675d3; - --theme-textbox-box-shadow: rgba(97,181,255,.75); - - /* For accessibility purposes we want to enhance the focus styling. This - * should improve keyboard navigation usability. */ - --theme-focus-outline: 1px dotted var(--theme-focus-outline-color); - --theme-focus-box-shadow-textbox: 0 0 0 1px var(--theme-textbox-box-shadow); -} diff --git a/packages/devtools-local-toolbox/src/reducers/index.js b/packages/devtools-local-toolbox/src/reducers/index.js deleted file mode 100644 index 2c705bf923..0000000000 --- a/packages/devtools-local-toolbox/src/reducers/index.js +++ /dev/null @@ -1,5 +0,0 @@ -const tabs = require("./tabs"); - -module.exports = { - tabs -}; diff --git a/packages/devtools-local-toolbox/src/reducers/tabs.js b/packages/devtools-local-toolbox/src/reducers/tabs.js deleted file mode 100644 index 95e552c404..0000000000 --- a/packages/devtools-local-toolbox/src/reducers/tabs.js +++ /dev/null @@ -1,50 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -const constants = require("../constants"); -const Immutable = require("immutable"); -const fromJS = require("../utils/fromJS"); - -const initialState = fromJS({ - tabs: {}, - selectedTab: null, -}); - -function update(state = initialState, action) { - switch (action.type) { - case constants.ADD_TABS: - const tabs = action.value; - if (!tabs) { - return state; - } - - return state.mergeIn( - ["tabs"], - Immutable.Map(tabs.map(tab => { - tab = Object.assign({}, tab, { id: getTabId(tab) }); - return [tab.id, Immutable.Map(tab)]; - })) - ); - case constants.SELECT_TAB: - const tab = state.getIn(["tabs", action.id]); - return state.setIn(["selectedTab"], tab); - } - - return state; -} - -function getTabId(tab) { - let id = tab.id; - const isFirefox = tab.clientType == "firefox"; - - // NOTE: we're getting the last part of the actor because - // we want to ignore the connection id - if (isFirefox) { - id = tab.id.split(".").pop(); - } - - return id; -} - -module.exports = update; diff --git a/packages/devtools-local-toolbox/src/selectors.js b/packages/devtools-local-toolbox/src/selectors.js deleted file mode 100644 index 6636516305..0000000000 --- a/packages/devtools-local-toolbox/src/selectors.js +++ /dev/null @@ -1,12 +0,0 @@ -function getTabs(state) { - return state.tabs.get("tabs"); -} - -function getSelectedTab(state) { - return state.tabs.get("selectedTab"); -} - -module.exports = { - getTabs, - getSelectedTab -}; diff --git a/packages/devtools-local-toolbox/src/test/utils/debuggee.js b/packages/devtools-local-toolbox/src/test/utils/debuggee.js deleted file mode 100644 index 772fb0e42c..0000000000 --- a/packages/devtools-local-toolbox/src/test/utils/debuggee.js +++ /dev/null @@ -1,120 +0,0 @@ -function Debuggee() { - function $(selector) { - const element = document.querySelector(selector); - console.log("$", selector, element); - - if (!element) { - throw new Error("Element not found, try changing the selector"); - } - return element; - } - - function mouseEvent(eventType) { - return new MouseEvent(eventType, { - "view": window, - "bubbles": true, - "cancelable": true - }); - } - - const specialKeysMap = { - "{enter}": 13 - }; - - // Special character examples {enter}, {esc}, {leftarrow} .. - function isSpecialCharacter(text) { - return text.match(/^\{.*\}$/); - } - - function keyInfo(key, eventType) { - let charCodeAt; - - if (key.length > 1) { - charCodeAt = specialKeysMap[key]; - } else { - charCodeAt = key.toUpperCase().charCodeAt(0); - } - - return { - charCode: eventType == "keypress" ? 0 : charCodeAt, - keyCode: charCodeAt, - which: charCodeAt - }; - } - - function keyEvent(eventType, key) { - const event = new Event(eventType, { - bubbles: true, - cancelable: false, - view: window - }); - - const { charCode, keyCode, which } = keyInfo(key, eventType); - - return Object.assign(event, { - charCode: charCode, - keyCode: keyCode, - which: which, - detail: 0, - layerX: 0, - layerY: 0, - pageX: 0, - pageY: 0 - }); - } - - function sendKey(element, key) { - element.dispatchEvent(keyEvent("keydown", key)); - element.dispatchEvent(keyEvent("keypress", key)); - if (key.length == 1) { - element.value += key; - } - element.dispatchEvent(keyEvent("keyup", key)); - } - - function click(selector) { - const element = $(selector); - console.log("click", selector); - element.dispatchEvent(mouseEvent("click")); - } - - function dblclick(selector) { - const element = $(selector); - console.log("dblclick", selector); - element.dispatchEvent(mouseEvent("dblclick")); - } - - function type(selector, text) { - const element = $(selector); - console.log("type", selector, text); - element.select(); - - if (isSpecialCharacter(text)) { - sendKey(element, text); - } else { - const chars = text.split(""); - chars.forEach(char => sendKey(element, char)); - } - } - - return { - click, - dblclick, - type - }; -} - -const debuggeeStatement = `window.dbg = (${Debuggee})()`; -let injectedDebuggee; - -function injectDebuggee() { - if (injectedDebuggee) { - return Promise.resolve(injectedDebuggee); - } - - return window.client.debuggeeCommand(debuggeeStatement).then(result => { - injectedDebuggee = result; - }); -} - -module.exports = injectDebuggee; diff --git a/packages/devtools-local-toolbox/src/utils/DevToolsUtils.js b/packages/devtools-local-toolbox/src/utils/DevToolsUtils.js deleted file mode 100644 index d162b6f1c3..0000000000 --- a/packages/devtools-local-toolbox/src/utils/DevToolsUtils.js +++ /dev/null @@ -1,16 +0,0 @@ -const assert = require("./assert"); - -function reportException(who, exception) { - let msg = `${who} threw an exception: `; - console.error(msg, exception); -} - -function executeSoon(fn) { - setTimeout(fn, 0); -} - -module.exports = { - reportException, - executeSoon, - assert -}; diff --git a/packages/devtools-local-toolbox/src/utils/L10N.js b/packages/devtools-local-toolbox/src/utils/L10N.js deleted file mode 100644 index 79339a6ccb..0000000000 --- a/packages/devtools-local-toolbox/src/utils/L10N.js +++ /dev/null @@ -1,25 +0,0 @@ -// @flow - -const { sprintf } = require("devtools-modules"); -let strings = {}; - -function setBundle(bundle: { [key: string]: string }) { - strings = bundle; -} - -function getStr(key: string) { - if (!strings[key]) { - throw new Error(`L10N key ${key} cannot be found.`); - } - return strings[key]; -} - -function getFormatStr(name: string, ...args: any) { - return sprintf(getStr(name), ...args); -} - -module.exports = { - getStr, - getFormatStr, - setBundle -}; diff --git a/packages/devtools-local-toolbox/src/utils/assert.js b/packages/devtools-local-toolbox/src/utils/assert.js deleted file mode 100644 index 521653432b..0000000000 --- a/packages/devtools-local-toolbox/src/utils/assert.js +++ /dev/null @@ -1,7 +0,0 @@ -function assert(condition, message) { - if (!condition) { - throw new Error(`Assertion failure: ${message}`); - } -} - -module.exports = assert; diff --git a/packages/devtools-local-toolbox/src/utils/create-store.js b/packages/devtools-local-toolbox/src/utils/create-store.js deleted file mode 100644 index bf04050f7b..0000000000 --- a/packages/devtools-local-toolbox/src/utils/create-store.js +++ /dev/null @@ -1,65 +0,0 @@ -// @flow - -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -/* global window */ - -const { createStore, applyMiddleware } = require("redux"); -const { waitUntilService } = require("./redux/middleware/wait-service"); -const { log } = require("./redux/middleware/log"); -const { history } = require("./redux/middleware/history"); -const { promise } = require("./redux/middleware/promise"); -const { thunk } = require("./redux/middleware/thunk"); - -type ReduxStoreOptions = { - makeThunkArgs?: Function, - history?: boolean, - middleware?: Function[], - log?: boolean -}; - -/** - * This creates a dispatcher with all the standard middleware in place - * that all code requires. It can also be optionally configured in - * various ways, such as logging and recording. - * - * @param {object} opts: - * - log: log all dispatched actions to console - * - history: an array to store every action in. Should only be - * used in tests. - * - middleware: array of middleware to be included in the redux store - */ -const configureStore = (opts: ReduxStoreOptions = {}) => { - const middleware = [ - thunk(opts.makeThunkArgs), - promise, - - // Order is important: services must go last as they always - // operate on "already transformed" actions. Actions going through - // them shouldn't have any special fields like promises, they - // should just be normal JSON objects. - waitUntilService - ]; - - if (opts.history) { - middleware.push(history(opts.history)); - } - - if (opts.middleware) { - opts.middleware.forEach(fn => middleware.push(fn)); - } - - if (opts.log) { - middleware.push(log); - } - - // Hook in the redux devtools browser extension if it exists - const devtoolsExt = typeof window === "object" && window.devToolsExtension ? - window.devToolsExtension() : - f => f; - - return applyMiddleware(...middleware)(devtoolsExt(createStore)); -}; - -module.exports = configureStore; diff --git a/packages/devtools-local-toolbox/src/utils/debug.js b/packages/devtools-local-toolbox/src/utils/debug.js deleted file mode 100644 index 1d89e41a89..0000000000 --- a/packages/devtools-local-toolbox/src/utils/debug.js +++ /dev/null @@ -1,20 +0,0 @@ -const { isDevelopment, isTesting } = require("devtools-config"); - -function debugGlobal(field, value) { - if (isDevelopment() || isTesting()) { - window[field] = value; - } -} - -function injectGlobals({ store }) { - debugGlobal("store", store); - debugGlobal("injectDebuggee", require("../test/utils/debuggee")); - debugGlobal("serializeStore", () => { - return JSON.parse(JSON.stringify(store.getState())); - }); -} - -module.exports = { - debugGlobal, - injectGlobals -}; diff --git a/packages/devtools-local-toolbox/src/utils/defer.js b/packages/devtools-local-toolbox/src/utils/defer.js deleted file mode 100644 index c8d2651eb8..0000000000 --- a/packages/devtools-local-toolbox/src/utils/defer.js +++ /dev/null @@ -1,12 +0,0 @@ -module.exports = function defer() { - let resolve, reject; - let promise = new Promise(function() { - resolve = arguments[0]; - reject = arguments[1]; - }); - return { - resolve: resolve, - reject: reject, - promise: promise - }; -}; diff --git a/packages/devtools-local-toolbox/src/utils/event-emitter.js b/packages/devtools-local-toolbox/src/utils/event-emitter.js deleted file mode 100644 index 0801d35701..0000000000 --- a/packages/devtools-local-toolbox/src/utils/event-emitter.js +++ /dev/null @@ -1,125 +0,0 @@ -let EventEmitter = function() {}; - -const defer = require("./defer"); - -/** - * Decorate an object with event emitter functionality. - * - * @param Object objectToDecorate - * Bind all public methods of EventEmitter to - * the objectToDecorate object. - */ -EventEmitter.decorate = function(objectToDecorate) { - let emitter = new EventEmitter(); - objectToDecorate.on = emitter.on.bind(emitter); - objectToDecorate.off = emitter.off.bind(emitter); - objectToDecorate.once = emitter.once.bind(emitter); - objectToDecorate.emit = emitter.emit.bind(emitter); -}; - -EventEmitter.prototype = { - /** - * Connect a listener. - * - * @param string event - * The event name to which we're connecting. - * @param function listener - * Called when the event is fired. - */ - on(event, listener) { - if (!this._eventEmitterListeners) { - this._eventEmitterListeners = new Map(); - } - if (!this._eventEmitterListeners.has(event)) { - this._eventEmitterListeners.set(event, []); - } - this._eventEmitterListeners.get(event).push(listener); - }, - - /** - * Listen for the next time an event is fired. - * - * @param string event - * The event name to which we're connecting. - * @param function listener - * (Optional) Called when the event is fired. Will be called at most - * one time. - * @return promise - * A promise which is resolved when the event next happens. The - * resolution value of the promise is the first event argument. If - * you need access to second or subsequent event arguments (it's rare - * that this is needed) then use listener - */ - once(event, listener) { - let deferred = defer(); - - let handler = (_, first, ...rest) => { - this.off(event, handler); - if (listener) { - listener.apply(null, [event, first, ...rest]); - } - deferred.resolve(first); - }; - - handler._originalListener = listener; - this.on(event, handler); - - return deferred.promise; - }, - - /** - * Remove a previously-registered event listener. Works for events - * registered with either on or once. - * - * @param string event - * The event name whose listener we're disconnecting. - * @param function listener - * The listener to remove. - */ - off(event, listener) { - if (!this._eventEmitterListeners) { - return; - } - let listeners = this._eventEmitterListeners.get(event); - if (listeners) { - this._eventEmitterListeners.set(event, listeners.filter(l => { - return l !== listener && l._originalListener !== listener; - })); - } - }, - - /** - * Emit an event. All arguments to this method will - * be sent to listener functions. - */ - emit(event) { - if (!this._eventEmitterListeners - || !this._eventEmitterListeners.has(event)) { - return; - } - - let originalListeners = this._eventEmitterListeners.get(event); - for (let listener of this._eventEmitterListeners.get(event)) { - // If the object was destroyed during event emission, stop - // emitting. - if (!this._eventEmitterListeners) { - break; - } - - // If listeners were removed during emission, make sure the - // event handler we're going to fire wasn't removed. - if (originalListeners === this._eventEmitterListeners.get(event) || - this._eventEmitterListeners.get(event).some(l => l === listener)) { - try { - listener.apply(null, arguments); - } catch (ex) { - // Prevent a bad listener from interfering with the others. - let msg = `${ex}: ${ex.stack}`; - console.error(msg); - } - } - } - } -}; - -module.exports = EventEmitter; diff --git a/packages/devtools-local-toolbox/src/utils/fromJS.js b/packages/devtools-local-toolbox/src/utils/fromJS.js deleted file mode 100644 index 1fb65ae198..0000000000 --- a/packages/devtools-local-toolbox/src/utils/fromJS.js +++ /dev/null @@ -1,39 +0,0 @@ -// @flow - -const Immutable = require("immutable"); - -// When our app state is fully types, we should be able to get rid of -// this function. This is only temporarily necessary to support -// converting typed objects to immutable.js, which usually happens in -// reducers. -function fromJS(value: any) : any { - if (Array.isArray(value)) { - return Immutable.Seq(value).map(fromJS).toList(); - } - if (value && value.constructor.meta) { - // This adds support for tcomb objects which are native JS objects - // but are not "plain", so the above checks fail. Since they - // behave the same we can use the same constructors, but we need - // special checks for them. - const kind = value.constructor.meta.kind; - if (kind === "struct") { - return Immutable.Seq(value).map(fromJS).toMap(); - } else if (kind === "list") { - return Immutable.Seq(value).map(fromJS).toList(); - } - } - - // If it's a primitive type, just return the value. Note `==` check - // for null, which is intentionally used to match either `null` or - // `undefined`. - if (value == null || (typeof value !== "object")) { - return value; - } - - // Otherwise, treat it like an object. We can't reliably detect if - // it's a plain object because we might be objects from other JS - // contexts so `Object !== Object`. - return Immutable.Seq(value).map(fromJS).toMap(); -} - -module.exports = fromJS; diff --git a/packages/devtools-local-toolbox/src/utils/redux/middleware/history.js b/packages/devtools-local-toolbox/src/utils/redux/middleware/history.js deleted file mode 100644 index 986bc6f49d..0000000000 --- a/packages/devtools-local-toolbox/src/utils/redux/middleware/history.js +++ /dev/null @@ -1,22 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -const { isDevelopment } = require("devtools-config"); - -/** - * A middleware that stores every action coming through the store in the passed - * in logging object. Should only be used for tests, as it collects all - * action information, which will cause memory bloat. - */ -exports.history = (log = []) => ({ dispatch, getState }) => { - if (isDevelopment()) { - console.warn("Using history middleware stores all actions in state for " + - "testing and devtools is not currently running in test " + - "mode. Be sure this is intentional."); - } - return next => action => { - log.push(action); - next(action); - }; -}; diff --git a/packages/devtools-local-toolbox/src/utils/redux/middleware/log.js b/packages/devtools-local-toolbox/src/utils/redux/middleware/log.js deleted file mode 100644 index 8fa9da4c6f..0000000000 --- a/packages/devtools-local-toolbox/src/utils/redux/middleware/log.js +++ /dev/null @@ -1,14 +0,0 @@ -/** - * A middleware that logs all actions coming through the system - * to the console. - */ -function log({ dispatch, getState }) { - return next => action => { - const actionText = JSON.stringify(action, null, 2); - const truncatedActionText = actionText.slice(0, 1000) + "..."; - console.log(`[DISPATCH ${action.type}]`, action, truncatedActionText); - next(action); - }; -} - -exports.log = log; diff --git a/packages/devtools-local-toolbox/src/utils/redux/middleware/promise.js b/packages/devtools-local-toolbox/src/utils/redux/middleware/promise.js deleted file mode 100644 index a3df99af6d..0000000000 --- a/packages/devtools-local-toolbox/src/utils/redux/middleware/promise.js +++ /dev/null @@ -1,57 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -const defer = require("../../defer"); -const { entries, toObject } = require("../../utils"); -const { executeSoon } = require("../../DevToolsUtils"); - -const PROMISE = exports.PROMISE = "@@dispatch/promise"; -let seqIdVal = 1; - -function seqIdGen() { - return seqIdVal++; -} - -function promiseMiddleware({ dispatch, getState }) { - return next => action => { - if (!(PROMISE in action)) { - return next(action); - } - - const promiseInst = action[PROMISE]; - const seqId = seqIdGen().toString(); - - // Create a new action that doesn't have the promise field and has - // the `seqId` field that represents the sequence id - action = Object.assign( - toObject(entries(action).filter(pair => pair[0] !== PROMISE)), { seqId } - ); - - dispatch(Object.assign({}, action, { status: "start" })); - - // Return the promise so action creators can still compose if they - // want to. - const deferred = defer(); - promiseInst.then(value => { - executeSoon(() => { - dispatch(Object.assign({}, action, { - status: "done", - value: value - })); - deferred.resolve(value); - }); - }, error => { - executeSoon(() => { - dispatch(Object.assign({}, action, { - status: "error", - error: error.message || error - })); - deferred.reject(error); - }); - }); - return deferred.promise; - }; -} - -exports.promise = promiseMiddleware; diff --git a/packages/devtools-local-toolbox/src/utils/redux/middleware/thunk.js b/packages/devtools-local-toolbox/src/utils/redux/middleware/thunk.js deleted file mode 100644 index c6f11aae7c..0000000000 --- a/packages/devtools-local-toolbox/src/utils/redux/middleware/thunk.js +++ /dev/null @@ -1,20 +0,0 @@ - -/** - * A middleware that allows thunks (functions) to be dispatched. If - * it's a thunk, it is called with an argument that contains - * `dispatch`, `getState`, and any additional args passed in via the - * middleware constructure. This allows the action to create multiple - * actions (most likely asynchronously). - */ -function thunk(makeArgs) { - return ({ dispatch, getState }) => { - const args = { dispatch, getState }; - - return next => action => { - return (typeof action === "function") - ? action(makeArgs ? makeArgs(args, getState()) : args) - : next(action); - }; - }; -} -exports.thunk = thunk; diff --git a/packages/devtools-local-toolbox/src/utils/redux/middleware/wait-service.js b/packages/devtools-local-toolbox/src/utils/redux/middleware/wait-service.js deleted file mode 100644 index 93878a3126..0000000000 --- a/packages/devtools-local-toolbox/src/utils/redux/middleware/wait-service.js +++ /dev/null @@ -1,64 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -"use strict"; - -/** - * A middleware which acts like a service, because it is stateful - * and "long-running" in the background. It provides the ability - * for actions to install a function to be run once when a specific - * condition is met by an action coming through the system. Think of - * it as a thunk that blocks until the condition is met. Example: - * - * ```js - * const services = { WAIT_UNTIL: require('wait-service').NAME }; - * - * { type: services.WAIT_UNTIL, - * predicate: action => action.type === constants.ADD_ITEM, - * run: (dispatch, getState, action) => { - * // Do anything here. You only need to accept the arguments - * // if you need them. `action` is the action that satisfied - * // the predicate. - * } - * } - * ``` - */ -const NAME = exports.NAME = "@@service/waitUntil"; - -function waitUntilService({ dispatch, getState }) { - let pending = []; - - function checkPending(action) { - let readyRequests = []; - let stillPending = []; - - // Find the pending requests whose predicates are satisfied with - // this action. Wait to run the requests until after we update the - // pending queue because the request handler may synchronously - // dispatch again and run this service (that use case is - // completely valid). - for (let request of pending) { - if (request.predicate(action)) { - readyRequests.push(request); - } else { - stillPending.push(request); - } - } - - pending = stillPending; - for (let request of readyRequests) { - request.run(dispatch, getState, action); - } - } - - return next => action => { - if (action.type === NAME) { - pending.push(action); - return null; - } - let result = next(action); - checkPending(action); - return result; - }; -} -exports.waitUntilService = waitUntilService; diff --git a/packages/devtools-local-toolbox/src/utils/utils.js b/packages/devtools-local-toolbox/src/utils/utils.js deleted file mode 100644 index a98c4b6fef..0000000000 --- a/packages/devtools-local-toolbox/src/utils/utils.js +++ /dev/null @@ -1,193 +0,0 @@ -// @flow -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -const co = require("co"); - -function asPaused(client: any, func: any) { - if (client.state != "paused") { - return co(function* () { - yield client.interrupt(); - let result; - - try { - result = yield func(); - } catch (e) { - // Try to put the debugger back in a working state by resuming - // it - yield client.resume(); - throw e; - } - - yield client.resume(); - return result; - }); - } - return func(); -} - -function handleError(err: any) { - console.log("ERROR: ", err); -} - -function promisify(context: any, method: any, ...args: any) { - return new Promise((resolve, reject) => { - args.push(response => { - if (response.error) { - reject(response); - } else { - resolve(response); - } - }); - method.apply(context, args); - }); -} - -function truncateStr(str: any, size: any) { - if (str.length > size) { - return `${str.slice(0, size)}...`; - } - return str; -} - -function endTruncateStr(str: string, size: number) { - if (str.length > size) { - return `...${str.slice(str.length - size)}`; - } - return str; -} - -let msgId = 1; -function workerTask(worker: any, method: string) { - return function(...args: any) { - return new Promise((resolve, reject) => { - const id = msgId++; - worker.postMessage({ id, method, args }); - - const listener = ({ data: result }) => { - if (result.id !== id) { - return; - } - - worker.removeEventListener("message", listener); - if (result.error) { - reject(result.error); - } else { - resolve(result.response); - } - }; - - worker.addEventListener("message", listener); - }); - }; -} - -/** - * Interleaves two arrays element by element, returning the combined array, like - * a zip. In the case of arrays with different sizes, undefined values will be - * interleaved at the end along with the extra values of the larger array. - * - * @param Array a - * @param Array b - * @returns Array - * The combined array, in the form [a1, b1, a2, b2, ...] - */ -function zip(a: any, b: any) { - if (!b) { - return a; - } - if (!a) { - return b; - } - const pairs = []; - for (let i = 0, aLength = a.length, bLength = b.length; - i < aLength || i < bLength; - i++) { - pairs.push([a[i], b[i]]); - } - return pairs; -} - -/** - * Converts an object into an array with 2-element arrays as key/value - * pairs of the object. `{ foo: 1, bar: 2}` would become - * `[[foo, 1], [bar 2]]` (order not guaranteed); - * - * @param object obj - * @returns array - */ -function entries(obj: any) { - return Object.keys(obj).map(k => [k, obj[k]]); -} - -function mapObject(obj: any, iteratee: any) { - return toObject(entries(obj).map(([key, value]) => { - return [key, iteratee(key, value)]; - })); -} - -/** - * Takes an array of 2-element arrays as key/values pairs and - * constructs an object using them. - */ -function toObject(arr: any) { - const obj = {}; - for (let pair of arr) { - obj[pair[0]] = pair[1]; - } - return obj; -} - -/** - * Composes the given functions into a single function, which will - * apply the results of each function right-to-left, starting with - * applying the given arguments to the right-most function. - * `compose(foo, bar, baz)` === `args => foo(bar(baz(args)` - * - * @param ...function funcs - * @returns function - */ -function compose(...funcs: any) { - return (...args: any) => { - const initialValue = funcs[funcs.length - 1].apply(null, args); - const leftFuncs = funcs.slice(0, -1); - return leftFuncs.reduceRight((composed, f) => f(composed), - initialValue); - }; -} - -function updateObj(obj: T, fields: $Shape) : T { - return Object.assign({}, obj, fields); -} - -function throttle(func: any, ms: number) { - let timeout, _this; - return function(...args: any) { - _this = this; - if (!timeout) { - timeout = setTimeout(() => { - func.apply(_this, ...args); - timeout = null; - }, ms); - } - }; -} - -module.exports = { - asPaused, - handleError, - promisify, - truncateStr, - endTruncateStr, - workerTask, - zip, - entries, - toObject, - mapObject, - compose, - updateObj, - throttle -}; diff --git a/packages/devtools-local-toolbox/webpack.config.devtools.js b/packages/devtools-local-toolbox/webpack.config.devtools.js deleted file mode 100644 index 5325137b3c..0000000000 --- a/packages/devtools-local-toolbox/webpack.config.devtools.js +++ /dev/null @@ -1,77 +0,0 @@ - -const path = require("path"); -const webpack = require("webpack"); - -const { DefinePlugin } = webpack; - -const ignoreRegexes = [ - /(chrome-remote-debugging-protocol)/ -]; - -const nativeMapping = { - "../utils/source-editor": "devtools/client/sourceeditor/editor", - "./test-flag": "devtools/shared/flags", - "./client/shared/shim/Services": "Services", - - // React can be required a few different ways, make sure they are - // all mapped. - "react": "devtools/client/shared/vendor/react", - "devtools/client/shared/vendor/react": "devtools/client/shared/vendor/react", - "react/lib/ReactDOM": "devtools/client/shared/vendor/react-dom" -}; - -let packagesPath = path.join(__dirname, "../"); -let projectPath = path.join(__dirname, "../../"); - -module.exports = (webpackConfig, envConfig) => { - webpackConfig.output.library = "Debugger"; - - if (process.env.MOCHITESTS) { - webpackConfig.output.path = path.join( - projectPath, - "firefox/devtools/client/debugger/new" - ); - } - - webpackConfig.resolve.alias["devtools-network-request"] = path.resolve( - packagesPath, - "devtools-network-request/privilegedNetworkRequest" - ); - - function externalsTest(context, request, callback) { - let mod = request; - - // Any matching paths here won't be included in the bundle. - if (ignoreRegexes.some(r => r.test(request))) { - callback(null, "var {}"); - return; - } else if (nativeMapping[mod]) { - const mapping = nativeMapping[mod]; - if (Array.isArray(mapping)) { - callback(null, `var devtoolsRequire("${mapping[0]}")["${mapping[1]}"]`); - } - else { - callback(null, `var devtoolsRequire("${mapping}")`); - } - return; - } - callback(); - } - - webpackConfig.externals = webpackConfig.externals || []; - webpackConfig.externals.push(externalsTest); - - // Remove the existing DefinePlugin so we can override it. - const plugins = webpackConfig.plugins.filter(p => !(p instanceof DefinePlugin)); - webpackConfig.plugins = plugins.concat([ - new webpack.DefinePlugin({ - "process.env": { - NODE_ENV: JSON.stringify(process.env.NODE_ENV || "production"), - TARGET: JSON.stringify("firefox-panel") - }, - "DebuggerConfig": JSON.stringify(envConfig) - }) - ]); - - return webpackConfig; -}; diff --git a/packages/devtools-local-toolbox/webpack.config.js b/packages/devtools-local-toolbox/webpack.config.js deleted file mode 100644 index c07f770661..0000000000 --- a/packages/devtools-local-toolbox/webpack.config.js +++ /dev/null @@ -1,122 +0,0 @@ - -require("babel-register"); - -const path = require("path"); -const webpack = require("webpack"); -const ExtractTextPlugin = require("extract-text-webpack-plugin"); -const { isDevelopment, isFirefoxPanel, getValue } = require("devtools-config"); -const NODE_ENV = process.env.NODE_ENV || "development"; -const TARGET = process.env.TARGET || "local"; - -const defaultBabelPlugins = [ - "transform-flow-strip-types", - "transform-async-to-generator" -]; - -module.exports = (webpackConfig, envConfig) => { - webpackConfig.context = path.resolve(__dirname, "src"); - webpackConfig.devtool = "source-map"; - - webpackConfig.module = webpackConfig.module || {}; - webpackConfig.module.loaders = webpackConfig.module.loaders || []; - webpackConfig.module.loaders.push({ - test: /\.json$/, - loader: "json" - }); - webpackConfig.module.loaders.push({ - test: /\.js$/, - exclude: request => { - let excluded = request.match(/(node_modules|bower_components|fs)/); - if (webpackConfig.babelExcludes) { - // If the tool defines an additional exclude regexp for Babel. - excluded = excluded || request.match(webpackConfig.babelExcludes); - } - return excluded && !request.match(/devtools-local-toolbox(\/|\\)src/); - }, - loaders: [ - "babel?" + - defaultBabelPlugins.map(p => "plugins[]=" + p) + - "&ignore=src/lib" - ], - isJavaScriptLoader: true - }); - webpackConfig.module.loaders.push({ - test: /\.svg$/, - exclude: /lkdjlskdjslkdjsdlk/, - loader: "svg-inline" - }); - - const ignoreRegexes = [/^fs$/]; - webpackConfig.externals = webpackConfig.externals || []; - - function externalsTest(context, request, callback) { - let mod = request; - - // Any matching paths here won't be included in the bundle. - if (ignoreRegexes.some(r => r.test(request))) { - return callback(null, "var {}"); - } - - callback(); - } - webpackConfig.externals.push(externalsTest); - - webpackConfig.plugins = webpackConfig.plugins || []; - webpackConfig.plugins.push( - new webpack.DefinePlugin({ - "process.env": { - NODE_ENV: JSON.stringify(NODE_ENV), - TARGET: JSON.stringify(TARGET) - }, - "DebuggerConfig": JSON.stringify(envConfig) - }) - ); - - if (isDevelopment()) { - webpackConfig.module.loaders.push({ - test: /\.css$/, - exclude: /lkjsdflksdjlksdj/, - loader: "style!css" - }); - - if (getValue("hotReloading")) { - webpackConfig.entry.bundle.push("webpack-hot-middleware/client"); - - webpackConfig.plugins = webpackConfig.plugins.concat([ - new webpack.HotModuleReplacementPlugin(), - new webpack.NoErrorsPlugin() - ]); - - webpackConfig.module.loaders.forEach(spec => { - if (spec.isJavaScriptLoader) { - spec.loaders.unshift("react-hot"); - } - }); - } - } else { - // Extract CSS into a single file - webpackConfig.module.loaders.push({ - test: /\.css$/, - loader: ExtractTextPlugin.extract("style-loader", "css-loader") - }); - - webpackConfig.plugins.push(new ExtractTextPlugin("styles.css")); - } - - if (isFirefoxPanel()) { - webpackConfig = require("./webpack.config.devtools")(webpackConfig, envConfig); - } - - // NOTE: This is only needed to fix a bug with chrome devtools' debugger and - // destructuring params https://github.com/devtools-html/debugger.html/issues/67 - if (getValue("transformParameters")) { - webpackConfig.module.loaders.forEach(spec => { - if (spec.isJavaScriptLoader) { - const idx = spec.loaders.findIndex(loader => loader.includes("babel")); - spec.loaders[idx] += "&plugins[]=transform-es2015-parameters"; - } - }); - } - - return webpackConfig; -}; diff --git a/packages/devtools-modules/client/shared/components/reps/array.js b/packages/devtools-modules/client/shared/components/reps/array.js deleted file mode 100644 index 70e1baa657..0000000000 --- a/packages/devtools-modules/client/shared/components/reps/array.js +++ /dev/null @@ -1,189 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -// Make this available to both AMD and CJS environments -define(function (require, exports, module) { - // Dependencies - const React = require("devtools/client/shared/vendor/react"); - const { createFactories } = require("./rep-utils"); - const { Caption } = createFactories(require("./caption")); - - // Shortcuts - const DOM = React.DOM; - - /** - * Renders an array. The array is enclosed by left and right bracket - * and the max number of rendered items depends on the current mode. - */ - let ArrayRep = React.createClass({ - displayName: "ArrayRep", - - getTitle: function (object, context) { - return "[" + object.length + "]"; - }, - - arrayIterator: function (array, max) { - let items = []; - let delim; - - for (let i = 0; i < array.length && i < max; i++) { - try { - let value = array[i]; - - delim = (i == array.length - 1 ? "" : ", "); - - items.push(ItemRep({ - key: i, - object: value, - // Hardcode tiny mode to avoid recursive handling. - mode: "tiny", - delim: delim - })); - } catch (exc) { - items.push(ItemRep({ - key: i, - object: exc, - mode: "tiny", - delim: delim - })); - } - } - - if (array.length > max) { - let objectLink = this.props.objectLink || DOM.span; - items.push(Caption({ - key: "more", - object: objectLink({ - object: this.props.object - }, (array.length - max) + " more…") - })); - } - - return items; - }, - - /** - * Returns true if the passed object is an array with additional (custom) - * properties, otherwise returns false. Custom properties should be - * displayed in extra expandable section. - * - * Example array with a custom property. - * let arr = [0, 1]; - * arr.myProp = "Hello"; - * - * @param {Array} array The array object. - */ - hasSpecialProperties: function (array) { - function isInteger(x) { - let y = parseInt(x, 10); - if (isNaN(y)) { - return false; - } - return x === y.toString(); - } - - let props = Object.getOwnPropertyNames(array); - for (let i = 0; i < props.length; i++) { - let p = props[i]; - - // Valid indexes are skipped - if (isInteger(p)) { - continue; - } - - // Ignore standard 'length' property, anything else is custom. - if (p != "length") { - return true; - } - } - - return false; - }, - - // Event Handlers - - onToggleProperties: function (event) { - }, - - onClickBracket: function (event) { - }, - - render: function () { - let mode = this.props.mode || "short"; - let object = this.props.object; - let items; - let brackets; - let needSpace = function (space) { - return space ? { left: "[ ", right: " ]"} : { left: "[", right: "]"}; - }; - - if (mode == "tiny") { - let isEmpty = object.length === 0; - items = DOM.span({className: "length"}, isEmpty ? "" : object.length); - brackets = needSpace(false); - } else { - let max = (mode == "short") ? 3 : 300; - items = this.arrayIterator(object, max); - brackets = needSpace(items.length > 0); - } - - let objectLink = this.props.objectLink || DOM.span; - - return ( - DOM.span({ - className: "objectBox objectBox-array"}, - objectLink({ - className: "arrayLeftBracket", - object: object - }, brackets.left), - items, - objectLink({ - className: "arrayRightBracket", - object: object - }, brackets.right), - DOM.span({ - className: "arrayProperties", - role: "group"} - ) - ) - ); - }, - }); - - /** - * Renders array item. Individual values are separated by a comma. - */ - let ItemRep = React.createFactory(React.createClass({ - displayName: "ItemRep", - - render: function () { - const { Rep } = createFactories(require("./rep")); - - let object = this.props.object; - let delim = this.props.delim; - let mode = this.props.mode; - return ( - DOM.span({}, - Rep({object: object, mode: mode}), - delim - ) - ); - } - })); - - function supportsObject(object, type) { - return Array.isArray(object) || - Object.prototype.toString.call(object) === "[object Arguments]"; - } - - // Exports from this module - exports.ArrayRep = { - rep: ArrayRep, - supportsObject: supportsObject - }; -}); diff --git a/packages/devtools-modules/client/shared/components/reps/attribute.js b/packages/devtools-modules/client/shared/components/reps/attribute.js deleted file mode 100644 index f57ed03806..0000000000 --- a/packages/devtools-modules/client/shared/components/reps/attribute.js +++ /dev/null @@ -1,70 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -"use strict"; - -// Make this available to both AMD and CJS environments -define(function (require, exports, module) { - // ReactJS - const React = require("devtools/client/shared/vendor/react"); - - // Reps - const { createFactories, isGrip } = require("./rep-utils"); - const { StringRep } = require("./string"); - - // Shortcuts - const { span } = React.DOM; - const { rep: StringRepFactory } = createFactories(StringRep); - - /** - * Renders DOM attribute - */ - let Attribute = React.createClass({ - displayName: "Attr", - - propTypes: { - object: React.PropTypes.object.isRequired - }, - - getTitle: function (grip) { - return grip.preview.nodeName; - }, - - render: function () { - let grip = this.props.object; - let value = grip.preview.value; - let objectLink = this.props.objectLink || span; - - return ( - objectLink({className: "objectLink-Attr"}, - span({}, - span({className: "attrTitle"}, - this.getTitle(grip) - ), - span({className: "attrEqual"}, - "=" - ), - StringRepFactory({object: value}) - ) - ) - ); - }, - }); - - // Registration - - function supportsObject(grip, type) { - if (!isGrip(grip)) { - return false; - } - - return (type == "Attr" && grip.preview); - } - - exports.Attribute = { - rep: Attribute, - supportsObject: supportsObject - }; -}); diff --git a/packages/devtools-modules/client/shared/components/reps/caption.js b/packages/devtools-modules/client/shared/components/reps/caption.js deleted file mode 100644 index 7f00b01e8d..0000000000 --- a/packages/devtools-modules/client/shared/components/reps/caption.js +++ /dev/null @@ -1,31 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -// Make this available to both AMD and CJS environments -define(function (require, exports, module) { - // Dependencies - const React = require("devtools/client/shared/vendor/react"); - const DOM = React.DOM; - - /** - * Renders a caption. This template is used by other components - * that needs to distinguish between a simple text/value and a label. - */ - const Caption = React.createClass({ - displayName: "Caption", - - render: function () { - return ( - DOM.span({"className": "caption"}, this.props.object) - ); - }, - }); - - // Exports from this module - exports.Caption = Caption; -}); diff --git a/packages/devtools-modules/client/shared/components/reps/date-time.js b/packages/devtools-modules/client/shared/components/reps/date-time.js deleted file mode 100644 index 8df7f7e3b0..0000000000 --- a/packages/devtools-modules/client/shared/components/reps/date-time.js +++ /dev/null @@ -1,66 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -"use strict"; - -// Make this available to both AMD and CJS environments -define(function (require, exports, module) { - // ReactJS - const React = require("devtools/client/shared/vendor/react"); - - // Reps - const { isGrip } = require("./rep-utils"); - - // Shortcuts - const { span } = React.DOM; - - /** - * Used to render JS built-in Date() object. - */ - let DateTime = React.createClass({ - displayName: "Date", - - propTypes: { - object: React.PropTypes.object.isRequired - }, - - getTitle: function (grip) { - if (this.props.objectLink) { - return this.props.objectLink({ - object: grip - }, grip.class + " "); - } - return ""; - }, - - render: function () { - let grip = this.props.object; - return ( - span({className: "objectBox"}, - this.getTitle(grip), - span({className: "Date"}, - new Date(grip.preview.timestamp).toISOString() - ) - ) - ); - }, - }); - - // Registration - - function supportsObject(grip, type) { - if (!isGrip(grip)) { - return false; - } - - return (type == "Date" && grip.preview); - } - - // Exports from this module - exports.DateTime = { - rep: DateTime, - supportsObject: supportsObject - }; -}); diff --git a/packages/devtools-modules/client/shared/components/reps/document.js b/packages/devtools-modules/client/shared/components/reps/document.js deleted file mode 100644 index 25e42609f0..0000000000 --- a/packages/devtools-modules/client/shared/components/reps/document.js +++ /dev/null @@ -1,78 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -"use strict"; - -// Make this available to both AMD and CJS environments -define(function (require, exports, module) { - // ReactJS - const React = require("devtools/client/shared/vendor/react"); - - // Reps - const { isGrip, getURLDisplayString } = require("./rep-utils"); - - // Shortcuts - const { span } = React.DOM; - - /** - * Renders DOM document object. - */ - let Document = React.createClass({ - displayName: "Document", - - propTypes: { - object: React.PropTypes.object.isRequired - }, - - getLocation: function (grip) { - let location = grip.preview.location; - return location ? getURLDisplayString(location) : ""; - }, - - getTitle: function (grip) { - if (this.props.objectLink) { - return span({className: "objectBox"}, - this.props.objectLink({ - object: grip - }, grip.class + " ") - ); - } - return ""; - }, - - getTooltip: function (doc) { - return doc.location.href; - }, - - render: function () { - let grip = this.props.object; - - return ( - span({className: "objectBox objectBox-object"}, - this.getTitle(grip), - span({className: "objectPropValue"}, - this.getLocation(grip) - ) - ) - ); - }, - }); - - // Registration - - function supportsObject(object, type) { - if (!isGrip(object)) { - return false; - } - - return (object.preview && type == "HTMLDocument"); - } - - // Exports from this module - exports.Document = { - rep: Document, - supportsObject: supportsObject - }; -}); diff --git a/packages/devtools-modules/client/shared/components/reps/event.js b/packages/devtools-modules/client/shared/components/reps/event.js deleted file mode 100644 index 1d37e01504..0000000000 --- a/packages/devtools-modules/client/shared/components/reps/event.js +++ /dev/null @@ -1,81 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -"use strict"; - -// Make this available to both AMD and CJS environments -define(function (require, exports, module) { - // ReactJS - const React = require("devtools/client/shared/vendor/react"); - - // Reps - const { createFactories, isGrip } = require("./rep-utils"); - const { rep } = createFactories(require("./grip").Grip); - - /** - * Renders DOM event objects. - */ - let Event = React.createClass({ - displayName: "event", - - propTypes: { - object: React.PropTypes.object.isRequired - }, - - render: function () { - // Use `Object.assign` to keep `this.props` without changes because: - // 1. JSON.stringify/JSON.parse is slow. - // 2. Immutable.js is planned for the future. - let props = Object.assign({}, this.props); - props.object = Object.assign({}, this.props.object); - props.object.preview = Object.assign({}, this.props.object.preview); - props.object.preview.ownProperties = props.object.preview.properties; - delete props.object.preview.properties; - props.object.ownPropertyLength = - Object.keys(props.object.preview.ownProperties).length; - - switch (props.object.class) { - case "MouseEvent": - props.isInterestingProp = (type, value, name) => { - return (name == "clientX" || - name == "clientY" || - name == "layerX" || - name == "layerY"); - }; - break; - case "KeyboardEvent": - props.isInterestingProp = (type, value, name) => { - return (name == "key" || - name == "charCode" || - name == "keyCode"); - }; - break; - case "MessageEvent": - props.isInterestingProp = (type, value, name) => { - return (name == "isTrusted" || - name == "data"); - }; - break; - } - return rep(props); - } - }); - - // Registration - - function supportsObject(grip, type) { - if (!isGrip(grip)) { - return false; - } - - return (grip.preview && grip.preview.kind == "DOMEvent"); - } - - // Exports from this module - exports.Event = { - rep: Event, - supportsObject: supportsObject - }; -}); diff --git a/packages/devtools-modules/client/shared/components/reps/function.js b/packages/devtools-modules/client/shared/components/reps/function.js deleted file mode 100644 index 095d8e360d..0000000000 --- a/packages/devtools-modules/client/shared/components/reps/function.js +++ /dev/null @@ -1,71 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -"use strict"; - -// Make this available to both AMD and CJS environments -define(function (require, exports, module) { - // ReactJS - const React = require("devtools/client/shared/vendor/react"); - - // Reps - const { isGrip, cropString } = require("./rep-utils"); - - // Shortcuts - const { span } = React.DOM; - - /** - * This component represents a template for Function objects. - */ - let Func = React.createClass({ - displayName: "Func", - - propTypes: { - object: React.PropTypes.object.isRequired - }, - - getTitle: function (grip) { - if (this.props.objectLink) { - return this.props.objectLink({ - object: grip - }, "function "); - } - return ""; - }, - - summarizeFunction: function (grip) { - let name = grip.userDisplayName || grip.displayName || grip.name || "function"; - return cropString(name + "()", 100); - }, - - render: function () { - let grip = this.props.object; - - return ( - span({className: "objectBox objectBox-function"}, - this.getTitle(grip), - this.summarizeFunction(grip) - ) - ); - }, - }); - - // Registration - - function supportsObject(grip, type) { - if (!isGrip(grip)) { - return (type == "function"); - } - - return (type == "Function"); - } - - // Exports from this module - - exports.Func = { - rep: Func, - supportsObject: supportsObject - }; -}); diff --git a/packages/devtools-modules/client/shared/components/reps/grip-array.js b/packages/devtools-modules/client/shared/components/reps/grip-array.js deleted file mode 100644 index edec087c20..0000000000 --- a/packages/devtools-modules/client/shared/components/reps/grip-array.js +++ /dev/null @@ -1,184 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -// Make this available to both AMD and CJS environments -define(function (require, exports, module) { - // Dependencies - const React = require("devtools/client/shared/vendor/react"); - const { createFactories, isGrip } = require("./rep-utils"); - const { Caption } = createFactories(require("./caption")); - - // Shortcuts - const { span } = React.DOM; - - /** - * Renders an array. The array is enclosed by left and right bracket - * and the max number of rendered items depends on the current mode. - */ - let GripArray = React.createClass({ - displayName: "GripArray", - - propTypes: { - object: React.PropTypes.object.isRequired, - mode: React.PropTypes.string, - provider: React.PropTypes.object, - }, - - getLength: function (grip) { - return grip.preview ? grip.preview.length : 0; - }, - - getTitle: function (object, context) { - let objectLink = this.props.objectLink || span; - if (this.props.mode != "tiny") { - return objectLink({ - object: object - }, object.class + " "); - } - return ""; - }, - - arrayIterator: function (grip, max) { - let items = []; - - if (!grip.preview || !grip.preview.length) { - return items; - } - - let array = grip.preview.items; - if (!array) { - return items; - } - - let delim; - // number of grip.preview.items is limited to 10, but we may have more - // items in grip-array - let delimMax = grip.preview.length > array.length ? - array.length : array.length - 1; - let provider = this.props.provider; - - for (let i = 0; i < array.length && i < max; i++) { - try { - let itemGrip = array[i]; - let value = provider ? provider.getValue(itemGrip) : itemGrip; - - delim = (i == delimMax ? "" : ", "); - - items.push(GripArrayItem(Object.assign({}, this.props, { - key: i, - object: value, - delim: delim} - ))); - } catch (exc) { - items.push(GripArrayItem(Object.assign({}, this.props, { - object: exc, - delim: delim, - key: i} - ))); - } - } - if (array.length > max || grip.preview.length > array.length) { - let objectLink = this.props.objectLink || span; - let leftItemNum = grip.preview.length - max > 0 ? - grip.preview.length - max : grip.preview.length - array.length; - items.push(Caption({ - key: "more", - object: objectLink({ - object: this.props.object - }, leftItemNum + " more…") - })); - } - - return items; - }, - - render: function () { - let mode = this.props.mode || "short"; - let object = this.props.object; - - let items; - let brackets; - let needSpace = function (space) { - return space ? { left: "[ ", right: " ]"} : { left: "[", right: "]"}; - }; - - if (mode == "tiny") { - let objectLength = this.getLength(object); - let isEmpty = objectLength === 0; - items = span({className: "length"}, isEmpty ? "" : objectLength); - brackets = needSpace(false); - } else { - let max = (mode == "short") ? 3 : 300; - items = this.arrayIterator(object, max); - brackets = needSpace(items.length > 0); - } - - let objectLink = this.props.objectLink || span; - let title = this.getTitle(object); - - return ( - span({ - className: "objectBox objectBox-array"}, - title, - objectLink({ - className: "arrayLeftBracket", - object: object - }, brackets.left), - items, - objectLink({ - className: "arrayRightBracket", - object: object - }, brackets.right), - span({ - className: "arrayProperties", - role: "group"} - ) - ) - ); - }, - }); - - /** - * Renders array item. Individual values are separated by - * a delimiter (a comma by default). - */ - let GripArrayItem = React.createFactory(React.createClass({ - displayName: "GripArrayItem", - - propTypes: { - delim: React.PropTypes.string, - }, - - render: function () { - let { Rep } = createFactories(require("./rep")); - - return ( - span({}, - Rep(Object.assign({}, this.props, { - mode: "tiny" - })), - this.props.delim - ) - ); - } - })); - - function supportsObject(grip, type) { - if (!isGrip(grip)) { - return false; - } - - return (grip.preview && grip.preview.kind == "ArrayLike"); - } - - // Exports from this module - exports.GripArray = { - rep: GripArray, - supportsObject: supportsObject - }; -}); diff --git a/packages/devtools-modules/client/shared/components/reps/grip-map.js b/packages/devtools-modules/client/shared/components/reps/grip-map.js deleted file mode 100644 index df673d0052..0000000000 --- a/packages/devtools-modules/client/shared/components/reps/grip-map.js +++ /dev/null @@ -1,193 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; -// Make this available to both AMD and CJS environments -define(function (require, exports, module) { - // Dependencies - const React = require("devtools/client/shared/vendor/react"); - const { createFactories, isGrip } = require("./rep-utils"); - const { Caption } = createFactories(require("./caption")); - const { PropRep } = createFactories(require("./prop-rep")); - - // Shortcuts - const { span } = React.DOM; - /** - * Renders an map. A map is represented by a list of its - * entries enclosed in curly brackets. - */ - const GripMap = React.createClass({ - displayName: "GripMap", - - propTypes: { - object: React.PropTypes.object, - mode: React.PropTypes.string, - }, - - getTitle: function (object) { - let title = object && object.class ? object.class : "Map"; - if (this.props.objectLink) { - return this.props.objectLink({ - object: object - }, title); - } - return title; - }, - - safeEntriesIterator: function (object, max) { - max = (typeof max === "undefined") ? 3 : max; - try { - return this.entriesIterator(object, max); - } catch (err) { - console.error(err); - } - return []; - }, - - entriesIterator: function (object, max) { - // Entry filter. Show only interesting entries to the user. - let isInterestingEntry = this.props.isInterestingEntry || ((type, value) => { - return ( - type == "boolean" || - type == "number" || - (type == "string" && value.length != 0) - ); - }); - - let mapEntries = object.preview && object.preview.entries - ? object.preview.entries : []; - - let indexes = this.getEntriesIndexes(mapEntries, max, isInterestingEntry); - if (indexes.length < max && indexes.length < mapEntries.length) { - // There are not enough entries yet, so we add uninteresting entries. - indexes = indexes.concat( - this.getEntriesIndexes(mapEntries, max - indexes.length, (t, value, name) => { - return !isInterestingEntry(t, value, name); - }) - ); - } - - let entries = this.getEntries(mapEntries, indexes); - if (entries.length < mapEntries.length) { - // There are some undisplayed entries. Then display "more…". - let objectLink = this.props.objectLink || span; - - entries.push(Caption({ - key: "more", - object: objectLink({ - object: object - }, `${mapEntries.length - max} more…`) - })); - } - - return entries; - }, - - /** - * Get entries ordered by index. - * - * @param {Array} entries Entries array. - * @param {Array} indexes Indexes of entries. - * @return {Array} Array of PropRep. - */ - getEntries: function (entries, indexes) { - // Make indexes ordered by ascending. - indexes.sort(function (a, b) { - return a - b; - }); - - return indexes.map((index, i) => { - let [key, entryValue] = entries[index]; - let value = entryValue.value !== undefined ? entryValue.value : entryValue; - - return PropRep({ - // key, - name: key, - equal: ": ", - object: value, - // Do not add a trailing comma on the last entry - // if there won't be a "more..." item. - delim: (i < indexes.length - 1 || indexes.length < entries.length) ? ", " : "", - mode: "tiny", - objectLink: this.props.objectLink, - }); - }); - }, - - /** - * Get the indexes of entries in the map. - * - * @param {Array} entries Entries array. - * @param {Number} max The maximum length of indexes array. - * @param {Function} filter Filter the entry you want. - * @return {Array} Indexes of filtered entries in the map. - */ - getEntriesIndexes: function (entries, max, filter) { - return entries - .reduce((indexes, [key, entry], i) => { - if (indexes.length < max) { - let value = (entry && entry.value !== undefined) ? entry.value : entry; - // Type is specified in grip's "class" field and for primitive - // values use typeof. - let type = (value && value.class ? value.class : typeof value).toLowerCase(); - - if (filter(type, value, key)) { - indexes.push(i); - } - } - - return indexes; - }, []); - }, - - render: function () { - let object = this.props.object; - let props = this.safeEntriesIterator(object, - (this.props.mode == "long") ? 100 : 3); - - let objectLink = this.props.objectLink || span; - if (this.props.mode == "tiny") { - return ( - span({className: "objectBox objectBox-object"}, - this.getTitle(object), - objectLink({ - className: "objectLeftBrace", - object: object - }, "") - ) - ); - } - - return ( - span({className: "objectBox objectBox-object"}, - this.getTitle(object), - objectLink({ - className: "objectLeftBrace", - object: object - }, " { "), - props, - objectLink({ - className: "objectRightBrace", - object: object - }, " }") - ) - ); - }, - }); - - function supportsObject(grip, type) { - if (!isGrip(grip)) { - return false; - } - return (grip.preview && grip.preview.kind == "MapLike"); - } - - // Exports from this module - exports.GripMap = { - rep: GripMap, - supportsObject: supportsObject - }; -}); diff --git a/packages/devtools-modules/client/shared/components/reps/grip.js b/packages/devtools-modules/client/shared/components/reps/grip.js deleted file mode 100644 index 44cc39ad03..0000000000 --- a/packages/devtools-modules/client/shared/components/reps/grip.js +++ /dev/null @@ -1,218 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -"use strict"; - -// Make this available to both AMD and CJS environments -define(function (require, exports, module) { - // ReactJS - const React = require("devtools/client/shared/vendor/react"); - // Dependencies - const { createFactories, isGrip } = require("./rep-utils"); - const { Caption } = createFactories(require("./caption")); - const { PropRep } = createFactories(require("./prop-rep")); - // Shortcuts - const { span } = React.DOM; - - /** - * Renders generic grip. Grip is client representation - * of remote JS object and is used as an input object - * for this rep component. - */ - const GripRep = React.createClass({ - displayName: "Grip", - - propTypes: { - object: React.PropTypes.object.isRequired, - mode: React.PropTypes.string, - isInterestingProp: React.PropTypes.func - }, - - getTitle: function (object) { - if (this.props.objectLink) { - return this.props.objectLink({ - object: object - }, object.class); - } - return object.class || "Object"; - }, - - safePropIterator: function (object, max) { - max = (typeof max === "undefined") ? 3 : max; - try { - return this.propIterator(object, max); - } catch (err) { - console.error(err); - } - return []; - }, - - propIterator: function (object, max) { - // Property filter. Show only interesting properties to the user. - let isInterestingProp = this.props.isInterestingProp || ((type, value) => { - return ( - type == "boolean" || - type == "number" || - (type == "string" && value.length != 0) - ); - }); - - let ownProperties = object.preview ? object.preview.ownProperties : []; - let indexes = this.getPropIndexes(ownProperties, max, isInterestingProp); - if (indexes.length < max && indexes.length < object.ownPropertyLength) { - // There are not enough props yet. Then add uninteresting props to display them. - indexes = indexes.concat( - this.getPropIndexes(ownProperties, max - indexes.length, (t, value, name) => { - return !isInterestingProp(t, value, name); - }) - ); - } - - let props = this.getProps(ownProperties, indexes); - if (props.length < object.ownPropertyLength) { - // There are some undisplayed props. Then display "more...". - let objectLink = this.props.objectLink || span; - - props.push(Caption({ - key: "more", - object: objectLink({ - object: object - }, ((object ? object.ownPropertyLength : 0) - max) + " more…") - })); - } else if (props.length > 0) { - // Remove the last comma. - // NOTE: do not change comp._store.props directly to update a property, - // it should be re-rendered or cloned with changed props - let last = props.length - 1; - props[last] = React.cloneElement(props[last], { - delim: "" - }); - } - - return props; - }, - - /** - * Get props ordered by index. - * - * @param {Object} ownProperties Props object. - * @param {Array} indexes Indexes of props. - * @return {Array} Props. - */ - getProps: function (ownProperties, indexes) { - let props = []; - - // Make indexes ordered by ascending. - indexes.sort(function (a, b) { - return a - b; - }); - - indexes.forEach((i) => { - let name = Object.keys(ownProperties)[i]; - let prop = ownProperties[name]; - let value = prop.value !== undefined ? prop.value : prop; - props.push(PropRep(Object.assign({}, this.props, { - key: name, - mode: "tiny", - name: name, - object: value, - equal: ": ", - delim: ", ", - defaultRep: Grip - }))); - }); - - return props; - }, - - /** - * Get the indexes of props in the object. - * - * @param {Object} ownProperties Props object. - * @param {Number} max The maximum length of indexes array. - * @param {Function} filter Filter the props you want. - * @return {Array} Indexes of interesting props in the object. - */ - getPropIndexes: function (ownProperties, max, filter) { - let indexes = []; - - try { - let i = 0; - for (let name in ownProperties) { - if (indexes.length >= max) { - return indexes; - } - - let prop = ownProperties[name]; - let value = prop.value !== undefined ? prop.value : prop; - - // Type is specified in grip's "class" field and for primitive - // values use typeof. - let type = (value.class || typeof value); - type = type.toLowerCase(); - - if (filter(type, value, name)) { - indexes.push(i); - } - i++; - } - } catch (err) { - console.error(err); - } - - return indexes; - }, - - render: function () { - let object = this.props.object; - let props = this.safePropIterator(object, - (this.props.mode == "long") ? 100 : 3); - - let objectLink = this.props.objectLink || span; - if (this.props.mode == "tiny" || !props.length) { - return ( - span({className: "objectBox objectBox-object"}, - this.getTitle(object), - objectLink({ - className: "objectLeftBrace", - object: object - }, "") - ) - ); - } - - return ( - span({className: "objectBox objectBox-object"}, - this.getTitle(object), - objectLink({ - className: "objectLeftBrace", - object: object - }, " { "), - props, - objectLink({ - className: "objectRightBrace", - object: object - }, " }") - ) - ); - }, - }); - - // Registration - function supportsObject(object, type) { - if (!isGrip(object)) { - return false; - } - return (object.preview && object.preview.ownProperties); - } - - let Grip = { - rep: GripRep, - supportsObject: supportsObject - }; - - // Exports from this module - exports.Grip = Grip; -}); diff --git a/packages/devtools-modules/client/shared/components/reps/moz.build b/packages/devtools-modules/client/shared/components/reps/moz.build deleted file mode 100644 index 1437663d7f..0000000000 --- a/packages/devtools-modules/client/shared/components/reps/moz.build +++ /dev/null @@ -1,35 +0,0 @@ -# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -DevToolsModules( - 'array.js', - 'attribute.js', - 'caption.js', - 'date-time.js', - 'document.js', - 'event.js', - 'function.js', - 'grip-array.js', - 'grip.js', - 'named-node-map.js', - 'null.js', - 'number.js', - 'object-box.js', - 'object-link.js', - 'object-with-text.js', - 'object-with-url.js', - 'object.js', - 'regexp.js', - 'rep-utils.js', - 'rep.js', - 'reps.css', - 'string.js', - 'stylesheet.js', - 'text-node.js', - 'undefined.js', - 'url.js', - 'window.js', -) diff --git a/packages/devtools-modules/client/shared/components/reps/null.js b/packages/devtools-modules/client/shared/components/reps/null.js deleted file mode 100644 index 5de00f026d..0000000000 --- a/packages/devtools-modules/client/shared/components/reps/null.js +++ /dev/null @@ -1,46 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -// Make this available to both AMD and CJS environments -define(function (require, exports, module) { - // Dependencies - const React = require("devtools/client/shared/vendor/react"); - - // Shortcuts - const { span } = React.DOM; - - /** - * Renders null value - */ - const Null = React.createClass({ - displayName: "NullRep", - - render: function () { - return ( - span({className: "objectBox objectBox-null"}, - "null" - ) - ); - }, - }); - - function supportsObject(object, type) { - if (object && object.type && object.type == "null") { - return true; - } - - return (object == null); - } - - // Exports from this module - - exports.Null = { - rep: Null, - supportsObject: supportsObject - }; -}); diff --git a/packages/devtools-modules/client/shared/components/reps/number.js b/packages/devtools-modules/client/shared/components/reps/number.js deleted file mode 100644 index d902c9e998..0000000000 --- a/packages/devtools-modules/client/shared/components/reps/number.js +++ /dev/null @@ -1,52 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -// Make this available to both AMD and CJS environments -define(function (require, exports, module) { - // Dependencies - const React = require("devtools/client/shared/vendor/react"); - - // Shortcuts - const { span } = React.DOM; - - /** - * Renders a number - */ - const Number = React.createClass({ - displayName: "Number", - - stringify: function (object) { - let isNegativeZero = Object.is(object, -0) || - (object.type && object.type == "-0"); - - return (isNegativeZero ? "-0" : String(object)); - }, - - render: function () { - let value = this.props.object; - - return ( - span({className: "objectBox objectBox-number"}, - this.stringify(value) - ) - ); - } - }); - - function supportsObject(object, type) { - return type == "boolean" || type == "number" || - (type == "object" && object.type == "-0"); - } - - // Exports from this module - - exports.Number = { - rep: Number, - supportsObject: supportsObject - }; -}); diff --git a/packages/devtools-modules/client/shared/components/reps/object-with-text.js b/packages/devtools-modules/client/shared/components/reps/object-with-text.js deleted file mode 100644 index 85168ce785..0000000000 --- a/packages/devtools-modules/client/shared/components/reps/object-with-text.js +++ /dev/null @@ -1,76 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -"use strict"; - -// Make this available to both AMD and CJS environments -define(function (require, exports, module) { - // ReactJS - const React = require("devtools/client/shared/vendor/react"); - - // Reps - const { isGrip } = require("./rep-utils"); - - // Shortcuts - const { span } = React.DOM; - - /** - * Renders a grip object with textual data. - */ - let ObjectWithText = React.createClass({ - displayName: "ObjectWithText", - - propTypes: { - object: React.PropTypes.object.isRequired, - }, - - getTitle: function (grip) { - if (this.props.objectLink) { - return span({className: "objectBox"}, - this.props.objectLink({ - object: grip - }, this.getType(grip) + " ") - ); - } - return ""; - }, - - getType: function (grip) { - return grip.class; - }, - - getDescription: function (grip) { - return "\"" + grip.preview.text + "\""; - }, - - render: function () { - let grip = this.props.object; - return ( - span({className: "objectBox objectBox-" + this.getType(grip)}, - this.getTitle(grip), - span({className: "objectPropValue"}, - this.getDescription(grip) - ) - ) - ); - }, - }); - - // Registration - - function supportsObject(grip, type) { - if (!isGrip(grip)) { - return false; - } - - return (grip.preview && grip.preview.kind == "ObjectWithText"); - } - - // Exports from this module - exports.ObjectWithText = { - rep: ObjectWithText, - supportsObject: supportsObject - }; -}); diff --git a/packages/devtools-modules/client/shared/components/reps/object-with-url.js b/packages/devtools-modules/client/shared/components/reps/object-with-url.js deleted file mode 100644 index 9c4b9a2295..0000000000 --- a/packages/devtools-modules/client/shared/components/reps/object-with-url.js +++ /dev/null @@ -1,76 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -"use strict"; - -// Make this available to both AMD and CJS environments -define(function (require, exports, module) { - // ReactJS - const React = require("devtools/client/shared/vendor/react"); - - // Reps - const { isGrip, getURLDisplayString } = require("./rep-utils"); - - // Shortcuts - const { span } = React.DOM; - - /** - * Renders a grip object with URL data. - */ - let ObjectWithURL = React.createClass({ - displayName: "ObjectWithURL", - - propTypes: { - object: React.PropTypes.object.isRequired, - }, - - getTitle: function (grip) { - if (this.props.objectLink) { - return span({className: "objectBox"}, - this.props.objectLink({ - object: grip - }, this.getType(grip) + " ") - ); - } - return ""; - }, - - getType: function (grip) { - return grip.class; - }, - - getDescription: function (grip) { - return getURLDisplayString(grip.preview.url); - }, - - render: function () { - let grip = this.props.object; - return ( - span({className: "objectBox objectBox-" + this.getType(grip)}, - this.getTitle(grip), - span({className: "objectPropValue"}, - this.getDescription(grip) - ) - ) - ); - }, - }); - - // Registration - - function supportsObject(grip, type) { - if (!isGrip(grip)) { - return false; - } - - return (grip.preview && grip.preview.kind == "ObjectWithURL"); - } - - // Exports from this module - exports.ObjectWithURL = { - rep: ObjectWithURL, - supportsObject: supportsObject - }; -}); diff --git a/packages/devtools-modules/client/shared/components/reps/object.js b/packages/devtools-modules/client/shared/components/reps/object.js deleted file mode 100644 index 18b4d115bf..0000000000 --- a/packages/devtools-modules/client/shared/components/reps/object.js +++ /dev/null @@ -1,173 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; -// Make this available to both AMD and CJS environments -define(function (require, exports, module) { - // Dependencies - const React = require("devtools/client/shared/vendor/react"); - const { createFactories } = require("./rep-utils"); - const { Caption } = createFactories(require("./caption")); - const { PropRep } = createFactories(require("./prop-rep")); - // Shortcuts - const { span } = React.DOM; - /** - * Renders an object. An object is represented by a list of its - * properties enclosed in curly brackets. - */ - const Obj = React.createClass({ - displayName: "Obj", - - propTypes: { - object: React.PropTypes.object, - mode: React.PropTypes.string, - }, - - getTitle: function (object) { - let className = object && object.class ? object.class : "Object"; - if (this.props.objectLink) { - return this.props.objectLink({ - object: object - }, className); - } - return className; - }, - - safePropIterator: function (object, max) { - max = (typeof max === "undefined") ? 3 : max; - try { - return this.propIterator(object, max); - } catch (err) { - console.error(err); - } - return []; - }, - - propIterator: function (object, max) { - let isInterestingProp = (t, value) => { - // Do not pick objects, it could cause recursion. - return (t == "boolean" || t == "number" || (t == "string" && value)); - }; - - // Work around https://bugzilla.mozilla.org/show_bug.cgi?id=945377 - if (Object.prototype.toString.call(object) === "[object Generator]") { - object = Object.getPrototypeOf(object); - } - - // Object members with non-empty values are preferred since it gives the - // user a better overview of the object. - let props = this.getProps(object, max, isInterestingProp); - - if (props.length <= max) { - // There are not enough props yet (or at least, not enough props to - // be able to know whether we should print "more…" or not). - // Let's display also empty members and functions. - props = props.concat(this.getProps(object, max, (t, value) => { - return !isInterestingProp(t, value); - })); - } - - if (props.length > max) { - props.pop(); - let objectLink = this.props.objectLink || span; - - props.push(Caption({ - key: "more", - object: objectLink({ - object: object - }, (Object.keys(object).length - max) + " more…") - })); - } else if (props.length > 0) { - // Remove the last comma. - props[props.length - 1] = React.cloneElement( - props[props.length - 1], { delim: "" }); - } - - return props; - }, - - getProps: function (object, max, filter) { - let props = []; - - max = max || 3; - if (!object) { - return props; - } - - // Hardcode tiny mode to avoid recursive handling. - let mode = "tiny"; - - try { - for (let name in object) { - if (props.length > max) { - return props; - } - - let value; - try { - value = object[name]; - } catch (exc) { - continue; - } - - let t = typeof value; - if (filter(t, value)) { - props.push(PropRep({ - key: name, - mode: mode, - name: name, - object: value, - equal: ": ", - delim: ", ", - })); - } - } - } catch (err) { - console.error(err); - } - - return props; - }, - - render: function () { - let object = this.props.object; - let props = this.safePropIterator(object); - let objectLink = this.props.objectLink || span; - - if (this.props.mode == "tiny" || !props.length) { - return ( - span({className: "objectBox objectBox-object"}, - objectLink({className: "objectTitle"}, this.getTitle(object)) - ) - ); - } - - return ( - span({className: "objectBox objectBox-object"}, - this.getTitle(object), - objectLink({ - className: "objectLeftBrace", - object: object - }, " { "), - props, - objectLink({ - className: "objectRightBrace", - object: object - }, " }") - ) - ); - }, - }); - function supportsObject(object, type) { - return true; - } - - // Exports from this module - exports.Obj = { - rep: Obj, - supportsObject: supportsObject - }; -}); diff --git a/packages/devtools-modules/client/shared/components/reps/prop-rep.js b/packages/devtools-modules/client/shared/components/reps/prop-rep.js deleted file mode 100644 index 775dfea2bb..0000000000 --- a/packages/devtools-modules/client/shared/components/reps/prop-rep.js +++ /dev/null @@ -1,70 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -"use strict"; - -// Make this available to both AMD and CJS environments -define(function (require, exports, module) { - const React = require("devtools/client/shared/vendor/react"); - const { createFactories } = require("./rep-utils"); - const { span } = React.DOM; - - /** - * Property for Obj (local JS objects), Grip (remote JS objects) - * and GripMap (remote JS maps and weakmaps) reps. - * It's used to render object properties. - */ - let PropRep = React.createFactory(React.createClass({ - displayName: "PropRep", - - propTypes: { - // Property name. - name: React.PropTypes.oneOfType([ - React.PropTypes.string, - React.PropTypes.object, - ]).isRequired, - // Equal character rendered between property name and value. - equal: React.PropTypes.string, - // Delimiter character used to separate individual properties. - delim: React.PropTypes.string, - mode: React.PropTypes.string, - }, - - render: function () { - const { Grip } = require("./grip"); - let { Rep } = createFactories(require("./rep")); - - let key; - // The key can be a simple string, for plain objects, - // or another object for maps and weakmaps. - if (typeof this.props.name === "string") { - key = span({"className": "nodeName"}, this.props.name); - } else { - key = Rep({ - object: this.props.name, - mode: this.props.mode || "tiny", - defaultRep: Grip, - objectLink: this.props.objectLink, - }); - } - - return ( - span({}, - key, - span({ - "className": "objectEqual" - }, this.props.equal), - Rep(this.props), - span({ - "className": "objectComma" - }, this.props.delim) - ) - ); - } - })); - - // Exports from this module - exports.PropRep = PropRep; -}); diff --git a/packages/devtools-modules/client/shared/components/reps/regexp.js b/packages/devtools-modules/client/shared/components/reps/regexp.js deleted file mode 100644 index 2f9212658f..0000000000 --- a/packages/devtools-modules/client/shared/components/reps/regexp.js +++ /dev/null @@ -1,63 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -"use strict"; - -// Make this available to both AMD and CJS environments -define(function (require, exports, module) { - // ReactJS - const React = require("devtools/client/shared/vendor/react"); - - // Reps - const { isGrip } = require("./rep-utils"); - - // Shortcuts - const { span } = React.DOM; - - /** - * Renders a grip object with regular expression. - */ - let RegExp = React.createClass({ - displayName: "regexp", - - propTypes: { - object: React.PropTypes.object.isRequired, - }, - - getSource: function (grip) { - return grip.displayString; - }, - - render: function () { - let grip = this.props.object; - let objectLink = this.props.objectLink || span; - - return ( - span({className: "objectBox objectBox-regexp"}, - objectLink({ - object: grip, - className: "regexpSource" - }, this.getSource(grip)) - ) - ); - }, - }); - - // Registration - - function supportsObject(object, type) { - if (!isGrip(object)) { - return false; - } - - return (type == "RegExp"); - } - - // Exports from this module - exports.RegExp = { - rep: RegExp, - supportsObject: supportsObject - }; -}); diff --git a/packages/devtools-modules/client/shared/components/reps/rep-utils.js b/packages/devtools-modules/client/shared/components/reps/rep-utils.js deleted file mode 100644 index d26996b64a..0000000000 --- a/packages/devtools-modules/client/shared/components/reps/rep-utils.js +++ /dev/null @@ -1,157 +0,0 @@ -/* globals URLSearchParams */ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -// Make this available to both AMD and CJS environments -define(function (require, exports, module) { - // Dependencies - const React = require("devtools/client/shared/vendor/react"); - - /** - * Create React factories for given arguments. - * Example: - * const { Rep } = createFactories(require("./rep")); - */ - function createFactories(args) { - let result = {}; - for (let p in args) { - result[p] = React.createFactory(args[p]); - } - return result; - } - - /** - * Returns true if the given object is a grip (see RDP protocol) - */ - function isGrip(object) { - return object && object.actor; - } - - function escapeNewLines(value) { - return value.replace(/\r/gm, "\\r").replace(/\n/gm, "\\n"); - } - - function cropMultipleLines(text, limit) { - return escapeNewLines(cropString(text, limit)); - } - - function cropString(text, limit, alternativeText) { - if (!alternativeText) { - alternativeText = "\u2026"; - } - - // Make sure it's a string. - text = text + ""; - - // Replace all non-printable characters, except of - // (horizontal) tab (HT: \x09) and newline (LF: \x0A, CR: \x0D), - // with unicode replacement character (u+fffd). - // eslint-disable-next-line no-control-regex - let re = new RegExp("[\x00-\x08\x0B\x0C\x0E-\x1F\x80-\x9F]", "g"); - text = text.replace(re, "\ufffd"); - - // Crop the string only if a limit is actually specified. - if (!limit || limit <= 0) { - return text; - } - - // Set the limit at least to the length of the alternative text - // plus one character of the original text. - if (limit <= alternativeText.length) { - limit = alternativeText.length + 1; - } - - let halfLimit = (limit - alternativeText.length) / 2; - - if (text.length > limit) { - return text.substr(0, Math.ceil(halfLimit)) + alternativeText + - text.substr(text.length - Math.floor(halfLimit)); - } - - return text; - } - - function parseURLParams(url) { - url = new URL(url); - return parseURLEncodedText(url.searchParams); - } - - function parseURLEncodedText(text) { - let params = []; - - // In case the text is empty just return the empty parameters - if (text == "") { - return params; - } - - let searchParams = new URLSearchParams(text); - let entries = [...searchParams.entries()]; - return entries.map(entry => { - return { - name: entry[0], - value: entry[1] - }; - }); - } - - function getFileName(url) { - let split = splitURLBase(url); - return split.name; - } - - function splitURLBase(url) { - if (!isDataURL(url)) { - return splitURLTrue(url); - } - return {}; - } - - function getURLDisplayString(url) { - return cropString(url); - } - - function isDataURL(url) { - return (url && url.substr(0, 5) == "data:"); - } - - function splitURLTrue(url) { - const reSplitFile = /(.*?):\/{2,3}([^\/]*)(.*?)([^\/]*?)($|\?.*)/; - let m = reSplitFile.exec(url); - - if (!m) { - return { - name: url, - path: url - }; - } else if (m[4] == "" && m[5] == "") { - return { - protocol: m[1], - domain: m[2], - path: m[3], - name: m[3] != "/" ? m[3] : m[2] - }; - } - - return { - protocol: m[1], - domain: m[2], - path: m[2] + m[3], - name: m[4] + m[5] - }; - } - - // Exports from this module - exports.createFactories = createFactories; - exports.isGrip = isGrip; - exports.cropString = cropString; - exports.cropMultipleLines = cropMultipleLines; - exports.parseURLParams = parseURLParams; - exports.parseURLEncodedText = parseURLEncodedText; - exports.getFileName = getFileName; - exports.getURLDisplayString = getURLDisplayString; -}); diff --git a/packages/devtools-modules/client/shared/components/reps/rep.js b/packages/devtools-modules/client/shared/components/reps/rep.js deleted file mode 100644 index 263b48e2ee..0000000000 --- a/packages/devtools-modules/client/shared/components/reps/rep.js +++ /dev/null @@ -1,132 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -// Make this available to both AMD and CJS environments -define(function (require, exports, module) { - // Dependencies - const React = require("devtools/client/shared/vendor/react"); - - const { isGrip } = require("./rep-utils"); - - // Load all existing rep templates - const { Undefined } = require("./undefined"); - const { Null } = require("./null"); - const { StringRep } = require("./string"); - const { Number } = require("./number"); - const { ArrayRep } = require("./array"); - const { Obj } = require("./object"); - const { SymbolRep } = require("./symbol"); - - // DOM types (grips) - const { Attribute } = require("./attribute"); - const { DateTime } = require("./date-time"); - const { Document } = require("./document"); - const { Event } = require("./event"); - const { Func } = require("./function"); - const { RegExp } = require("./regexp"); - const { StyleSheet } = require("./stylesheet"); - const { TextNode } = require("./text-node"); - const { Window } = require("./window"); - const { ObjectWithText } = require("./object-with-text"); - const { ObjectWithURL } = require("./object-with-url"); - const { GripArray } = require("./grip-array"); - const { GripMap } = require("./grip-map"); - const { Grip } = require("./grip"); - - // List of all registered template. - // XXX there should be a way for extensions to register a new - // or modify an existing rep. - let reps = [ - RegExp, - StyleSheet, - Event, - DateTime, - TextNode, - Attribute, - Func, - ArrayRep, - Document, - Window, - ObjectWithText, - ObjectWithURL, - GripArray, - GripMap, - Grip, - Undefined, - Null, - StringRep, - Number, - SymbolRep, - ]; - - /** - * Generic rep that is using for rendering native JS types or an object. - * The right template used for rendering is picked automatically according - * to the current value type. The value must be passed is as 'object' - * property. - */ - const Rep = React.createClass({ - displayName: "Rep", - - propTypes: { - object: React.PropTypes.any, - defaultRep: React.PropTypes.object, - mode: React.PropTypes.string - }, - - render: function () { - let rep = getRep(this.props.object, this.props.defaultRep); - return rep(this.props); - }, - }); - - // Helpers - - /** - * Return a rep object that is responsible for rendering given - * object. - * - * @param object {Object} Object to be rendered in the UI. This - * can be generic JS object as well as a grip (handle to a remote - * debuggee object). - * - * @param defaultObject {React.Component} The default template - * that should be used to render given object if none is found. - */ - function getRep(object, defaultRep = Obj) { - let type = typeof object; - if (type == "object" && object instanceof String) { - type = "string"; - } else if (type == "object" && object.type === "symbol") { - type = "symbol"; - } - - if (isGrip(object)) { - type = object.class; - } - - for (let i = 0; i < reps.length; i++) { - let rep = reps[i]; - try { - // supportsObject could return weight (not only true/false - // but a number), which would allow to priorities templates and - // support better extensibility. - if (rep.supportsObject(object, type)) { - return React.createFactory(rep.rep); - } - } catch (err) { - console.error(err); - } - } - - return React.createFactory(defaultRep.rep); - } - - // Exports from this module - exports.Rep = Rep; -}); diff --git a/packages/devtools-modules/client/shared/components/reps/reps.css b/packages/devtools-modules/client/shared/components/reps/reps.css deleted file mode 100644 index 2cfc80c69a..0000000000 --- a/packages/devtools-modules/client/shared/components/reps/reps.css +++ /dev/null @@ -1,181 +0,0 @@ -/* vim:set ts=2 sw=2 sts=2 et: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -.theme-dark, -.theme-light { - --number-color: var(--theme-highlight-green); - --string-color: var(--theme-highlight-orange); - --null-color: var(--theme-comment); - --object-color: var(--theme-body-color); - --caption-color: var(--theme-highlight-blue); - --location-color: var(--theme-content-color1); - --source-link-color: var(--theme-highlight-blue); - --node-color: var(--theme-highlight-bluegrey); - --reference-color: var(--theme-highlight-purple); -} - -.theme-firebug { - --number-color: #000088; - --string-color: #FF0000; - --null-color: #787878; - --object-color: DarkGreen; - --caption-color: #444444; - --location-color: #555555; - --source-link-color: blue; - --node-color: rgb(0, 0, 136); - --reference-color: rgb(102, 102, 255); -} - -/******************************************************************************/ - -.objectLink:hover { - cursor: pointer; - text-decoration: underline; -} - -.inline { - display: inline; - white-space: normal; -} - -.objectBox-object { - font-weight: bold; - color: var(--object-color); - white-space: pre-wrap; -} - -.objectBox-string, -.objectBox-text, -.objectLink-textNode, -.objectBox-table { - white-space: pre-wrap; -} - -.objectBox-number, -.objectLink-styleRule, -.objectLink-element, -.objectLink-textNode, -.objectBox-array > .length { - color: var(--number-color); -} - -.objectBox-string { - color: var(--string-color); -} - -.objectLink-function, -.objectBox-stackTrace, -.objectLink-profile { - color: var(--object-color); -} - -.objectLink-Location { - font-style: italic; - color: var(--location-color); -} - -.objectBox-null, -.objectBox-undefined, -.objectBox-hint, -.logRowHint { - font-style: italic; - color: var(--null-color); -} - -.objectLink-sourceLink { - position: absolute; - right: 4px; - top: 2px; - padding-left: 8px; - font-weight: bold; - color: var(--source-link-color); -} - -/******************************************************************************/ - -.objectLink-event, -.objectLink-eventLog, -.objectLink-regexp, -.objectLink-object, -.objectLink-Date { - font-weight: bold; - color: var(--object-color); - white-space: pre-wrap; -} - -/******************************************************************************/ - -.objectLink-object .nodeName, -.objectLink-NamedNodeMap .nodeName, -.objectLink-NamedNodeMap .objectEqual, -.objectLink-NamedNodeMap .arrayLeftBracket, -.objectLink-NamedNodeMap .arrayRightBracket, -.objectLink-Attr .attrEqual, -.objectLink-Attr .attrTitle { - color: var(--node-color); -} - -.objectLink-object .nodeName { - font-weight: normal; -} - -/******************************************************************************/ - -.objectLeftBrace, -.objectRightBrace, -.arrayLeftBracket, -.arrayRightBracket { - cursor: pointer; - font-weight: bold; -} - -.objectLeftBrace, -.arrayLeftBracket { - margin-right: 4px; -} - -.objectRightBrace, -.arrayRightBracket { - margin-left: 4px; -} - -/******************************************************************************/ -/* Cycle reference*/ - -.objectLink-Reference { - font-weight: bold; - color: var(--reference-color); -} - -.objectBox-array > .objectTitle { - font-weight: bold; - color: var(--object-color); -} - -.caption { - font-weight: bold; - color: var(--caption-color); -} - -/******************************************************************************/ -/* Themes */ - -.theme-dark .objectBox-null, -.theme-dark .objectBox-undefined, -.theme-light .objectBox-null, -.theme-light .objectBox-undefined { - font-style: normal; -} - -.theme-dark .objectBox-object, -.theme-light .objectBox-object { - font-weight: normal; - white-space: pre-wrap; -} - -.theme-dark .caption, -.theme-light .caption { - font-weight: normal; -} diff --git a/packages/devtools-modules/client/shared/components/reps/string.js b/packages/devtools-modules/client/shared/components/reps/string.js deleted file mode 100644 index beb15b1273..0000000000 --- a/packages/devtools-modules/client/shared/components/reps/string.js +++ /dev/null @@ -1,68 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -// Make this available to both AMD and CJS environments -define(function (require, exports, module) { - // Dependencies - const React = require("devtools/client/shared/vendor/react"); - const { cropMultipleLines } = require("./rep-utils"); - - // Shortcuts - const { span } = React.DOM; - - /** - * Renders a string. String value is enclosed within quotes. - */ - const StringRep = React.createClass({ - displayName: "StringRep", - - propTypes: { - useQuotes: React.PropTypes.bool, - }, - - getDefaultProps: function () { - return { - useQuotes: true, - }; - }, - - render: function () { - let text = this.props.object; - let member = this.props.member; - if (member && member.open) { - return ( - span({className: "objectBox objectBox-string"}, - "\"" + text + "\"" - ) - ); - } - - let croppedString = this.props.cropLimit ? - cropMultipleLines(text, this.props.cropLimit) : cropMultipleLines(text); - - let formattedString = this.props.useQuotes ? - "\"" + croppedString + "\"" : croppedString; - - return ( - span({className: "objectBox objectBox-string"}, formattedString - ) - ); - }, - }); - - function supportsObject(object, type) { - return (type == "string"); - } - - // Exports from this module - - exports.StringRep = { - rep: StringRep, - supportsObject: supportsObject, - }; -}); diff --git a/packages/devtools-modules/client/shared/components/reps/stylesheet.js b/packages/devtools-modules/client/shared/components/reps/stylesheet.js deleted file mode 100644 index c1fc7f1be2..0000000000 --- a/packages/devtools-modules/client/shared/components/reps/stylesheet.js +++ /dev/null @@ -1,77 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -"use strict"; - -// Make this available to both AMD and CJS environments -define(function (require, exports, module) { - // ReactJS - const React = require("devtools/client/shared/vendor/react"); - - // Reps - const { isGrip, getURLDisplayString } = require("./rep-utils"); - - // Shortcuts - const DOM = React.DOM; - - /** - * Renders a grip representing CSSStyleSheet - */ - let StyleSheet = React.createClass({ - displayName: "object", - - propTypes: { - object: React.PropTypes.object.isRequired, - }, - - getTitle: function (grip) { - let title = "StyleSheet "; - if (this.props.objectLink) { - return DOM.span({className: "objectBox"}, - this.props.objectLink({ - object: grip - }, title) - ); - } - return title; - }, - - getLocation: function (grip) { - // Embedded stylesheets don't have URL and so, no preview. - let url = grip.preview ? grip.preview.url : ""; - return url ? getURLDisplayString(url) : ""; - }, - - render: function () { - let grip = this.props.object; - - return ( - DOM.span({className: "objectBox objectBox-object"}, - this.getTitle(grip), - DOM.span({className: "objectPropValue"}, - this.getLocation(grip) - ) - ) - ); - }, - }); - - // Registration - - function supportsObject(object, type) { - if (!isGrip(object)) { - return false; - } - - return (type == "CSSStyleSheet"); - } - - // Exports from this module - - exports.StyleSheet = { - rep: StyleSheet, - supportsObject: supportsObject - }; -}); diff --git a/packages/devtools-modules/client/shared/components/reps/symbol.js b/packages/devtools-modules/client/shared/components/reps/symbol.js deleted file mode 100644 index 1117940089..0000000000 --- a/packages/devtools-modules/client/shared/components/reps/symbol.js +++ /dev/null @@ -1,48 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -// Make this available to both AMD and CJS environments -define(function (require, exports, module) { - // Dependencies - const React = require("devtools/client/shared/vendor/react"); - - // Shortcuts - const { span } = React.DOM; - - /** - * Renders a symbol. - */ - const SymbolRep = React.createClass({ - displayName: "SymbolRep", - - propTypes: { - object: React.PropTypes.object.isRequired - }, - - render: function () { - let {object} = this.props; - let {name} = object; - - return ( - span({className: "objectBox objectBox-symbol"}, - `Symbol(${name || ""})` - ) - ); - }, - }); - - function supportsObject(object, type) { - return (type == "symbol"); - } - - // Exports from this module - exports.SymbolRep = { - rep: SymbolRep, - supportsObject: supportsObject, - }; -}); diff --git a/packages/devtools-modules/client/shared/components/reps/text-node.js b/packages/devtools-modules/client/shared/components/reps/text-node.js deleted file mode 100644 index 0b88d122b0..0000000000 --- a/packages/devtools-modules/client/shared/components/reps/text-node.js +++ /dev/null @@ -1,92 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -"use strict"; - -// Make this available to both AMD and CJS environments -define(function (require, exports, module) { - // ReactJS - const React = require("devtools/client/shared/vendor/react"); - - // Reps - const { isGrip, cropMultipleLines } = require("./rep-utils"); - - // Shortcuts - const DOM = React.DOM; - - /** - * Renders DOM #text node. - */ - let TextNode = React.createClass({ - displayName: "TextNode", - - propTypes: { - object: React.PropTypes.object.isRequired, - mode: React.PropTypes.string, - }, - - getTextContent: function (grip) { - return cropMultipleLines(grip.preview.textContent); - }, - - getTitle: function (grip) { - if (this.props.objectLink) { - return this.props.objectLink({ - object: grip - }, "#text"); - } - return ""; - }, - - render: function () { - let grip = this.props.object; - let mode = this.props.mode || "short"; - - if (mode == "short" || mode == "tiny") { - return ( - DOM.span({className: "objectBox objectBox-textNode"}, - this.getTitle(grip), - "\"" + this.getTextContent(grip) + "\"" - ) - ); - } - - let objectLink = this.props.objectLink || DOM.span; - return ( - DOM.span({className: "objectBox objectBox-textNode"}, - this.getTitle(grip), - objectLink({ - object: grip - }, "<"), - DOM.span({className: "nodeTag"}, "TextNode"), - " textContent=\"", - DOM.span({className: "nodeValue"}, - this.getTextContent(grip) - ), - "\"", - objectLink({ - object: grip - }, ">;") - ) - ); - }, - }); - - // Registration - - function supportsObject(grip, type) { - if (!isGrip(grip)) { - return false; - } - - return (grip.preview && grip.class == "Text"); - } - - // Exports from this module - exports.TextNode = { - rep: TextNode, - supportsObject: supportsObject - }; -}); diff --git a/packages/devtools-modules/client/shared/components/reps/undefined.js b/packages/devtools-modules/client/shared/components/reps/undefined.js deleted file mode 100644 index c4e64a12cc..0000000000 --- a/packages/devtools-modules/client/shared/components/reps/undefined.js +++ /dev/null @@ -1,46 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -// Make this available to both AMD and CJS environments -define(function (require, exports, module) { - // Dependencies - const React = require("devtools/client/shared/vendor/react"); - - // Shortcuts - const { span } = React.DOM; - - /** - * Renders undefined value - */ - const Undefined = React.createClass({ - displayName: "UndefinedRep", - - render: function () { - return ( - span({className: "objectBox objectBox-undefined"}, - "undefined" - ) - ); - }, - }); - - function supportsObject(object, type) { - if (object && object.type && object.type == "undefined") { - return true; - } - - return (type == "undefined"); - } - - // Exports from this module - - exports.Undefined = { - rep: Undefined, - supportsObject: supportsObject - }; -}); diff --git a/packages/devtools-modules/client/shared/components/reps/window.js b/packages/devtools-modules/client/shared/components/reps/window.js deleted file mode 100644 index 634242cfb8..0000000000 --- a/packages/devtools-modules/client/shared/components/reps/window.js +++ /dev/null @@ -1,82 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -"use strict"; - -// Make this available to both AMD and CJS environments -define(function (require, exports, module) { - // ReactJS - const React = require("devtools/client/shared/vendor/react"); - - // Reps - const { isGrip, getURLDisplayString } = require("./rep-utils"); - - // Shortcuts - const DOM = React.DOM; - - /** - * Renders a grip representing a window. - */ - let Window = React.createClass({ - displayName: "Window", - - propTypes: { - object: React.PropTypes.object.isRequired, - mode: React.PropTypes.string - }, - - getTitle: function (grip) { - if (this.props.objectLink) { - return DOM.span({className: "objectBox"}, - this.props.objectLink({ - object: grip - }, grip.class + " ") - ); - } - return ""; - }, - - getLocation: function (grip) { - return getURLDisplayString(grip.preview.url); - }, - - getDisplayValue: function (grip) { - if (this.props.mode === "tiny") { - return grip.isGlobal ? "Global" : "Window"; - } else { - return this.getLocation(grip); - } - }, - - render: function () { - let grip = this.props.object; - - return ( - DOM.span({className: "objectBox objectBox-Window"}, - this.getTitle(grip), - DOM.span({className: "objectPropValue"}, - this.getDisplayValue(grip) - ) - ) - ); - }, - }); - - // Registration - - function supportsObject(object, type) { - if (!isGrip(object)) { - return false; - } - - return (object.preview && type == "Window"); - } - - // Exports from this module - exports.Window = { - rep: Window, - supportsObject: supportsObject - }; -}); diff --git a/packages/devtools-modules/client/shared/components/splitter/Draggable.js b/packages/devtools-modules/client/shared/components/splitter/Draggable.js deleted file mode 100644 index 77f4058b45..0000000000 --- a/packages/devtools-modules/client/shared/components/splitter/Draggable.js +++ /dev/null @@ -1,52 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -const React = require("devtools/client/shared/vendor/react"); -const ReactDOM = require("devtools/client/shared/vendor/react-dom"); -const { DOM: dom, PropTypes } = React; - -const Draggable = React.createClass({ - displayName: "Draggable", - - propTypes: { - onMove: PropTypes.func.isRequired, - onStart: PropTypes.func, - onStop: PropTypes.func, - style: PropTypes.object, - className: PropTypes.string - }, - - startDragging(ev) { - ev.preventDefault(); - const doc = ReactDOM.findDOMNode(this).ownerDocument; - doc.addEventListener("mousemove", this.onMove); - doc.addEventListener("mouseup", this.onUp); - this.props.onStart && this.props.onStart(); - }, - - onMove(ev) { - ev.preventDefault(); - // Use screen coordinates so, moving mouse over iframes - // doesn't mangle (relative) coordinates. - this.props.onMove(ev.screenX, ev.screenY); - }, - - onUp(ev) { - ev.preventDefault(); - const doc = ReactDOM.findDOMNode(this).ownerDocument; - doc.removeEventListener("mousemove", this.onMove); - doc.removeEventListener("mouseup", this.onUp); - this.props.onStop && this.props.onStop(); - }, - - render() { - return dom.div({ - style: this.props.style, - className: this.props.className, - onMouseDown: this.startDragging - }); - } -}); - -module.exports = Draggable; diff --git a/packages/devtools-modules/client/shared/components/splitter/SplitBox.css b/packages/devtools-modules/client/shared/components/splitter/SplitBox.css deleted file mode 100644 index 5a91c6fbcc..0000000000 --- a/packages/devtools-modules/client/shared/components/splitter/SplitBox.css +++ /dev/null @@ -1,88 +0,0 @@ -/* vim:set ts=2 sw=2 sts=2 et: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -.split-box { - display: flex; - flex: 1; - min-width: 0; - height: 100%; - width: 100%; -} - -.split-box.vert { - flex-direction: row; -} - -.split-box.horz { - flex-direction: column; -} - -.split-box > .uncontrolled { - display: flex; - flex: 1; - min-width: 0; - overflow: auto; -} - -.split-box > .controlled { - display: flex; - overflow: auto; -} - -.split-box > .splitter { - background-image: none; - border: 0; - border-style: solid; - border-color: transparent; - background-color: var(--theme-splitter-color); - background-clip: content-box; - position: relative; - - box-sizing: border-box; - - /* Positive z-index positions the splitter on top of its siblings and makes - it clickable on both sides. */ - z-index: 1; -} - -.split-box.vert > .splitter { - min-width: calc(var(--devtools-splitter-inline-start-width) + - var(--devtools-splitter-inline-end-width) + 1px); - - border-left-width: var(--devtools-splitter-inline-start-width); - border-right-width: var(--devtools-splitter-inline-end-width); - - margin-left: calc(-1 * var(--devtools-splitter-inline-start-width) - 1px); - margin-right: calc(-1 * var(--devtools-splitter-inline-end-width)); - - cursor: ew-resize; -} - -.split-box.horz > .splitter { - min-height: calc(var(--devtools-splitter-top-width) + - var(--devtools-splitter-bottom-width) + 1px); - - border-top-width: var(--devtools-splitter-top-width); - border-bottom-width: var(--devtools-splitter-bottom-width); - - margin-top: calc(-1 * var(--devtools-splitter-top-width) - 1px); - margin-bottom: calc(-1 * var(--devtools-splitter-bottom-width)); - - cursor: ns-resize; -} - -.split-box.disabled { - pointer-events: none; -} - -/** - * Make sure splitter panels are not processing any mouse - * events. This is good for performance during splitter - * bar dragging. - */ -.split-box.dragging > .controlled, -.split-box.dragging > .uncontrolled { - pointer-events: none; -} diff --git a/packages/devtools-modules/client/shared/components/splitter/SplitBox.js b/packages/devtools-modules/client/shared/components/splitter/SplitBox.js deleted file mode 100644 index c046762dab..0000000000 --- a/packages/devtools-modules/client/shared/components/splitter/SplitBox.js +++ /dev/null @@ -1,220 +0,0 @@ -const React = require("devtools/client/shared/vendor/react"); -const ReactDOM = require("devtools/client/shared/vendor/react-dom"); -const Draggable = React.createFactory( - require("./Draggable")); -const { DOM: dom, PropTypes } = React; - -/** - * This component represents a Splitter. The splitter supports vertical - * as well as horizontal mode. - */ -const SplitBox = React.createClass({ - - propTypes: { - // Custom class name. You can use more names separated by a space. - className: PropTypes.string, - // Initial size of controlled panel. - initialSize: PropTypes.any, - // Optional initial width of controlled panel. - initialWidth: PropTypes.number, - // Optional initial height of controlled panel. - initialHeight: PropTypes.number, - // Left/top panel - startPanel: PropTypes.any, - // Min panel size. - minSize: PropTypes.any, - // Max panel size. - maxSize: PropTypes.any, - // Right/bottom panel - endPanel: PropTypes.any, - // True if the right/bottom panel should be controlled. - endPanelControl: PropTypes.bool, - // Size of the splitter handle bar. - splitterSize: PropTypes.number, - // True if the splitter bar is vertical (default is vertical). - vert: PropTypes.bool, - // Optional style properties passed into the splitbox - style: PropTypes.object - }, - - displayName: "SplitBox", - - getDefaultProps() { - return { - splitterSize: 5, - vert: true, - endPanelControl: false - }; - }, - - /** - * The state stores the current orientation (vertical or horizontal) - * and the current size (width/height). All these values can change - * during the component's life time. - */ - getInitialState() { - return { - vert: this.props.vert, - width: this.props.initialWidth || this.props.initialSize, - height: this.props.initialHeight || this.props.initialSize - }; - }, - - // Dragging Events - - /** - * Set 'resizing' cursor on entire document during splitter dragging. - * This avoids cursor-flickering that happens when the mouse leaves - * the splitter bar area (happens frequently). - */ - onStartMove() { - const splitBox = ReactDOM.findDOMNode(this); - const doc = splitBox.ownerDocument; - let defaultCursor = doc.documentElement.style.cursor; - doc.documentElement.style.cursor = - (this.state.vert ? "ew-resize" : "ns-resize"); - - splitBox.classList.add("dragging"); - - this.setState({ - defaultCursor: defaultCursor - }); - }, - - onStopMove() { - const splitBox = ReactDOM.findDOMNode(this); - const doc = splitBox.ownerDocument; - doc.documentElement.style.cursor = this.state.defaultCursor; - - splitBox.classList.remove("dragging"); - }, - - screenX() { - const borderWidth = (window.outerWidth - window.innerWidth) / 2; - return window.screenX + borderWidth; - }, - - screenY() { - const borderHeignt = (window.outerHeight - window.innerHeight); - return window.screenY + borderHeignt; - }, - - /** - * Adjust size of the controlled panel. Depending on the current - * orientation we either remember the width or height of - * the splitter box. - */ - onMove(x, y) { - const node = ReactDOM.findDOMNode(this); - const doc = node.ownerDocument; - const win = doc.defaultView; - - let size; - let { endPanelControl } = this.props; - - if (this.state.vert) { - // Switch the control flag in case of RTL. Note that RTL - // has impact on vertical splitter only. - let dir = win.getComputedStyle(doc.documentElement).direction; - if (dir == "rtl") { - endPanelControl = !endPanelControl; - } - - let innerOffset = x - this.screenX(); - size = endPanelControl ? - (node.offsetLeft + node.offsetWidth) - innerOffset : - innerOffset - node.offsetLeft; - - this.setState({ - width: size - }); - } else { - let innerOffset = y - this.screenY(); - size = endPanelControl ? - (node.offsetTop + node.offsetHeight) - innerOffset : - innerOffset - node.offsetTop; - - this.setState({ - height: size - }); - } - }, - - // Rendering - - render() { - const vert = this.state.vert; - const { startPanel, endPanel, endPanelControl, minSize, - maxSize, splitterSize } = this.props; - - let style = Object.assign({}, this.props.style); - - // Calculate class names list. - let classNames = ["split-box"]; - classNames.push(vert ? "vert" : "horz"); - if (this.props.className) { - classNames = classNames.concat(this.props.className.split(" ")); - } - - let leftPanelStyle; - let rightPanelStyle; - - // Set proper size for panels depending on the current state. - if (vert) { - leftPanelStyle = { - maxWidth: endPanelControl ? null : maxSize, - minWidth: endPanelControl ? null : minSize, - width: endPanelControl ? null : this.state.width - }; - rightPanelStyle = { - maxWidth: endPanelControl ? maxSize : null, - minWidth: endPanelControl ? minSize : null, - width: endPanelControl ? this.state.width : null - }; - } else { - leftPanelStyle = { - maxHeight: endPanelControl ? null : maxSize, - minHeight: endPanelControl ? null : minSize, - height: endPanelControl ? null : this.state.height - }; - rightPanelStyle = { - maxHeight: endPanelControl ? maxSize : null, - minHeight: endPanelControl ? minSize : null, - height: endPanelControl ? this.state.height : null - }; - } - - // Calculate splitter size - let splitterStyle = { - flex: "0 0 " + splitterSize + "px" - }; - - return ( - dom.div({ - className: classNames.join(" "), - style: style }, - startPanel ? - dom.div({ - className: endPanelControl ? "uncontrolled" : "controlled", - style: leftPanelStyle }, - startPanel - ) : null, - Draggable({ - className: "splitter", - style: splitterStyle, - onStart: this.onStartMove, - onStop: this.onStopMove, - onMove: this.onMove - }), - endPanel ? - dom.div({ - className: endPanelControl ? "controlled" : "uncontrolled", - style: rightPanelStyle }, - endPanel - ) : null - ) - ); - } -}); - -module.exports = SplitBox; diff --git a/packages/devtools-modules/client/shared/shim/Services.js b/packages/devtools-modules/client/shared/shim/Services.js deleted file mode 100644 index 6b01c6134b..0000000000 --- a/packages/devtools-modules/client/shared/shim/Services.js +++ /dev/null @@ -1,601 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - - -/* globals localStorage, window, document, NodeFilter */ - -// Some constants from nsIPrefBranch.idl. -const PREF_INVALID = 0; -const PREF_STRING = 32; -const PREF_INT = 64; -const PREF_BOOL = 128; -const NS_PREFBRANCH_PREFCHANGE_TOPIC_ID = "nsPref:changed"; - -// We prefix all our local storage items with this. -const PREFIX = "Services.prefs:"; - -/** - * Create a new preference branch. This object conforms largely to - * nsIPrefBranch and nsIPrefService, though it only implements the - * subset needed by devtools. A preference branch can hold child - * preferences while also holding a preference value itself. - * - * @param {PrefBranch} parent the parent branch, or null for the root - * branch. - * @param {String} name the base name of this branch - * @param {String} fullName the fully-qualified name of this branch - */ -function PrefBranch(parent, name, fullName) { - this._parent = parent; - this._name = name; - this._fullName = fullName; - this._observers = {}; - this._children = {}; - - // Properties used when this branch has a value as well. - this._defaultValue = null; - this._hasUserValue = false; - this._userValue = null; - this._type = PREF_INVALID; -} - -PrefBranch.prototype = { - PREF_INVALID: PREF_INVALID, - PREF_STRING: PREF_STRING, - PREF_INT: PREF_INT, - PREF_BOOL: PREF_BOOL, - - /** @see nsIPrefBranch.root. */ - get root() { - return this._fullName; - }, - - /** @see nsIPrefBranch.getPrefType. */ - getPrefType: function(prefName) { - return this._findPref(prefName)._type; - }, - - /** @see nsIPrefBranch.getBoolPref. */ - getBoolPref: function(prefName) { - let thePref = this._findPref(prefName); - if (thePref._type !== PREF_BOOL) { - throw new Error(`${prefName} does not have bool type`); - } - return thePref._get(); - }, - - /** @see nsIPrefBranch.setBoolPref. */ - setBoolPref: function(prefName, value) { - if (typeof value !== "boolean") { - throw new Error("non-bool passed to setBoolPref"); - } - let thePref = this._findOrCreatePref(prefName, value, true, value); - if (thePref._type !== PREF_BOOL) { - throw new Error(`${prefName} does not have bool type`); - } - thePref._set(value); - }, - - /** @see nsIPrefBranch.getCharPref. */ - getCharPref: function(prefName) { - let thePref = this._findPref(prefName); - if (thePref._type !== PREF_STRING) { - throw new Error(`${prefName} does not have string type`); - } - return thePref._get(); - }, - - /** @see nsIPrefBranch.setCharPref. */ - setCharPref: function(prefName, value) { - if (typeof value !== "string") { - throw new Error("non-string passed to setCharPref"); - } - let thePref = this._findOrCreatePref(prefName, value, true, value); - if (thePref._type !== PREF_STRING) { - throw new Error(`${prefName} does not have string type`); - } - thePref._set(value); - }, - - /** @see nsIPrefBranch.getIntPref. */ - getIntPref: function(prefName) { - let thePref = this._findPref(prefName); - if (thePref._type !== PREF_INT) { - throw new Error(`${prefName} does not have int type`); - } - return thePref._get(); - }, - - /** @see nsIPrefBranch.setIntPref. */ - setIntPref: function(prefName, value) { - if (typeof value !== "number") { - throw new Error("non-number passed to setIntPref"); - } - let thePref = this._findOrCreatePref(prefName, value, true, value); - if (thePref._type !== PREF_INT) { - throw new Error(`${prefName} does not have int type`); - } - thePref._set(value); - }, - - /** @see nsIPrefBranch.clearUserPref */ - clearUserPref: function(prefName) { - let thePref = this._findPref(prefName); - thePref._clearUserValue(); - }, - - /** @see nsIPrefBranch.prefHasUserValue */ - prefHasUserValue: function(prefName) { - let thePref = this._findPref(prefName); - return thePref._hasUserValue; - }, - - /** @see nsIPrefBranch.addObserver */ - addObserver: function(domain, observer, holdWeak) { - if (holdWeak) { - throw new Error("shim prefs only supports strong observers"); - } - - if (!(domain in this._observers)) { - this._observers[domain] = []; - } - this._observers[domain].push(observer); - }, - - /** @see nsIPrefBranch.removeObserver */ - removeObserver: function(domain, observer) { - if (!(domain in this._observers)) { - return; - } - let index = this._observers[domain].indexOf(observer); - if (index >= 0) { - this._observers[domain].splice(index, 1); - } - }, - - /** @see nsIPrefService.savePrefFile */ - savePrefFile: function(file) { - if (file) { - throw new Error("shim prefs only supports null file in savePrefFile"); - } - // Nothing to do - this implementation always writes back. - }, - - /** @see nsIPrefService.getBranch */ - getBranch: function(prefRoot) { - if (!prefRoot) { - return this; - } - if (prefRoot.endsWith(".")) { - prefRoot = prefRoot.slice(0, -1); - } - // This is a bit weird since it could erroneously return a pref, - // not a pref branch. - return this._findPref(prefRoot); - }, - - /** - * Return this preference's current value. - * - * @return {Any} The current value of this preference. This may - * return a string, a number, or a boolean depending on the - * preference's type. - */ - _get: function() { - if (this._hasUserValue) { - return this._userValue; - } - return this._defaultValue; - }, - - /** - * Set the preference's value. The new value is assumed to be a - * user value. After setting the value, this function emits a - * change notification. - * - * @param {Any} value the new value - */ - _set: function(value) { - if (!this._hasUserValue || value !== this._userValue) { - this._userValue = value; - this._hasUserValue = true; - this._saveAndNotify(); - } - }, - - /** - * Set the default value for this preference, and emit a - * notification if this results in a visible change. - * - * @param {Any} value the new default value - */ - _setDefault: function(value) { - if (this._defaultValue !== value) { - this._defaultValue = value; - if (!this._hasUserValue) { - this._saveAndNotify(); - } - } - }, - - /** - * If this preference has a user value, clear it. If a change was - * made, emit a change notification. - */ - _clearUserValue: function() { - if (this._hasUserValue) { - this._userValue = null; - this._hasUserValue = false; - this._saveAndNotify(); - } - }, - - /** - * Helper function to write the preference's value to local storage - * and then emit a change notification. - */ - _saveAndNotify: function() { - let store = { - type: this._type, - defaultValue: this._defaultValue, - hasUserValue: this._hasUserValue, - userValue: this._userValue, - }; - - localStorage.setItem(PREFIX + this.fullName, JSON.stringify(store)); - this._parent._notify(this._name); - }, - - /** - * Change this preference's value without writing it back to local - * storage. This is used to handle changes to local storage that - * were made externally. - * - * @param {Number} type one of the PREF_* values - * @param {Any} userValue the user value to use if the pref does not exist - * @param {Any} defaultValue the default value to use if the pref - * does not exist - * @param {Boolean} hasUserValue if a new pref is created, whether - * the default value is also a user value - * @param {Object} store the new value of the preference. It should - * be of the form {type, defaultValue, hasUserValue, userValue}; - * where |type| is one of the PREF_* type constants; |defaultValue| - * and |userValue| are the default and user values, respectively; - * and |hasUserValue| is a boolean indicating whether the user value - * is valid - */ - _storageUpdated: function(type, userValue, hasUserValue, defaultValue) { - this._type = type; - this._defaultValue = defaultValue; - this._hasUserValue = hasUserValue; - this._userValue = userValue; - // There's no need to write this back to local storage, since it - // came from there; and this avoids infinite event loops. - this._parent._notify(this._name); - }, - - /** - * Helper function to find either a Preference or PrefBranch object - * given its name. If the name is not found, throws an exception. - * - * @param {String} prefName the fully-qualified preference name - * @return {Object} Either a Preference or PrefBranch object - */ - _findPref: function(prefName) { - let branchNames = prefName.split("."); - let branch = this; - - for (let branchName of branchNames) { - branch = branch._children[branchName]; - if (!branch) { - throw new Error("could not find pref branch " + prefName); - } - } - - return branch; - }, - - /** - * Helper function to notify any observers when a preference has - * changed. This will also notify the parent branch for further - * reporting. - * - * @param {String} relativeName the name of the updated pref, - * relative to this branch - */ - _notify: function(relativeName) { - for (let domain in this._observers) { - if (relativeName === domain || domain === "" || - (domain.endsWith(".") && relativeName.startsWith(domain))) { - // Allow mutation while walking. - let localList = this._observers[domain].slice(); - for (let observer of localList) { - try { - observer.observe(this, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID, - relativeName); - } catch (e) { - console.error(e); - } - } - } - } - - if (this._parent) { - this._parent._notify(this._name + "." + relativeName); - } - }, - - /** - * Helper function to create a branch given an array of branch names - * representing the path of the new branch. - * - * @param {Array} branchList an array of strings, one per component - * of the branch to be created - * @return {PrefBranch} the new branch - */ - _createBranch: function(branchList) { - let parent = this; - for (let branch of branchList) { - if (!parent._children[branch]) { - parent._children[branch] = new PrefBranch(parent, branch, - parent.root + "." + branch); - } - parent = parent._children[branch]; - } - return parent; - }, - - /** - * Create a new preference. The new preference is assumed to be in - * local storage already, and the new value is taken from there. - * - * @param {String} keyName the full-qualified name of the preference. - * This is also the name of the key in local storage. - * @param {Any} userValue the user value to use if the pref does not exist - * @param {Any} defaultValue the default value to use if the pref - * does not exist - * @param {Boolean} hasUserValue if a new pref is created, whether - * the default value is also a user value - */ - _findOrCreatePref: function(keyName, userValue, hasUserValue, defaultValue) { - let branch = this._createBranch(keyName.split(".")); - - if (hasUserValue && typeof (userValue) !== typeof (defaultValue)) { - throw new Error("inconsistent values when creating " + keyName); - } - - let type; - switch (typeof (defaultValue)) { - case "boolean": - type = PREF_BOOL; - break; - case "number": - type = PREF_INT; - break; - case "string": - type = PREF_STRING; - break; - default: - throw new Error("unhandled argument type: " + typeof (defaultValue)); - } - - if (branch._type === PREF_INVALID) { - branch._storageUpdated(type, userValue, hasUserValue, defaultValue); - } else if (branch._type !== type) { - throw new Error("attempt to change type of pref " + keyName); - } - - return branch; - }, - - /** - * Helper function that is called when local storage changes. This - * updates the preferences and notifies pref observers as needed. - * - * @param {StorageEvent} event the event representing the local - * storage change - */ - _onStorageChange: function(event) { - if (event.storageArea !== localStorage) { - return; - } - // Ignore delete events. Not clear what's correct. - if (event.key === null || event.newValue === null) { - return; - } - - let { type, userValue, hasUserValue, defaultValue } = - JSON.parse(event.newValue); - if (event.oldValue === null) { - this._findOrCreatePref(event.key, userValue, hasUserValue, defaultValue); - } else { - let thePref = this._findPref(event.key); - thePref._storageUpdated(type, userValue, hasUserValue, defaultValue); - } - }, - - /** - * Helper function to initialize the root PrefBranch. - */ - _initializeRoot: function() { - if (localStorage.length === 0 && Services._defaultPrefsEnabled) { - /* eslint-disable no-eval */ - // let devtools = require("raw!prefs!devtools/client/preferences/devtools"); - // eval(devtools); - // let all = require("raw!prefs!modules/libpref/init/all"); - // eval(all); - /* eslint-enable no-eval */ - } - - // Read the prefs from local storage and create the local - // representations. - for (let i = 0; i < localStorage.length; ++i) { - let keyName = localStorage.key(i); - if (keyName.startsWith(PREFIX)) { - let { userValue, hasUserValue, defaultValue } = - JSON.parse(localStorage.getItem(keyName)); - this._findOrCreatePref(keyName.slice(PREFIX.length), userValue, - hasUserValue, defaultValue); - } - } - - this._onStorageChange = this._onStorageChange.bind(this); - window.addEventListener("storage", this._onStorageChange); - }, -}; - -const Services = { - _prefs: null, - - // For use by tests. If set to false before Services.prefs is used, - // this will disable the reading of the default prefs. - _defaultPrefsEnabled: true, - - /** - * An implementation of nsIPrefService that is based on local - * storage. Only the subset of nsIPrefService that is actually used - * by devtools is implemented here. This is lazily instantiated so - * that the tests have a chance to disable the loading of default - * prefs. - */ - get prefs() { - if (!this._prefs) { - this._prefs = new PrefBranch(null, "", ""); - this._prefs._initializeRoot(); - } - return this._prefs; - }, - - /** - * An implementation of Services.appinfo that holds just the - * properties needed by devtools. - */ - appinfo: { - get OS() { - if (typeof window == "undefined") { - return "Unknown"; - } - const os = window.navigator.userAgent; - if (os) { - if (os.includes("Linux")) { - return "Linux"; - } else if (os.includes("Windows")) { - return "WINNT"; - } else if (os.includes("Mac")) { - return "Darwin"; - } - } - return "Unknown"; - }, - - // It's fine for this to be an approximation. - get name() { - return window.navigator.userAgent; - }, - - // It's fine for this to be an approximation. - get version() { - return window.navigator.appVersion; - }, - - // This is only used by telemetry, which is disabled for the - // content case. So, being totally wrong is ok. - get is64Bit() { - return true; - }, - }, - - /** - * A no-op implementation of Services.telemetry. This supports just - * the subset of Services.telemetry that is used by devtools. - */ - telemetry: { - getHistogramById: function(name) { - return { - add: () => {} - }; - }, - - getKeyedHistogramById: function(name) { - return { - add: () => {} - }; - }, - }, - - /** - * An implementation of Services.focus that holds just the - * properties and methods needed by devtools. - * @see nsIFocusManager.idl for details. - */ - focus: { - // These values match nsIFocusManager in order to make testing a - // bit simpler. - MOVEFOCUS_FORWARD: 1, - MOVEFOCUS_BACKWARD: 2, - - get focusedElement() { - if (!document.hasFocus()) { - return null; - } - return document.activeElement; - }, - - moveFocus: function(window, startElement, type, flags) { - if (flags !== 0) { - throw new Error("shim Services.focus.moveFocus only accepts flags===0"); - } - if (type !== Services.focus.MOVEFOCUS_FORWARD - && type !== Services.focus.MOVEFOCUS_BACKWARD) { - throw new Error("shim Services.focus.moveFocus only supports " + - " MOVEFOCUS_FORWARD and MOVEFOCUS_BACKWARD"); - } - - if (!startElement) { - startElement = document.activeElement || document; - } - - let iter = document.createTreeWalker(document, NodeFilter.SHOW_ELEMENT, { - acceptNode: function(node) { - let tabIndex = node.getAttribute("tabindex"); - if (tabIndex === "-1") { - return NodeFilter.FILTER_SKIP; - } - node.focus(); - if (document.activeElement == node) { - return NodeFilter.FILTER_ACCEPT; - } - return NodeFilter.FILTER_SKIP; - } - }); - - iter.currentNode = startElement; - - // Sets the focus via side effect in the filter. - if (type === Services.focus.MOVEFOCUS_FORWARD) { - iter.nextNode(); - } else { - iter.previousNode(); - } - }, - }, -}; - -/** - * Create a new preference. This is used during startup (see - * devtools/client/preferences/devtools.js) to install the - * default preferences. - * - * @param {String} name the name of the preference - * @param {Any} value the default value of the preference - */ -function pref(name, value) { - let thePref = Services.prefs._findOrCreatePref(name, value, true, value); - thePref._setDefault(value); -} - -Services.pref = pref; -module.exports = Services; diff --git a/packages/devtools-modules/index.js b/packages/devtools-modules/index.js deleted file mode 100644 index 61b99d6f5e..0000000000 --- a/packages/devtools-modules/index.js +++ /dev/null @@ -1,22 +0,0 @@ -const Services = require("./client/shared/shim/Services"); -const SplitBox = require("./client/shared/components/splitter/SplitBox"); -// const SplitBoxCSS = require("./client/shared/components/splitter/SplitBox.css") -const Rep = require("./client/shared/components/reps/rep").Rep; -const repUtils = require("./client/shared/components/reps/rep-utils"); -const StringRep = require("./client/shared/components/reps/string").StringRep; - -// const repCSS = require("./client/shared/components/reps/reps.css"); -const Grip = require("./client/shared/components/reps/grip").Grip; -const sprintf = require("./shared/sprintf").sprintf; - -module.exports = { - Services, - SplitBox, - // SplitBoxCSS, - Rep, - repUtils, - StringRep, - // repCSS, - Grip, - sprintf -}; diff --git a/packages/devtools-modules/package.json b/packages/devtools-modules/package.json deleted file mode 100644 index 9a49dc9805..0000000000 --- a/packages/devtools-modules/package.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "devtools-modules", - "version": "0.0.9", - "description": "DevTools Modules from M-C", - "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "", - "license": "ISC" -} diff --git a/packages/devtools-modules/shared/flags.js b/packages/devtools-modules/shared/flags.js deleted file mode 100644 index 9903e6f50c..0000000000 --- a/packages/devtools-modules/shared/flags.js +++ /dev/null @@ -1,21 +0,0 @@ - -/* - * Create a writable property by tracking it with a private variable. - * We cannot make a normal property writeable on `exports` because - * the module system freezes it. - */ -function makeWritableFlag(exports, name) { - let flag = false; - Object.defineProperty(exports, name, { - get: function () { return flag; }, - set: function (state) { flag = state; } - }); -} - -makeWritableFlag(exports, "wantLogging"); -makeWritableFlag(exports, "wantVerbose"); - -// When the testing flag is set, various behaviors may be altered from -// production mode, typically to enable easier testing or enhanced -// debugging. -makeWritableFlag(exports, "testing"); diff --git a/packages/devtools-modules/shared/sprintf.js b/packages/devtools-modules/shared/sprintf.js deleted file mode 100644 index 8e3344e026..0000000000 --- a/packages/devtools-modules/shared/sprintf.js +++ /dev/null @@ -1,274 +0,0 @@ -/** - * Copyright (c) 2007-2016, Alexandru Marasteanu - * 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 of this software 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 AUTHORS OR COPYRIGHT HOLDERS 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. - * - */ - -/* globals window, exports, define */ - -(function(window) { - 'use strict' - - var re = { - not_string: /[^s]/, - not_bool: /[^t]/, - not_type: /[^T]/, - not_primitive: /[^v]/, - number: /[diefg]/, - numeric_arg: /bcdiefguxX/, - json: /[j]/, - not_json: /[^j]/, - text: /^[^\x25]+/, - modulo: /^\x25{2}/, - placeholder: /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-gijosStTuvxX])/, - key: /^([a-z_][a-z_\d]*)/i, - key_access: /^\.([a-z_][a-z_\d]*)/i, - index_access: /^\[(\d+)\]/, - sign: /^[\+\-]/ - } - - function sprintf() { - var key = arguments[0], cache = sprintf.cache - if (!(cache[key] && cache.hasOwnProperty(key))) { - cache[key] = sprintf.parse(key) - } - return sprintf.format.call(null, cache[key], arguments) - } - - sprintf.format = function(parse_tree, argv) { - var cursor = 1, tree_length = parse_tree.length, node_type = '', arg, output = [], i, k, match, pad, pad_character, pad_length, is_positive = true, sign = '' - for (i = 0; i < tree_length; i++) { - node_type = get_type(parse_tree[i]) - if (node_type === 'string') { - output[output.length] = parse_tree[i] - } - else if (node_type === 'array') { - match = parse_tree[i] // convenience purposes only - if (match[2]) { // keyword argument - arg = argv[cursor] - for (k = 0; k < match[2].length; k++) { - if (!arg.hasOwnProperty(match[2][k])) { - throw new Error(sprintf('[sprintf] property "%s" does not exist', match[2][k])) - } - arg = arg[match[2][k]] - } - } - else if (match[1]) { // positional argument (explicit) - arg = argv[match[1]] - } - else { // positional argument (implicit) - arg = argv[cursor++] - } - - if (re.not_type.test(match[8]) && re.not_primitive.test(match[8]) && get_type(arg) == 'function') { - arg = arg() - } - - if (re.numeric_arg.test(match[8]) && (get_type(arg) != 'number' && isNaN(arg))) { - throw new TypeError(sprintf("[sprintf] expecting number but found %s", get_type(arg))) - } - - if (re.number.test(match[8])) { - is_positive = arg >= 0 - } - - switch (match[8]) { - case 'b': - arg = parseInt(arg, 10).toString(2) - break - case 'c': - arg = String.fromCharCode(parseInt(arg, 10)) - break - case 'd': - case 'i': - arg = parseInt(arg, 10) - break - case 'j': - arg = JSON.stringify(arg, null, match[6] ? parseInt(match[6]) : 0) - break - case 'e': - arg = match[7] ? parseFloat(arg).toExponential(match[7]) : parseFloat(arg).toExponential() - break - case 'f': - arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg) - break - case 'g': - arg = match[7] ? parseFloat(arg).toPrecision(match[7]) : parseFloat(arg) - break - case 'o': - arg = arg.toString(8) - break - case 's': - case 'S': - arg = String(arg) - arg = (match[7] ? arg.substring(0, match[7]) : arg) - break - case 't': - arg = String(!!arg) - arg = (match[7] ? arg.substring(0, match[7]) : arg) - break - case 'T': - arg = get_type(arg) - arg = (match[7] ? arg.substring(0, match[7]) : arg) - break - case 'u': - arg = parseInt(arg, 10) >>> 0 - break - case 'v': - arg = arg.valueOf() - arg = (match[7] ? arg.substring(0, match[7]) : arg) - break - case 'x': - arg = parseInt(arg, 10).toString(16) - break - case 'X': - arg = parseInt(arg, 10).toString(16).toUpperCase() - break - } - if (re.json.test(match[8])) { - output[output.length] = arg - } - else { - if (re.number.test(match[8]) && (!is_positive || match[3])) { - sign = is_positive ? '+' : '-' - arg = arg.toString().replace(re.sign, '') - } - else { - sign = '' - } - pad_character = match[4] ? match[4] === '0' ? '0' : match[4].charAt(1) : ' ' - pad_length = match[6] - (sign + arg).length - pad = match[6] ? (pad_length > 0 ? str_repeat(pad_character, pad_length) : '') : '' - output[output.length] = match[5] ? sign + arg + pad : (pad_character === '0' ? sign + pad + arg : pad + sign + arg) - } - } - } - return output.join('') - } - - sprintf.cache = {} - - sprintf.parse = function(fmt) { - var _fmt = fmt, match = [], parse_tree = [], arg_names = 0 - while (_fmt) { - if ((match = re.text.exec(_fmt)) !== null) { - parse_tree[parse_tree.length] = match[0] - } - else if ((match = re.modulo.exec(_fmt)) !== null) { - parse_tree[parse_tree.length] = '%' - } - else if ((match = re.placeholder.exec(_fmt)) !== null) { - if (match[2]) { - arg_names |= 1 - var field_list = [], replacement_field = match[2], field_match = [] - if ((field_match = re.key.exec(replacement_field)) !== null) { - field_list[field_list.length] = field_match[1] - while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') { - if ((field_match = re.key_access.exec(replacement_field)) !== null) { - field_list[field_list.length] = field_match[1] - } - else if ((field_match = re.index_access.exec(replacement_field)) !== null) { - field_list[field_list.length] = field_match[1] - } - else { - throw new SyntaxError("[sprintf] failed to parse named argument key") - } - } - } - else { - throw new SyntaxError("[sprintf] failed to parse named argument key") - } - match[2] = field_list - } - else { - arg_names |= 2 - } - if (arg_names === 3) { - throw new Error("[sprintf] mixing positional and named placeholders is not (yet) supported") - } - parse_tree[parse_tree.length] = match - } - else { - throw new SyntaxError("[sprintf] unexpected placeholder") - } - _fmt = _fmt.substring(match[0].length) - } - return parse_tree - } - - var vsprintf = function(fmt, argv, _argv) { - _argv = (argv || []).slice(0) - _argv.splice(0, 0, fmt) - return sprintf.apply(null, _argv) - } - - /** - * helpers - */ - function get_type(variable) { - if (typeof variable === 'number') { - return 'number' - } - else if (typeof variable === 'string') { - return 'string' - } - else { - return Object.prototype.toString.call(variable).slice(8, -1).toLowerCase() - } - } - - var preformattedPadding = { - '0': ['', '0', '00', '000', '0000', '00000', '000000', '0000000'], - ' ': ['', ' ', ' ', ' ', ' ', ' ', ' ', ' '], - '_': ['', '_', '__', '___', '____', '_____', '______', '_______'], - } - function str_repeat(input, multiplier) { - if (multiplier >= 0 && multiplier <= 7 && preformattedPadding[input]) { - return preformattedPadding[input][multiplier] - } - return Array(multiplier + 1).join(input) - } - - /** - * export to either browser or node.js - */ - if (typeof exports !== 'undefined') { - exports.sprintf = sprintf - exports.vsprintf = vsprintf - } - else { - window.sprintf = sprintf - window.vsprintf = vsprintf - - if (typeof define === 'function' && define.amd) { - define(function() { - return { - sprintf: sprintf, - vsprintf: vsprintf - } - }) - } - } -})(typeof window === 'undefined' ? this : window); diff --git a/packages/devtools-network-request/index.js b/packages/devtools-network-request/index.js deleted file mode 100644 index a453571bd9..0000000000 --- a/packages/devtools-network-request/index.js +++ /dev/null @@ -1,3 +0,0 @@ -const networkRequest = require("./networkRequest"); - -module.exports = networkRequest; diff --git a/packages/devtools-network-request/networkRequest.js b/packages/devtools-network-request/networkRequest.js deleted file mode 100644 index b68a64182f..0000000000 --- a/packages/devtools-network-request/networkRequest.js +++ /dev/null @@ -1,23 +0,0 @@ -const { getValue } = require("devtools-config"); - -// opts is ignored because this is only used in local development and -// replaces a more powerful network request from Firefox that can be -// configured. -function networkRequest(url, opts) { - const devServerURL = getValue("host"); - - return Promise.race([ - fetch(`${devServerURL}/get?url=${url}`) - .then(res => { - if (res.status >= 200 && res.status < 300) { - return res.text().then(text => ({ content: text })); - } - return Promise.reject(new Error(`failed to request ${url}`)); - }), - new Promise((resolve, reject) => { - setTimeout(() => reject(new Error("Connect timeout error")), 6000); - }) - ]); -} - -module.exports = networkRequest; diff --git a/packages/devtools-network-request/package.json b/packages/devtools-network-request/package.json deleted file mode 100644 index c6fb4e9cc5..0000000000 --- a/packages/devtools-network-request/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "devtools-network-request", - "version": "0.0.9", - "description": "Devtools Library for making cross origin requests", - "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "devDependencies": { - "devtools-config": "^0.0.9" - }, - "author": "", - "license": "ISC" -} diff --git a/packages/devtools-network-request/privilegedNetworkRequest.js b/packages/devtools-network-request/privilegedNetworkRequest.js deleted file mode 100644 index a5af70c69e..0000000000 --- a/packages/devtools-network-request/privilegedNetworkRequest.js +++ /dev/null @@ -1,29 +0,0 @@ -function networkRequest(url, opts) { - return new Promise((resolve, reject) => { - const req = new XMLHttpRequest(); - - req.addEventListener("readystatechange", () => { - if (req.readyState === XMLHttpRequest.DONE) { - if (req.status === 200) { - resolve({ content: req.responseText }); - } else { - resolve(req.statusText); - } - } - }); - - // Not working yet. - // if (!opts.loadFromCache) { - // req.channel.loadFlags = ( - // Components.interfaces.nsIRequest.LOAD_BYPASS_CACHE | - // Components.interfaces.nsIRequest.INHIBIT_CACHING | - // Components.interfaces.nsIRequest.LOAD_ANONYMOUS - // ); - // } - - req.open("GET", url); - req.send(); - }); -} - -module.exports = networkRequest; diff --git a/packages/devtools-network-request/stubNetworkRequest.js b/packages/devtools-network-request/stubNetworkRequest.js deleted file mode 100644 index 42cc2784e3..0000000000 --- a/packages/devtools-network-request/stubNetworkRequest.js +++ /dev/null @@ -1,9 +0,0 @@ -const fs = require("fs"); -module.exports = function(url) { - return new Promise((resolve, reject) => { - // example.com is used at a dummy URL that points to our local - // `/src` folder. - url = url.replace("http://example.com/test/", "/../../src/test/mochitest/examples/"); - resolve({ content: fs.readFileSync(__dirname + url, "utf8") }); - }); -}; diff --git a/packages/devtools-sham-modules/client/framework/menu-item.js b/packages/devtools-sham-modules/client/framework/menu-item.js deleted file mode 100644 index f6afefa41b..0000000000 --- a/packages/devtools-sham-modules/client/framework/menu-item.js +++ /dev/null @@ -1,65 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -/** - * A partial implementation of the MenuItem API provided by electron: - * https://github.com/electron/electron/blob/master/docs/api/menu-item.md. - * - * Missing features: - * - id String - Unique within a single menu. If defined then it can be used - * as a reference to this item by the position attribute. - * - role String - Define the action of the menu item; when specified the - * click property will be ignored - * - sublabel String - * - accelerator Accelerator - * - icon NativeImage - * - position String - This field allows fine-grained definition of the - * specific location within a given menu. - * - * Implemented features: - * @param Object options - * Function click - * Will be called with click(menuItem, browserWindow) when the menu item - * is clicked - * String type - * Can be normal, separator, submenu, checkbox or radio - * String label - * Boolean enabled - * If false, the menu item will be greyed out and unclickable. - * Boolean checked - * Should only be specified for checkbox or radio type menu items. - * Menu submenu - * Should be specified for submenu type menu items. If submenu is specified, - * the type: 'submenu' can be omitted. If the value is not a Menu then it - * will be automatically converted to one using Menu.buildFromTemplate. - * Boolean visible - * If false, the menu item will be entirely hidden. - */ -function MenuItem({ - accesskey = null, - checked = false, - click = () => {}, - disabled = false, - label = "", - id = null, - submenu = null, - type = "normal", - visible = true, -} = { }) { - this.accesskey = accesskey; - this.checked = checked; - this.click = click; - this.disabled = disabled; - this.id = id; - this.label = label; - this.submenu = submenu; - this.type = type; - this.visible = visible; -} - -module.exports = MenuItem; diff --git a/packages/devtools-sham-modules/client/framework/menu.js b/packages/devtools-sham-modules/client/framework/menu.js deleted file mode 100644 index f8f8593519..0000000000 --- a/packages/devtools-sham-modules/client/framework/menu.js +++ /dev/null @@ -1,176 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -const EventEmitter = require("../../shared/event-emitter"); - -/** - * A partial implementation of the Menu API provided by electron: - * https://github.com/electron/electron/blob/master/docs/api/menu.md. - * - * Extra features: - * - Emits an 'open' and 'close' event when the menu is opened/closed - - * @param String id (non standard) - * Needed so tests can confirm the XUL implementation is working - */ -function Menu({ id = null } = {}) { - this.menuitems = []; - this.id = id; - - Object.defineProperty(this, "items", { - get() { - return this.menuitems; - } - }); - - EventEmitter.decorate(this); -} - -/** - * Add an item to the end of the Menu - * - * @param {MenuItem} menuItem - */ -Menu.prototype.append = function (menuItem) { - this.menuitems.push(menuItem); -}; - -/** - * Add an item to a specified position in the menu - * - * @param {int} pos - * @param {MenuItem} menuItem - */ -Menu.prototype.insert = function (pos, menuItem) { - throw Error("Not implemented"); -}; - -/** - * Show the Menu at a specified location on the screen - * - * Missing features: - * - browserWindow - BrowserWindow (optional) - Default is null. - * - positioningItem Number - (optional) OS X - * - * @param {int} screenX - * @param {int} screenY - * @param Toolbox toolbox (non standard) - * Needed so we in which window to inject XUL - */ -Menu.prototype.popup = function (screenX, screenY, toolbox) { - let doc = toolbox.doc; - let popupset = doc.querySelector("popupset"); - // See bug 1285229, on Windows, opening the same popup multiple times in a - // row ends up duplicating the popup. The newly inserted popup doesn't - // dismiss the old one. So remove any previously displayed popup before - // opening a new one. - let popup = popupset.querySelector("menupopup[menu-api=\"true\"]"); - if (popup) { - popup.hidePopup(); - } - - popup = this.createPopup(doc) - popup.setAttribute("menu-api", "true"); - - if (this.id) { - popup.id = this.id; - } - this._createMenuItems(popup); - - // Remove the menu from the DOM once it's hidden. - popup.addEventListener("popuphidden", (e) => { - if (e.target === popup) { - popup.remove(); - this.emit("close", popup); - } - }); - - popup.addEventListener("popupshown", (e) => { - if (e.target === popup) { - this.emit("open", popup); - } - }); - - popupset.appendChild(popup); - popup.openPopupAtScreen(screenX, screenY, true); -}; - -Menu.prototype.createPopup = function(doc) { - return doc.createElement("menupopup"); -} - -Menu.prototype._createMenuItems = function (parent) { - let doc = parent.ownerDocument; - this.menuitems.forEach(item => { - if (!item.visible) { - return; - } - - if (item.submenu) { - let menupopup = doc.createElement("menupopup"); - item.submenu._createMenuItems(menupopup); - - let menu = doc.createElement("menu"); - menu.appendChild(menupopup); - menu.setAttribute("label", item.label); - if (item.disabled) { - menu.setAttribute("disabled", "true"); - } - if (item.accesskey) { - menu.setAttribute("accesskey", item.accesskey); - } - if (item.id) { - menu.id = item.id; - } - parent.appendChild(menu); - } else if (item.type === "separator") { - let menusep = doc.createElement("menuseparator"); - parent.appendChild(menusep); - } else { - let menuitem = doc.createElement("menuitem"); - menuitem.setAttribute("label", item.label); - menuitem.textContent = item.label; - menuitem.addEventListener("command", () => item.click()); - - if (item.type === "checkbox") { - menuitem.setAttribute("type", "checkbox"); - } - if (item.type === "radio") { - menuitem.setAttribute("type", "radio"); - } - if (item.disabled) { - menuitem.setAttribute("disabled", "true"); - } - if (item.checked) { - menuitem.setAttribute("checked", "true"); - } - if (item.accesskey) { - menuitem.setAttribute("accesskey", item.accesskey); - } - if (item.id) { - menuitem.id = item.id; - } - - parent.appendChild(menuitem); - } - }); -}; - -Menu.setApplicationMenu = () => { - throw Error("Not implemented"); -}; - -Menu.sendActionToFirstResponder = () => { - throw Error("Not implemented"); -}; - -Menu.buildFromTemplate = () => { - throw Error("Not implemented"); -}; - -module.exports = Menu; diff --git a/packages/devtools-sham-modules/client/framework/target.js b/packages/devtools-sham-modules/client/framework/target.js deleted file mode 100644 index 739736a82a..0000000000 --- a/packages/devtools-sham-modules/client/framework/target.js +++ /dev/null @@ -1,686 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -const promise = require("../../sham/promise"); -const EventEmitter = require("../../shared/event-emitter"); - -/* const { DebuggerServer } = require("../../server/main");*/ -const { DebuggerClient } = require("../../shared/client/main"); - -const targets = new WeakMap(); -const promiseTargets = new WeakMap(); - -/** - * Functions for creating Targets - */ -exports.TargetFactory = { - /** - * Construct a Target - * @param {XULTab} tab - * The tab to use in creating a new target. - * - * @return A target object - */ - forTab: function(tab) { - let target = targets.get(tab); - if (target == null) { - target = new TabTarget(tab); - targets.set(tab, target); - } - return target; - }, - - /** - * Return a promise of a Target for a remote tab. - * @param {Object} options - * The options object has the following properties: - * { - * form: the remote protocol form of a tab, - * client: a DebuggerClient instance - * (caller owns this and is responsible for closing), - * chrome: true if the remote target is the whole process - * } - * - * @return A promise of a target object - */ - forRemoteTab: function(options) { - let targetPromise = promiseTargets.get(options); - if (targetPromise == null) { - let target = new TabTarget(options); - targetPromise = target.makeRemote().then(() => target); - promiseTargets.set(options, targetPromise); - } - return targetPromise; - }, - - forWorker: function(workerClient) { - let target = targets.get(workerClient); - if (target == null) { - target = new WorkerTarget(workerClient); - targets.set(workerClient, target); - } - return target; - }, - - /** - * Creating a target for a tab that is being closed is a problem because it - * allows a leak as a result of coming after the close event which normally - * clears things up. This function allows us to ask if there is a known - * target for a tab without creating a target - * @return true/false - */ - isKnownTab: function(tab) { - return targets.has(tab); - }, -}; - -/** - * A Target represents something that we can debug. Targets are generally - * read-only. Any changes that you wish to make to a target should be done via - * a Tool that attaches to the target. i.e. a Target is just a pointer saying - * "the thing to debug is over there". - * - * Providing a generalized abstraction of a web-page or web-browser (available - * either locally or remotely) is beyond the scope of this class (and maybe - * also beyond the scope of this universe) However Target does attempt to - * abstract some common events and read-only properties common to many Tools. - * - * Supported read-only properties: - * - name, isRemote, url - * - * Target extends EventEmitter and provides support for the following events: - * - close: The target window has been closed. All tools attached to this - * target should close. This event is not currently cancelable. - * - navigate: The target window has navigated to a different URL - * - * Optional events: - * - will-navigate: The target window will navigate to a different URL - * - hidden: The target is not visible anymore (for TargetTab, another tab is - * selected) - * - visible: The target is visible (for TargetTab, tab is selected) - * - * Comparing Targets: 2 instances of a Target object can point at the same - * thing, so t1 !== t2 and t1 != t2 even when they represent the same object. - * To compare to targets use 't1.equals(t2)'. - */ - -/** - * A TabTarget represents a page living in a browser tab. Generally these will - * be web pages served over http(s), but they don't have to be. - */ -function TabTarget(tab) { - EventEmitter.decorate(this); - this.destroy = this.destroy.bind(this); - this._handleThreadState = this._handleThreadState.bind(this); - this.on("thread-resumed", this._handleThreadState); - this.on("thread-paused", this._handleThreadState); - this.activeTab = this.activeConsole = null; - // Only real tabs need initialization here. Placeholder objects for remote - // targets will be initialized after a makeRemote method call. - if (tab && !["client", "form", "chrome"].every(tab.hasOwnProperty, tab)) { - this._tab = tab; - this._setupListeners(); - } else { - this._form = tab.form; - this._client = tab.client; - this._chrome = tab.chrome; - } - // Default isTabActor to true if not explicitly specified - if (typeof tab.isTabActor == "boolean") { - this._isTabActor = tab.isTabActor; - } else { - this._isTabActor = true; - } -} - -TabTarget.prototype = { - _webProgressListener: null, - - /** - * Returns a promise for the protocol description from the root actor. Used - * internally with `target.actorHasMethod`. Takes advantage of caching if - * definition was fetched previously with the corresponding actor information. - * Actors are lazily loaded, so not only must the tool using a specific actor - * be in use, the actors are only registered after invoking a method (for - * performance reasons, added in bug 988237), so to use these actor detection - * methods, one must already be communicating with a specific actor of that - * type. - * - * Must be a remote target. - * - * @return {Promise} - * { - * "category": "actor", - * "typeName": "longstractor", - * "methods": [{ - * "name": "substring", - * "request": { - * "type": "substring", - * "start": { - * "_arg": 0, - * "type": "primitive" - * }, - * "end": { - * "_arg": 1, - * "type": "primitive" - * } - * }, - * "response": { - * "substring": { - * "_retval": "primitive" - * } - * } - * }], - * "events": {} - * } - */ - getActorDescription: function(actorName) { - if (!this.client) { - throw new Error("TabTarget#getActorDescription() can only be called on " + - "remote tabs."); - } - - let deferred = promise.defer(); - - if (this._protocolDescription && - this._protocolDescription.types[actorName]) { - deferred.resolve(this._protocolDescription.types[actorName]); - } else { - this.client.mainRoot.protocolDescription(description => { - this._protocolDescription = description; - deferred.resolve(description.types[actorName]); - }); - } - - return deferred.promise; - }, - - /** - * Returns a boolean indicating whether or not the specific actor - * type exists. Must be a remote target. - * - * @param {String} actorName - * @return {Boolean} - */ - hasActor: function(actorName) { - if (!this.client) { - throw new Error("TabTarget#hasActor() can only be called on remote " + - "tabs."); - } - if (this.form) { - return !!this.form[actorName + "Actor"]; - } - return false; - }, - - /** - * Queries the protocol description to see if an actor has - * an available method. The actor must already be lazily-loaded (read - * the restrictions in the `getActorDescription` comments), - * so this is for use inside of tool. Returns a promise that - * resolves to a boolean. Must be a remote target. - * - * @param {String} actorName - * @param {String} methodName - * @return {Promise} - */ - actorHasMethod: function(actorName, methodName) { - if (!this.client) { - throw new Error("TabTarget#actorHasMethod() can only be called on " + - "remote tabs."); - } - return this.getActorDescription(actorName).then(desc => { - if (desc && desc.methods) { - return !!desc.methods.find(method => method.name === methodName); - } - return false; - }); - }, - - /** - * Returns a trait from the root actor. - * - * @param {String} traitName - * @return {Mixed} - */ - getTrait: function(traitName) { - if (!this.client) { - throw new Error("TabTarget#getTrait() can only be called on remote " + - "tabs."); - } - - // If the targeted actor exposes traits and has a defined value for this - // traits, override the root actor traits - if (this.form.traits && traitName in this.form.traits) { - return this.form.traits[traitName]; - } - - return this.client.traits[traitName]; - }, - - get tab() { - return this._tab; - }, - - get form() { - return this._form; - }, - - // Get a promise of the root form returned by a listTabs request. This promise - // is cached. - get root() { - if (!this._root) { - this._root = this._getRoot(); - } - return this._root; - }, - - _getRoot: function() { - return new Promise((resolve, reject) => { - this.client.listTabs(response => { - if (response.error) { - reject(new Error(response.error + ": " + response.message)); - return; - } - - resolve(response); - }); - }); - }, - - get client() { - return this._client; - }, - - // Tells us if we are debugging content document - // or if we are debugging chrome stuff. - // Allows to controls which features are available against - // a chrome or a content document. - get chrome() { - return this._chrome; - }, - - // Tells us if the related actor implements TabActor interface - // and requires to call `attach` request before being used - // and `detach` during cleanup - get isTabActor() { - return this._isTabActor; - }, - - get window() { - // XXX - this is a footgun for e10s - there .contentWindow will be null, - // and even though .contentWindowAsCPOW *might* work, it will not work - // in all contexts. Consumers of .window need to be refactored to not - // rely on this. - // if (Services.appinfo.processType != Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT) { - // console.error("The .window getter on devtools' |target| object isn't " + - // "e10s friendly!\n" + Error().stack); - // } - // Be extra careful here, since this may be called by HS_getHudByWindow - // during shutdown. - if (this._tab && this._tab.linkedBrowser) { - return this._tab.linkedBrowser.contentWindow; - } - return null; - }, - - get name() { - if (this._tab && this._tab.linkedBrowser.contentDocument) { - return this._tab.linkedBrowser.contentDocument.title; - } - if (this.isAddon) { - return this._form.name; - } - return this._form.title; - }, - - get url() { - return this._tab ? this._tab.linkedBrowser.currentURI.spec : - this._form.url; - }, - - get isRemote() { - return !this.isLocalTab; - }, - - get isAddon() { - return !!(this._form && this._form.actor && - this._form.actor.match(/conn\d+\.addon\d+/)); - }, - - get isLocalTab() { - return !!this._tab; - }, - - get isMultiProcess() { - return !this.window; - }, - - get isThreadPaused() { - return !!this._isThreadPaused; - }, - - /** - * Adds remote protocol capabilities to the target, so that it can be used - * for tools that support the Remote Debugging Protocol even for local - * connections. - */ - makeRemote: function() { - if (this._remote) { - return this._remote.promise; - } - - this._remote = promise.defer(); - - if (this.isLocalTab) { - // Since a remote protocol connection will be made, let's start the - // DebuggerServer here, once and for all tools. - if (!DebuggerServer.initialized) { - DebuggerServer.init(); - DebuggerServer.addBrowserActors(); - } - - this._client = new DebuggerClient(DebuggerServer.connectPipe()); - // A local TabTarget will never perform chrome debugging. - this._chrome = false; - } - - this._setupRemoteListeners(); - - let attachTab = () => { - this._client.attachTab(this._form.actor, (response, tabClient) => { - if (!tabClient) { - this._remote.reject("Unable to attach to the tab"); - return; - } - this.activeTab = tabClient; - this.threadActor = response.threadActor; - attachConsole(); - }); - }; - - let onConsoleAttached = (response, consoleClient) => { - if (!consoleClient) { - this._remote.reject("Unable to attach to the console"); - return; - } - this.activeConsole = consoleClient; - this._remote.resolve(null); - }; - - let attachConsole = () => { - this._client.attachConsole(this._form.consoleActor, - [ "NetworkActivity" ], - onConsoleAttached); - }; - - if (this.isLocalTab) { - this._client.connect(() => { - this._client.getTab({ tab: this.tab }).then(response => { - this._form = response.tab; - attachTab(); - }); - }); - } else if (this.isTabActor) { - // In the remote debugging case, the protocol connection will have been - // already initialized in the connection screen code. - attachTab(); - } else { - // AddonActor and chrome debugging on RootActor doesn't inherits from - // TabActor and doesn't need to be attached. - attachConsole(); - } - - return this._remote.promise; - }, - - /** - * Listen to the different events. - */ - _setupListeners: function() { - this._webProgressListener = new TabWebProgressListener(this); - this.tab.linkedBrowser.addProgressListener(this._webProgressListener); - this.tab.addEventListener("TabClose", this); - this.tab.parentNode.addEventListener("TabSelect", this); - this.tab.ownerDocument.defaultView.addEventListener("unload", this); - }, - - /** - * Teardown event listeners. - */ - _teardownListeners: function() { - if (this._webProgressListener) { - this._webProgressListener.destroy(); - } - - this._tab.ownerDocument.defaultView.removeEventListener("unload", this); - this._tab.removeEventListener("TabClose", this); - this._tab.parentNode.removeEventListener("TabSelect", this); - }, - - /** - * Setup listeners for remote debugging, updating existing ones as necessary. - */ - _setupRemoteListeners: function() { - this.client.addListener("closed", this.destroy); - - this._onTabDetached = (aType, aPacket) => { - // We have to filter message to ensure that this detach is for this tab - if (aPacket.from == this._form.actor) { - this.destroy(); - } - }; - this.client.addListener("tabDetached", this._onTabDetached); - - this._onTabNavigated = (aType, aPacket) => { - let event = Object.create(null); - event.url = aPacket.url; - event.title = aPacket.title; - event.nativeConsoleAPI = aPacket.nativeConsoleAPI; - event.isFrameSwitching = aPacket.isFrameSwitching; - // Send any stored event payload (DOMWindow or nsIRequest) for backwards - // compatibility with non-remotable tools. - if (aPacket.state == "start") { - event._navPayload = this._navRequest; - this.emit("will-navigate", event); - this._navRequest = null; - } else { - event._navPayload = this._navWindow; - this.emit("navigate", event); - this._navWindow = null; - } - }; - this.client.addListener("tabNavigated", this._onTabNavigated); - - this._onFrameUpdate = (aType, aPacket) => { - this.emit("frame-update", aPacket); - }; - this.client.addListener("frameUpdate", this._onFrameUpdate); - }, - - /** - * Teardown listeners for remote debugging. - */ - _teardownRemoteListeners: function() { - this.client.removeListener("closed", this.destroy); - this.client.removeListener("tabNavigated", this._onTabNavigated); - this.client.removeListener("tabDetached", this._onTabDetached); - this.client.removeListener("frameUpdate", this._onFrameUpdate); - }, - - /** - * Handle tabs events. - */ - handleEvent: function(event) { - switch (event.type) { - case "TabClose": - case "unload": - this.destroy(); - break; - case "TabSelect": - if (this.tab.selected) { - this.emit("visible", event); - } else { - this.emit("hidden", event); - } - break; - } - }, - - /** - * Handle script status. - */ - _handleThreadState: function(event) { - switch (event) { - case "thread-resumed": - this._isThreadPaused = false; - break; - case "thread-paused": - this._isThreadPaused = true; - break; - } - }, - - /** - * Target is not alive anymore. - */ - destroy: function() { - // If several things call destroy then we give them all the same - // destruction promise so we're sure to destroy only once - if (this._destroyer) { - return this._destroyer.promise; - } - - this._destroyer = promise.defer(); - - // Before taking any action, notify listeners that destruction is imminent. - this.emit("close"); - - // First of all, do cleanup tasks that pertain to both remoted and - // non-remoted targets. - this.off("thread-resumed", this._handleThreadState); - this.off("thread-paused", this._handleThreadState); - - if (this._tab) { - this._teardownListeners(); - } - - let cleanupAndResolve = () => { - this._cleanup(); - this._destroyer.resolve(null); - }; - // If this target was not remoted, the promise will be resolved before the - // function returns. - if (this._tab && !this._client) { - cleanupAndResolve(); - } else if (this._client) { - // If, on the other hand, this target was remoted, the promise will be - // resolved after the remote connection is closed. - this._teardownRemoteListeners(); - - if (this.isLocalTab) { - // We started with a local tab and created the client ourselves, so we - // should close it. - this._client.close(cleanupAndResolve); - } else if (this.activeTab) { - // The client was handed to us, so we are not responsible for closing - // it. We just need to detach from the tab, if already attached. - // |detach| may fail if the connection is already dead, so proceed with - // cleanup directly after this. - this.activeTab.detach(); - cleanupAndResolve(); - } else { - cleanupAndResolve(); - } - } - - return this._destroyer.promise; - }, - - /** - * Clean up references to what this target points to. - */ - _cleanup: function() { - if (this._tab) { - targets.delete(this._tab); - } else { - promiseTargets.delete(this._form); - } - this.activeTab = null; - this.activeConsole = null; - this._client = null; - this._tab = null; - this._form = null; - this._remote = null; - }, - - toString: function() { - let id = this._tab ? this._tab : (this._form && this._form.actor); - return `TabTarget:${id}`; - }, -}; - -function WorkerTarget(workerClient) { - EventEmitter.decorate(this); - this._workerClient = workerClient; -} - -/** - * A WorkerTarget represents a worker. Unlike TabTarget, which can represent - * either a local or remote tab, WorkerTarget always represents a remote worker. - * Moreover, unlike TabTarget, which is constructed with a placeholder object - * for remote tabs (from which a TabClient can then be lazily obtained), - * WorkerTarget is constructed with a WorkerClient directly. - * - * WorkerClient is designed to mimic the interface of TabClient as closely as - * possible. This allows us to debug workers as if they were ordinary tabs, - * requiring only minimal changes to the rest of the frontend. - */ -WorkerTarget.prototype = { - destroy: function() {}, - - get isRemote() { - return true; - }, - - get isTabActor() { - return true; - }, - - get url() { - return this._workerClient.url; - }, - - get isWorkerTarget() { - return true; - }, - - get form() { - return { - consoleActor: this._workerClient.consoleActor - }; - }, - - get activeTab() { - return this._workerClient; - }, - - get client() { - return this._workerClient.client; - }, - - destroy: function() {}, - - hasActor: function(name) { - return false; - }, - - getTrait: function() { - return undefined; - }, - - makeRemote: function() { - return Promise.resolve(); - } -}; diff --git a/packages/devtools-sham-modules/client/shared/components/frame.js b/packages/devtools-sham-modules/client/shared/components/frame.js deleted file mode 100644 index bd8ddcad7f..0000000000 --- a/packages/devtools-sham-modules/client/shared/components/frame.js +++ /dev/null @@ -1,248 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -const { DOM: dom, createClass, PropTypes } = require("devtools/client/shared/vendor/react"); -const { getSourceNames, parseURL, - isScratchpadScheme, getSourceMappedFile } = require("../source-utils"); -// const { LocalizationHelper } = require("devtools/shared/l10n"); -// -// const l10n = new LocalizationHelper("devtools/client/locales/components.properties"); -// const webl10n = new LocalizationHelper("devtools/client/locales/webconsole.properties"); - -const l10n = { getStr: () => {} }; -const webl10n = { getStr: () => {} }; - -module.exports = createClass({ - displayName: "Frame", - - propTypes: { - // SavedFrame, or an object containing all the required properties. - frame: PropTypes.shape({ - functionDisplayName: PropTypes.string, - source: PropTypes.string.isRequired, - line: PropTypes.oneOfType([ PropTypes.string, PropTypes.number ]), - column: PropTypes.oneOfType([ PropTypes.string, PropTypes.number ]), - }).isRequired, - // Clicking on the frame link -- probably should link to the debugger. - onClick: PropTypes.func.isRequired, - // Option to display a function name before the source link. - showFunctionName: PropTypes.bool, - // Option to display a function name even if it's anonymous. - showAnonymousFunctionName: PropTypes.bool, - // Option to display a host name after the source link. - showHost: PropTypes.bool, - // Option to display a host name if the filename is empty or just '/' - showEmptyPathAsHost: PropTypes.bool, - // Option to display a full source instead of just the filename. - showFullSourceUrl: PropTypes.bool, - // Service to enable the source map feature for console. - sourceMapService: PropTypes.object, - }, - - getDefaultProps() { - return { - showFunctionName: false, - showAnonymousFunctionName: false, - showHost: false, - showEmptyPathAsHost: false, - showFullSourceUrl: false, - }; - }, - - componentWillMount() { - const sourceMapService = this.props.sourceMapService; - if (sourceMapService) { - const source = this.getSource(); - sourceMapService.subscribe(source, this.onSourceUpdated); - } - }, - - componentWillUnmount() { - const sourceMapService = this.props.sourceMapService; - if (sourceMapService) { - const source = this.getSource(); - sourceMapService.unsubscribe(source, this.onSourceUpdated); - } - }, - - /** - * Component method to update the FrameView when a resolved location is available - * @param event - * @param location - */ - onSourceUpdated(event, location, resolvedLocation) { - const frame = this.getFrame(resolvedLocation); - this.setState({ - frame, - isSourceMapped: true, - }); - }, - - /** - * Utility method to convert the Frame object to the - * Source Object model required by SourceMapService - * @param frame - * @returns {{url: *, line: *, column: *}} - */ - getSource(frame) { - frame = frame || this.props.frame; - const { source, line, column } = frame; - return { - url: source, - line, - column, - }; - }, - - /** - * Utility method to convert the Source object model to the - * Frame object model required by FrameView class. - * @param source - * @returns {{source: *, line: *, column: *, functionDisplayName: *}} - */ - getFrame(source) { - const { url, line, column } = source; - return { - source: url, - line, - column, - functionDisplayName: this.props.frame.functionDisplayName, - }; - }, - - render() { - let frame, isSourceMapped; - let { - onClick, - showFunctionName, - showAnonymousFunctionName, - showHost, - showEmptyPathAsHost, - showFullSourceUrl - } = this.props; - - if (this.state && this.state.isSourceMapped) { - frame = this.state.frame; - isSourceMapped = this.state.isSourceMapped; - } else { - frame = this.props.frame; - } - - let source = frame.source ? String(frame.source) : ""; - let line = frame.line != void 0 ? Number(frame.line) : null; - let column = frame.column != void 0 ? Number(frame.column) : null; - - const { short, long, host } = getSourceNames(source); - // Reparse the URL to determine if we should link this; `getSourceNames` - // has already cached this indirectly. We don't want to attempt to - // link to "self-hosted" and "(unknown)". However, we do want to link - // to Scratchpad URIs. - // Source mapped sources might not necessary linkable, but they - // are still valid in the debugger. - const isLinkable = !!(isScratchpadScheme(source) || parseURL(source)) - || isSourceMapped; - const elements = []; - const sourceElements = []; - let sourceEl; - - let tooltip = long; - - // If the source is linkable and line > 0 - const shouldDisplayLine = isLinkable && line; - - // Exclude all falsy values, including `0`, as even - // a number 0 for line doesn't make sense, and should not be displayed. - // If source isn't linkable, don't attempt to append line and column - // info, as this probably doesn't make sense. - if (shouldDisplayLine) { - tooltip += `:${line}`; - // Intentionally exclude 0 - if (column) { - tooltip += `:${column}`; - } - } - - let attributes = { - "data-url": long, - className: "frame-link", - }; - - if (showFunctionName) { - let functionDisplayName = frame.functionDisplayName; - if (!functionDisplayName && showAnonymousFunctionName) { - functionDisplayName = webl10n.getStr("stacktrace.anonymousFunction"); - } - - if (functionDisplayName) { - elements.push( - dom.span({ className: "frame-link-function-display-name" }, - functionDisplayName), - " " - ); - } - } - - let displaySource = showFullSourceUrl ? long : short; - if (isSourceMapped) { - displaySource = getSourceMappedFile(displaySource); - } else if (showEmptyPathAsHost && (displaySource === "" || displaySource === "/")) { - displaySource = host; - } - - sourceElements.push(dom.span({ - className: "frame-link-filename", - }, displaySource)); - - // If source is linkable, and we have a line number > 0 - if (shouldDisplayLine) { - let lineInfo = `:${line}`; - // Add `data-line` attribute for testing - attributes["data-line"] = line; - - // Intentionally exclude 0 - if (column) { - lineInfo += `:${column}`; - // Add `data-column` attribute for testing - attributes["data-column"] = column; - } - - sourceElements.push(dom.span({ className: "frame-link-line" }, lineInfo)); - } - - // Inner el is useful for achieving ellipsis on the left and correct LTR/RTL - // ordering. See CSS styles for frame-link-source-[inner] and bug 1290056. - let sourceInnerEl = dom.span({ - className: "frame-link-source-inner", - title: isLinkable ? - l10n.getFormatStr("frame.viewsourceindebugger", tooltip) : tooltip, - }, sourceElements); - - // If source is not a URL (self-hosted, eval, etc.), don't make - // it an anchor link, as we can't link to it. - if (isLinkable) { - sourceEl = dom.a({ - onClick: e => { - e.preventDefault(); - onClick(this.getSource(frame)); - }, - href: source, - className: "frame-link-source", - draggable: false, - }, sourceInnerEl); - } else { - sourceEl = dom.span({ - className: "frame-link-source", - }, sourceInnerEl); - } - elements.push(sourceEl); - - if (showHost && host) { - elements.push(" ", dom.span({ className: "frame-link-host" }, host)); - } - - return dom.span(attributes, ...elements); - } -}); diff --git a/packages/devtools-sham-modules/client/shared/components/stack-trace.js b/packages/devtools-sham-modules/client/shared/components/stack-trace.js deleted file mode 100644 index 43d0b87161..0000000000 --- a/packages/devtools-sham-modules/client/shared/components/stack-trace.js +++ /dev/null @@ -1,68 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -const React = require("devtools/client/shared/vendor/react"); -const { DOM: dom, createClass, createFactory, PropTypes } = React; -const { LocalizationHelper } = require("devtools/shared/l10n"); -const Frame = createFactory(require("./frame")); - -const l10n = new LocalizationHelper("devtools/client/locales/webconsole.properties"); - -const AsyncFrame = createFactory(createClass({ - displayName: "AsyncFrame", - - PropTypes: { - asyncCause: PropTypes.string.isRequired - }, - - render() { - let { asyncCause } = this.props; - - return dom.span( - { className: "frame-link-async-cause" }, - l10n.getFormatStr("stacktrace.asyncStack", asyncCause) - ); - } -})); - -const StackTrace = createClass({ - displayName: "StackTrace", - - PropTypes: { - stacktrace: PropTypes.array.isRequired, - onViewSourceInDebugger: PropTypes.func.isRequired - }, - - render() { - let { stacktrace, onViewSourceInDebugger } = this.props; - - let frames = []; - stacktrace.forEach(s => { - if (s.asyncCause) { - frames.push("\t", AsyncFrame({ - asyncCause: s.asyncCause - }), "\n"); - } - - frames.push("\t", Frame({ - frame: { - functionDisplayName: s.functionName, - source: s.filename.split(" -> ").pop(), - line: s.lineNumber, - column: s.columnNumber, - }, - showFunctionName: true, - showAnonymousFunctionName: true, - showFullSourceUrl: true, - onClick: onViewSourceInDebugger - }), "\n"); - }); - - return dom.div({ className: "stack-trace" }, frames); - } -}); - -module.exports = StackTrace; diff --git a/packages/devtools-sham-modules/client/shared/components/tree.js b/packages/devtools-sham-modules/client/shared/components/tree.js deleted file mode 100644 index c1f22f0a98..0000000000 --- a/packages/devtools-sham-modules/client/shared/components/tree.js +++ /dev/null @@ -1,604 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -const { DOM: dom, createClass, createFactory, PropTypes } = require("react"); -// const { ViewHelpers } = -// require("resource://devtools/client/shared/widgets/ViewHelpers.jsm"); -// let { VirtualScroll } = require("react-virtualized"); -// VirtualScroll = createFactory(VirtualScroll); - -const AUTO_EXPAND_DEPTH = 0; // depth - -/** - * An arrow that displays whether its node is expanded (▼) or collapsed - * (▶). When its node has no children, it is hidden. - */ -const ArrowExpander = createFactory(createClass({ - displayName: "ArrowExpander", - - shouldComponentUpdate(nextProps, nextState) { - return this.props.item !== nextProps.item - || this.props.visible !== nextProps.visible - || this.props.expanded !== nextProps.expanded; - }, - - render() { - const attrs = { - className: "arrow theme-twisty", - onClick: this.props.expanded - ? () => this.props.onCollapse(this.props.item) - : e => this.props.onExpand(this.props.item, e.altKey) - }; - - if (this.props.expanded) { - attrs.className += " open"; - } - - if (!this.props.visible) { - attrs.style = Object.assign({}, this.props.style || {}, { - visibility: "hidden" - }); - } - - return dom.div(attrs, this.props.children); - } -})); - -const TreeNode = createFactory(createClass({ - displayName: "TreeNode", - - componentDidMount() { - if (this.props.focused) { - this.refs.button.focus(); - } - }, - - componentDidUpdate() { - if (this.props.focused) { - this.refs.button.focus(); - } - }, - - shouldComponentUpdate(nextProps) { - return this.props.item !== nextProps.item || - this.props.focused !== nextProps.focused || - this.props.expanded !== nextProps.expanded; - }, - - render() { - const arrow = ArrowExpander({ - item: this.props.item, - expanded: this.props.expanded, - visible: this.props.hasChildren, - onExpand: this.props.onExpand, - onCollapse: this.props.onCollapse, - }); - - let isOddRow = this.props.index % 2; - return dom.div( - { - className: `tree-node div ${isOddRow ? "tree-node-odd" : ""}`, - onFocus: this.props.onFocus, - onClick: this.props.onFocus, - onBlur: this.props.onBlur, - style: { - padding: 0, - margin: 0 - } - }, - - this.props.renderItem(this.props.item, - this.props.depth, - this.props.focused, - arrow, - this.props.expanded), - - // XXX: OSX won't focus/blur regular elements even if you set tabindex - // unless there is an input/button child. - dom.button(this._buttonAttrs) - ); - }, - - _buttonAttrs: { - ref: "button", - style: { - opacity: 0, - width: "0 !important", - height: "0 !important", - padding: "0 !important", - outline: "none", - MozAppearance: "none", - // XXX: Despite resetting all of the above properties (and margin), the - // button still ends up with ~79px width, so we set a large negative - // margin to completely hide it. - MozMarginStart: "-1000px !important", - } - } -})); - -/** - * Create a function that calls the given function `fn` only once per animation - * frame. - * - * @param {Function} fn - * @returns {Function} - */ -function oncePerAnimationFrame(fn) { - let animationId = null; - let argsToPass = null; - return function(...args) { - argsToPass = args; - if (animationId !== null) { - return; - } - - animationId = requestAnimationFrame(() => { - fn.call(this, ...argsToPass); - animationId = null; - argsToPass = null; - }); - }; -} - -const NUMBER_OF_OFFSCREEN_ITEMS = 1; - -/** - * A generic tree component. See propTypes for the public API. - * - * @see `devtools/client/memory/components/test/mochitest/head.js` for usage - * @see `devtools/client/memory/components/heap.js` for usage - */ -const Tree = module.exports = createClass({ - displayName: "Tree", - - propTypes: { - // Required props - - // A function to get an item's parent, or null if it is a root. - getParent: PropTypes.func.isRequired, - // A function to get an item's children. - getChildren: PropTypes.func.isRequired, - // A function which takes an item and ArrowExpander and returns a - // component. - renderItem: PropTypes.func.isRequired, - // A function which returns the roots of the tree (forest). - getRoots: PropTypes.func.isRequired, - // A function to get a unique key for the given item. - getKey: PropTypes.func.isRequired, - // A function to get whether an item is expanded or not. If an item is not - // expanded, then it must be collapsed. - isExpanded: PropTypes.func.isRequired, - // The height of an item in the tree including margin and padding, in - // pixels. - itemHeight: PropTypes.number.isRequired, - - // Optional props - - // The currently focused item, if any such item exists. - focused: PropTypes.any, - // Handle when a new item is focused. - onFocus: PropTypes.func, - // The depth to which we should automatically expand new items. - autoExpandDepth: PropTypes.number, - // Should auto expand all new items or just the new items under the first - // root item. - autoExpandAll: PropTypes.bool, - // Optional event handlers for when items are expanded or collapsed. - onExpand: PropTypes.func, - onCollapse: PropTypes.func, - }, - - getDefaultProps() { - return { - autoExpandDepth: AUTO_EXPAND_DEPTH, - autoExpandAll: true - }; - }, - - getInitialState() { - return { - scroll: 0, - height: window.innerHeight, - seen: new Set(), - }; - }, - - componentDidMount() { - window.addEventListener("resize", this._updateHeight); - this._autoExpand(this.props); - this._updateHeight(); - }, - - componentWillUnmount() { - window.removeEventListener("resize", this._updateHeight); - }, - - componentWillReceiveProps(nextProps) { - this._autoExpand(nextProps); - this._updateHeight(); - }, - - _autoExpand(props) { - if (!props.autoExpandDepth) { - return; - } - - // Automatically expand the first autoExpandDepth levels for new items. Do - // not use the usual DFS infrastructure because we don't want to ignore - // collapsed nodes. - const autoExpand = (item, currentDepth) => { - if (currentDepth >= props.autoExpandDepth || - this.state.seen.has(item)) { - return; - } - - props.onExpand(item); - this.state.seen.add(item); - - const children = props.getChildren(item); - const length = children.length; - for (let i = 0; i < length; i++) { - autoExpand(children[i], currentDepth + 1); - } - }; - - const roots = props.getRoots(); - const length = roots.length; - if (props.autoExpandAll) { - for (let i = 0; i < length; i++) { - autoExpand(roots[i], 0); - } - } else { - autoExpand(roots[0], 0); - } - }, - - render() { - const traversal = this._dfsFromRoots(); - - // Remove `NUMBER_OF_OFFSCREEN_ITEMS` from `begin` and add `2 * - // NUMBER_OF_OFFSCREEN_ITEMS` to `end` so that the top and bottom of the - // page are filled with the `NUMBER_OF_OFFSCREEN_ITEMS` previous and next - // items respectively, rather than whitespace if the item is not in full - // view. - // const begin = Math.max(((this.state.scroll / this.props.itemHeight) | 0) - NUMBER_OF_OFFSCREEN_ITEMS, 0); - // const end = begin + (2 * NUMBER_OF_OFFSCREEN_ITEMS) + ((this.state.height / this.props.itemHeight) | 0); - // const toRender = traversal; - - // const nodes = [ - // dom.div({ - // key: "top-spacer", - // style: { - // padding: 0, - // margin: 0, - // height: begin * this.props.itemHeight + "px" - // } - // }) - // ]; - - const renderItem = i => { - let { item, depth } = traversal[i]; - return TreeNode({ - key: this.props.getKey(item, i), - index: i, - item: item, - depth: depth, - renderItem: this.props.renderItem, - focused: this.props.focused === item, - expanded: this.props.isExpanded(item), - hasChildren: !!this.props.getChildren(item).length, - onExpand: this._onExpand, - onCollapse: this._onCollapse, - onFocus: () => this._focus(i, item), - }); - }; - - // nodes.push(dom.div({ - // key: "bottom-spacer", - // style: { - // padding: 0, - // margin: 0, - // height: (traversal.length - 1 - end) * this.props.itemHeight + "px" - // } - // })); - - const style = Object.assign({}, this.props.style || {}, { - padding: 0, - margin: 0 - }); - - return dom.div( - { - className: "tree", - ref: "tree", - onKeyDown: this._onKeyDown, - onKeyPress: this._preventArrowKeyScrolling, - onKeyUp: this._preventArrowKeyScrolling, - // onScroll: this._onScroll, - style - }, - // VirtualScroll({ - // width: this.props.width, - // height: this.props.height, - // rowsCount: traversal.length, - // rowHeight: this.props.itemHeight, - // rowRenderer: renderItem - // }) - traversal.map((v, i) => renderItem(i)) - ); - }, - - _preventArrowKeyScrolling(e) { - switch (e.key) { - case "ArrowUp": - case "ArrowDown": - case "ArrowLeft": - case "ArrowRight": - e.preventDefault(); - e.stopPropagation(); - if (e.nativeEvent) { - if (e.nativeEvent.preventDefault) { - e.nativeEvent.preventDefault(); - } - if (e.nativeEvent.stopPropagation) { - e.nativeEvent.stopPropagation(); - } - } - } - }, - - /** - * Updates the state's height based on clientHeight. - */ - _updateHeight() { - this.setState({ - height: this.refs.tree.clientHeight - }); - }, - - /** - * Perform a pre-order depth-first search from item. - */ - _dfs(item, maxDepth = Infinity, traversal = [], _depth = 0) { - traversal.push({ item, depth: _depth }); - - if (!this.props.isExpanded(item)) { - return traversal; - } - - const nextDepth = _depth + 1; - - if (nextDepth > maxDepth) { - return traversal; - } - - const children = this.props.getChildren(item); - const length = children.length; - for (let i = 0; i < length; i++) { - this._dfs(children[i], maxDepth, traversal, nextDepth); - } - - return traversal; - }, - - /** - * Perform a pre-order depth-first search over the whole forest. - */ - _dfsFromRoots(maxDepth = Infinity) { - const traversal = []; - - const roots = this.props.getRoots(); - const length = roots.length; - for (let i = 0; i < length; i++) { - this._dfs(roots[i], maxDepth, traversal); - } - - return traversal; - }, - - /** - * Expands current row. - * - * @param {Object} item - * @param {Boolean} expandAllChildren - */ - _onExpand: oncePerAnimationFrame(function(item, expandAllChildren) { - if (this.props.onExpand) { - this.props.onExpand(item); - - if (expandAllChildren) { - const children = this._dfs(item); - const length = children.length; - for (let i = 0; i < length; i++) { - this.props.onExpand(children[i].item); - } - } - } - }), - - /** - * Collapses current row. - * - * @param {Object} item - */ - _onCollapse: oncePerAnimationFrame(function(item) { - if (this.props.onCollapse) { - this.props.onCollapse(item); - } - }), - - /** - * Sets the passed in item to be the focused item. - * - * @param {Number} index - * The index of the item in a full DFS traversal (ignoring collapsed - * nodes). Ignored if `item` is undefined. - * - * @param {Object|undefined} item - * The item to be focused, or undefined to focus no item. - */ - _focus(index, item) { - if (item !== undefined) { - const itemStartPosition = index * this.props.itemHeight; - const itemEndPosition = (index + 1) * this.props.itemHeight; - - // Note that if the height of the viewport (this.state.height) is less than - // `this.props.itemHeight`, we could accidentally try and scroll both up and - // down in a futile attempt to make both the item's start and end positions - // visible. Instead, give priority to the start of the item by checking its - // position first, and then using an "else if", rather than a separate "if", - // for the end position. - if (this.state.scroll > itemStartPosition) { - this.refs.tree.scrollTop = itemStartPosition; - } else if ((this.state.scroll + this.state.height) < itemEndPosition) { - this.refs.tree.scrollTop = itemEndPosition - this.state.height; - } - } - - if (this.props.onFocus) { - this.props.onFocus(item); - } - }, - - /** - * Sets the state to have no focused item. - */ - _onBlur() { - this._focus(0, undefined); - }, - - /** - * Fired on a scroll within the tree's container, updates - * the stored position of the view port to handle virtual view rendering. - * - * @param {Event} e - */ - _onScroll: oncePerAnimationFrame(function(e) { - this.setState({ - scroll: Math.max(this.refs.tree.scrollTop, 0), - height: this.refs.tree.clientHeight - }); - }), - - /** - * Handles key down events in the tree's container. - * - * @param {Event} e - */ - _onKeyDown(e) { - if (this.props.focused == null) { - return; - } - - // Allow parent nodes to use navigation arrows with modifiers. - if (e.altKey || e.ctrlKey || e.shiftKey || e.metaKey) { - return; - } - - this._preventArrowKeyScrolling(e); - - switch (e.key) { - case "ArrowUp": - this._focusPrevNode(); - return; - - case "ArrowDown": - this._focusNextNode(); - return; - - case "ArrowLeft": - if (this.props.isExpanded(this.props.focused) - && this.props.getChildren(this.props.focused).length) { - this._onCollapse(this.props.focused); - } else { - this._focusParentNode(); - } - return; - - case "ArrowRight": - if (!this.props.isExpanded(this.props.focused)) { - this._onExpand(this.props.focused); - } else { - this._focusNextNode(); - } - return; - } - }, - - /** - * Sets the previous node relative to the currently focused item, to focused. - */ - _focusPrevNode: oncePerAnimationFrame(function() { - // Start a depth first search and keep going until we reach the currently - // focused node. Focus the previous node in the DFS, if it exists. If it - // doesn't exist, we're at the first node already. - - let prev; - let prevIndex; - - const traversal = this._dfsFromRoots(); - const length = traversal.length; - for (let i = 0; i < length; i++) { - const item = traversal[i].item; - if (item === this.props.focused) { - break; - } - prev = item; - prevIndex = i; - } - - if (prev === undefined) { - return; - } - - this._focus(prevIndex, prev); - }), - - /** - * Handles the down arrow key which will focus either the next child - * or sibling row. - */ - _focusNextNode: oncePerAnimationFrame(function() { - // Start a depth first search and keep going until we reach the currently - // focused node. Focus the next node in the DFS, if it exists. If it - // doesn't exist, we're at the last node already. - - const traversal = this._dfsFromRoots(); - const length = traversal.length; - let i = 0; - - while (i < length) { - if (traversal[i].item === this.props.focused) { - break; - } - i++; - } - - if (i + 1 < traversal.length) { - this._focus(i + 1, traversal[i + 1].item); - } - }), - - /** - * Handles the left arrow key, going back up to the current rows' - * parent row. - */ - _focusParentNode: oncePerAnimationFrame(function() { - const parent = this.props.getParent(this.props.focused); - if (!parent) { - return; - } - - const traversal = this._dfsFromRoots(); - const length = traversal.length; - let parentIndex = 0; - for (; parentIndex < length; parentIndex++) { - if (traversal[parentIndex].item === parent) { - break; - } - } - - this._focus(parentIndex, parent); - }), -}); diff --git a/packages/devtools-sham-modules/client/shared/key-shortcuts.js b/packages/devtools-sham-modules/client/shared/key-shortcuts.js deleted file mode 100644 index 7582fcbd4c..0000000000 --- a/packages/devtools-sham-modules/client/shared/key-shortcuts.js +++ /dev/null @@ -1,244 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -const { Services: { appinfo }} = require("devtools-modules"); -const EventEmitter = require("../../shared/event-emitter"); -const isOSX = appinfo.OS === "Darwin"; -"use strict"; - -// List of electron keys mapped to DOM API (DOM_VK_*) key code -const ElectronKeysMapping = { - "F1": "DOM_VK_F1", - "F2": "DOM_VK_F2", - "F3": "DOM_VK_F3", - "F4": "DOM_VK_F4", - "F5": "DOM_VK_F5", - "F6": "DOM_VK_F6", - "F7": "DOM_VK_F7", - "F8": "DOM_VK_F8", - "F9": "DOM_VK_F9", - "F10": "DOM_VK_F10", - "F11": "DOM_VK_F11", - "F12": "DOM_VK_F12", - "F13": "DOM_VK_F13", - "F14": "DOM_VK_F14", - "F15": "DOM_VK_F15", - "F16": "DOM_VK_F16", - "F17": "DOM_VK_F17", - "F18": "DOM_VK_F18", - "F19": "DOM_VK_F19", - "F20": "DOM_VK_F20", - "F21": "DOM_VK_F21", - "F22": "DOM_VK_F22", - "F23": "DOM_VK_F23", - "F24": "DOM_VK_F24", - "Space": "DOM_VK_SPACE", - "Backspace": "DOM_VK_BACK_SPACE", - "Delete": "DOM_VK_DELETE", - "Insert": "DOM_VK_INSERT", - "Return": "DOM_VK_RETURN", - "Enter": "DOM_VK_RETURN", - "Up": "DOM_VK_UP", - "Down": "DOM_VK_DOWN", - "Left": "DOM_VK_LEFT", - "Right": "DOM_VK_RIGHT", - "Home": "DOM_VK_HOME", - "End": "DOM_VK_END", - "PageUp": "DOM_VK_PAGE_UP", - "PageDown": "DOM_VK_PAGE_DOWN", - "Escape": "DOM_VK_ESCAPE", - "Esc": "DOM_VK_ESCAPE", - "Tab": "DOM_VK_TAB", - "VolumeUp": "DOM_VK_VOLUME_UP", - "VolumeDown": "DOM_VK_VOLUME_DOWN", - "VolumeMute": "DOM_VK_VOLUME_MUTE", - "PrintScreen": "DOM_VK_PRINTSCREEN", -}; - -/** - * Helper to listen for keyboard events decribed in .properties file. - * - * let shortcuts = new KeyShortcuts({ - * window - * }); - * shortcuts.on("Ctrl+F", event => { - * // `event` is the KeyboardEvent which relates to the key shortcuts - * }); - * - * @param DOMWindow window - * The window object of the document to listen events from. - * @param DOMElement target - * Optional DOM Element on which we should listen events from. - * If omitted, we listen for all events fired on `window`. - */ -function KeyShortcuts({ window, target }) { - this.window = window; - this.target = target || window; - this.keys = new Map(); - this.eventEmitter = new EventEmitter(); - this.target.addEventListener("keydown", this); -} - -/* - * Parse an electron-like key string and return a normalized object which - * allow efficient match on DOM key event. The normalized object matches DOM - * API. - * - * @param DOMWindow window - * Any DOM Window object, just to fetch its `KeyboardEvent` object - * @param String str - * The shortcut string to parse, following this document: - * https://github.com/electron/electron/blob/master/docs/api/accelerator.md - */ -KeyShortcuts.parseElectronKey = function(window, str) { - let modifiers = str.split("+"); - let key = modifiers.pop(); - - let shortcut = { - ctrl: false, - meta: false, - alt: false, - shift: false, - // Set for character keys - key: undefined, - // Set for non-character keys - keyCode: undefined, - }; - for (let mod of modifiers) { - if (mod === "Alt") { - shortcut.alt = true; - } else if (["Command", "Cmd"].includes(mod)) { - shortcut.meta = true; - } else if (["CommandOrControl", "CmdOrCtrl"].includes(mod)) { - if (isOSX) { - shortcut.meta = true; - } else { - shortcut.ctrl = true; - } - } else if (["Control", "Ctrl"].includes(mod)) { - shortcut.ctrl = true; - } else if (mod === "Shift") { - shortcut.shift = true; - } else { - console.error("Unsupported modifier:", mod, "from key:", str); - return null; - } - } - - // Plus is a special case. It's a character key and shouldn't be matched - // against a keycode as it is only accessible via Shift/Capslock - if (key === "Plus") { - key = "+"; - } - - if (typeof key === "string" && key.length === 1) { - // Match any single character - shortcut.key = key.toLowerCase(); - } else if (key in ElectronKeysMapping) { - // Maps the others manually to DOM API DOM_VK_* - key = ElectronKeysMapping[key]; - shortcut.keyCode = window.KeyboardEvent[key]; - // Used only to stringify the shortcut - shortcut.keyCodeString = key; - shortcut.key = key; - } else { - console.error("Unsupported key:", key); - return null; - } - - return shortcut; -}; - -KeyShortcuts.stringify = function(shortcut) { - let list = []; - if (shortcut.alt) { - list.push("Alt"); - } - if (shortcut.ctrl) { - list.push("Ctrl"); - } - if (shortcut.meta) { - list.push("Cmd"); - } - if (shortcut.shift) { - list.push("Shift"); - } - let key; - if (shortcut.key) { - key = shortcut.key.toUpperCase(); - } else { - key = shortcut.keyCodeString; - } - list.push(key); - return list.join("+"); -}; - -KeyShortcuts.prototype = { - destroy() { - this.target.removeEventListener("keydown", this); - this.keys.clear(); - }, - - doesEventMatchShortcut(event, shortcut) { - if (shortcut.meta != event.metaKey) { - return false; - } - if (shortcut.ctrl != event.ctrlKey) { - return false; - } - if (shortcut.alt != event.altKey) { - return false; - } - // Shift is a special modifier, it may implicitely be required if the - // expected key is a special character accessible via shift. - if (shortcut.shift != event.shiftKey && event.key && - event.key.match(/[a-zA-Z]/)) { - return false; - } - if (shortcut.keyCode) { - return event.keyCode == shortcut.keyCode; - } else if (event.key in ElectronKeysMapping) { - return ElectronKeysMapping[event.key] === shortcut.key; - } - - // get the key from the keyCode if key is not provided. - let key = event.key || String.fromCharCode(event.keyCode); - - // For character keys, we match if the final character is the expected one. - // But for digits we also accept indirect match to please azerty keyboard, - // which requires Shift to be pressed to get digits. - return key.toLowerCase() == shortcut.key || - (shortcut.key.match(/[0-9]/) && - event.keyCode == shortcut.key.charCodeAt(0)); - }, - - handleEvent(event) { - for (let [key, shortcut] of this.keys) { - if (this.doesEventMatchShortcut(event, shortcut)) { - this.eventEmitter.emit(key, event); - } - } - }, - - on(key, listener) { - if (typeof listener !== "function") { - throw new Error("KeyShortcuts.on() expects a function as " + - "second argument"); - } - if (!this.keys.has(key)) { - let shortcut = KeyShortcuts.parseElectronKey(this.window, key); - // The key string is wrong and we were unable to compute the key shortcut - if (!shortcut) { - return; - } - this.keys.set(key, shortcut); - } - this.eventEmitter.on(key, listener); - }, - - off(key, listener) { - this.eventEmitter.off(key, listener); - }, -}; -exports.KeyShortcuts = KeyShortcuts; diff --git a/packages/devtools-sham-modules/client/shared/prefs.js b/packages/devtools-sham-modules/client/shared/prefs.js deleted file mode 100644 index fcb880330c..0000000000 --- a/packages/devtools-sham-modules/client/shared/prefs.js +++ /dev/null @@ -1,177 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -const { Services } = require("devtools-modules"); -const EventEmitter = require("../../shared/event-emitter"); - -/** - * Shortcuts for lazily accessing and setting various preferences. - * Usage: - * let prefs = new Prefs("root.path.to.branch", { - * myIntPref: ["Int", "leaf.path.to.my-int-pref"], - * myCharPref: ["Char", "leaf.path.to.my-char-pref"], - * myJsonPref: ["Json", "leaf.path.to.my-json-pref"], - * myFloatPref: ["Float", "leaf.path.to.my-float-pref"] - * ... - * }); - * - * Get/set: - * prefs.myCharPref = "foo"; - * let aux = prefs.myCharPref; - * - * Observe: - * prefs.registerObserver(); - * prefs.on("pref-changed", (prefName, prefValue) => { - * ... - * }); - * - * @param string prefsRoot - * The root path to the required preferences branch. - * @param object prefsBlueprint - * An object containing { accessorName: [prefType, prefName] } keys. - */ -function PrefsHelper(prefsRoot = "", prefsBlueprint = {}) { - EventEmitter.decorate(this); - - let cache = new Map(); - - for (let accessorName in prefsBlueprint) { - let [prefType, prefName] = prefsBlueprint[accessorName]; - map(this, cache, accessorName, prefType, prefsRoot, prefName); - } - - let observer = makeObserver(this, cache, prefsRoot, prefsBlueprint); - this.registerObserver = () => observer.register(); - this.unregisterObserver = () => observer.unregister(); -} - -/** - * Helper method for getting a pref value. - * - * @param Map cache - * @param string prefType - * @param string prefsRoot - * @param string prefName - * @return any - */ -function get(cache, prefType, prefsRoot, prefName) { - let cachedPref = cache.get(prefName); - if (cachedPref !== undefined) { - return cachedPref; - } - let value = Services.prefs["get" + prefType + "Pref"]( - [prefsRoot, prefName].join(".") - ); - cache.set(prefName, value); - return value; -} - -/** - * Helper method for setting a pref value. - * - * @param Map cache - * @param string prefType - * @param string prefsRoot - * @param string prefName - * @param any value - */ -function set(cache, prefType, prefsRoot, prefName, value) { - Services.prefs["set" + prefType + "Pref"]( - [prefsRoot, prefName].join("."), - value - ); - cache.set(prefName, value); -} - -/** - * Maps a property name to a pref, defining lazy getters and setters. - * Supported types are "Bool", "Char", "Int", "Float" (sugar around "Char" - * type and casting), and "Json" (which is basically just sugar for "Char" - * using the standard JSON serializer). - * - * @param PrefsHelper self - * @param Map cache - * @param string accessorName - * @param string prefType - * @param string prefsRoot - * @param string prefName - * @param array serializer [optional] - */ -function map(self, cache, accessorName, prefType, prefsRoot, prefName, - serializer = { in: e => e, out: e => e }) { - if (prefName in self) { - throw new Error(`Can't use ${prefName} because it overrides a property` + - "on the instance."); - } - if (prefType == "Json") { - map(self, cache, accessorName, "Char", prefsRoot, prefName, { - in: JSON.parse, - out: JSON.stringify - }); - return; - } - if (prefType == "Float") { - map(self, cache, accessorName, "Char", prefsRoot, prefName, { - in: Number.parseFloat, - out: (n) => n + "" - }); - return; - } - - Object.defineProperty(self, accessorName, { - get: () => serializer.in(get(cache, prefType, prefsRoot, prefName)), - set: (e) => set(cache, prefType, prefsRoot, prefName, serializer.out(e)) - }); -} - -/** - * Finds the accessor for the provided pref, based on the blueprint object - * used in the constructor. - * - * @param PrefsHelper self - * @param object prefsBlueprint - * @return string - */ -function accessorNameForPref(somePrefName, prefsBlueprint) { - for (let accessorName in prefsBlueprint) { - let [, prefName] = prefsBlueprint[accessorName]; - if (somePrefName == prefName) { - return accessorName; - } - } - return ""; -} - -/** - * Creates a pref observer for `self`. - * - * @param PrefsHelper self - * @param Map cache - * @param string prefsRoot - * @param object prefsBlueprint - * @return object - */ -function makeObserver(self, cache, prefsRoot, prefsBlueprint) { - return { - register: function() { - this._branch = Services.prefs.getBranch(prefsRoot + "."); - this._branch.addObserver("", this, false); - }, - unregister: function() { - this._branch.removeObserver("", this); - }, - observe: function(subject, topic, prefName) { - // If this particular pref isn't handled by the blueprint object, - // even though it's in the specified branch, ignore it. - let accessorName = accessorNameForPref(prefName, prefsBlueprint); - if (!(accessorName in self)) { - return; - } - cache.delete(prefName); - self.emit("pref-changed", accessorName, self[accessorName]); - } - }; -} - -exports.PrefsHelper = PrefsHelper; diff --git a/packages/devtools-sham-modules/client/shared/source-utils.js b/packages/devtools-sham-modules/client/shared/source-utils.js deleted file mode 100644 index f2e76e40e6..0000000000 --- a/packages/devtools-sham-modules/client/shared/source-utils.js +++ /dev/null @@ -1,332 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -"use strict"; - -// const { LocalizationHelper } = require("devtools/shared/l10n"); -// -// const l10n = new LocalizationHelper("devtools/client/locales/components.properties"); -// const UNKNOWN_SOURCE_STRING = l10n.getStr("frame.unknownSource"); - -const l10n = { - getStr: () => {} -} - -// Character codes used in various parsing helper functions. -const CHAR_CODE_A = "a".charCodeAt(0); -const CHAR_CODE_C = "c".charCodeAt(0); -const CHAR_CODE_D = "d".charCodeAt(0); -const CHAR_CODE_E = "e".charCodeAt(0); -const CHAR_CODE_F = "f".charCodeAt(0); -const CHAR_CODE_H = "h".charCodeAt(0); -const CHAR_CODE_I = "i".charCodeAt(0); -const CHAR_CODE_J = "j".charCodeAt(0); -const CHAR_CODE_L = "l".charCodeAt(0); -const CHAR_CODE_M = "m".charCodeAt(0); -const CHAR_CODE_O = "o".charCodeAt(0); -const CHAR_CODE_P = "p".charCodeAt(0); -const CHAR_CODE_R = "r".charCodeAt(0); -const CHAR_CODE_S = "s".charCodeAt(0); -const CHAR_CODE_T = "t".charCodeAt(0); -const CHAR_CODE_U = "u".charCodeAt(0); -const CHAR_CODE_COLON = ":".charCodeAt(0); -const CHAR_CODE_SLASH = "/".charCodeAt(0); -const CHAR_CODE_CAP_S = "S".charCodeAt(0); - -// The cache used in the `parseURL` function. -const gURLStore = new Map(); -// The cache used in the `getSourceNames` function. -const gSourceNamesStore = new Map(); - -/** - * Takes a string and returns an object containing all the properties - * available on an URL instance, with additional properties (fileName), - * Leverages caching. - * - * @param {String} location - * @return {Object?} An object containing most properties available - * in https://developer.mozilla.org/en-US/docs/Web/API/URL - */ - -function parseURL(location) { - let url = gURLStore.get(location); - - if (url !== void 0) { - return url; - } - - try { - url = new URL(location); - // The callers were generally written to expect a URL from - // sdk/url, which is subtly different. So, work around some - // important differences here. - url = { - href: url.href, - protocol: url.protocol, - host: url.host, - hostname: url.hostname, - port: url.port || null, - pathname: url.pathname, - search: url.search, - hash: url.hash, - username: url.username, - password: url.password, - origin: url.origin, - }; - - // Definitions: - // Example: https://foo.com:8888/file.js - // `hostname`: "foo.com" - // `host`: "foo.com:8888" - let isChrome = isChromeScheme(location); - - url.fileName = url.pathname ? - (url.pathname.slice(url.pathname.lastIndexOf("/") + 1) || "/") : - "/"; - - if (isChrome) { - url.hostname = null; - url.host = null; - } - - gURLStore.set(location, url); - return url; - } catch (e) { - gURLStore.set(location, null); - return null; - } -} - -/** - * Parse a source into a short and long name as well as a host name. - * - * @param {String} source - * The source to parse. Can be a URI or names like "(eval)" or - * "self-hosted". - * @return {Object} - * An object with the following properties: - * - {String} short: A short name for the source. - * - "http://page.com/test.js#go?q=query" -> "test.js" - * - {String} long: The full, long name for the source, with - hash/query stripped. - * - "http://page.com/test.js#go?q=query" -> "http://page.com/test.js" - * - {String?} host: If available, the host name for the source. - * - "http://page.com/test.js#go?q=query" -> "page.com" - */ -function getSourceNames(source) { - let data = gSourceNamesStore.get(source); - - if (data) { - return data; - } - - let short, long, host; - const sourceStr = source ? String(source) : ""; - - // If `data:...` uri - if (isDataScheme(sourceStr)) { - let commaIndex = sourceStr.indexOf(","); - if (commaIndex > -1) { - // The `short` name for a data URI becomes `data:` followed by the actual - // encoded content, omitting the MIME type, and charset. - short = `data:${sourceStr.substring(commaIndex + 1)}`.slice(0, 100); - let result = { short, long: sourceStr }; - gSourceNamesStore.set(source, result); - return result; - } - } - - // If Scratchpad URI, like "Scratchpad/1"; no modifications, - // and short/long are the same. - if (isScratchpadScheme(sourceStr)) { - let result = { short: sourceStr, long: sourceStr }; - gSourceNamesStore.set(source, result); - return result; - } - - const parsedUrl = parseURL(sourceStr); - - if (!parsedUrl) { - // Malformed URI. - long = sourceStr; - short = sourceStr.slice(0, 100); - } else { - host = parsedUrl.host; - - long = parsedUrl.href; - if (parsedUrl.hash) { - long = long.replace(parsedUrl.hash, ""); - } - if (parsedUrl.search) { - long = long.replace(parsedUrl.search, ""); - } - - short = parsedUrl.fileName; - // If `short` is just a slash, and we actually have a path, - // strip the slash and parse again to get a more useful short name. - // e.g. "http://foo.com/bar/" -> "bar", rather than "/" - if (short === "/" && parsedUrl.pathname !== "/") { - short = parseURL(long.replace(/\/$/, "")).fileName; - } - } - - if (!short) { - if (!long) { - long = UNKNOWN_SOURCE_STRING; - } - short = long.slice(0, 100); - } - - let result = { short, long, host }; - gSourceNamesStore.set(source, result); - return result; -} - -// For the functions below, we assume that we will never access the location -// argument out of bounds, which is indeed the vast majority of cases. -// -// They are written this way because they are hot. Each frame is checked for -// being content or chrome when processing the profile. - -function isColonSlashSlash(location, i = 0) { - return location.charCodeAt(++i) === CHAR_CODE_COLON && - location.charCodeAt(++i) === CHAR_CODE_SLASH && - location.charCodeAt(++i) === CHAR_CODE_SLASH; -} - -/** - * Checks for a Scratchpad URI, like "Scratchpad/1" - */ -function isScratchpadScheme(location, i = 0) { - return location.charCodeAt(i) === CHAR_CODE_CAP_S && - location.charCodeAt(++i) === CHAR_CODE_C && - location.charCodeAt(++i) === CHAR_CODE_R && - location.charCodeAt(++i) === CHAR_CODE_A && - location.charCodeAt(++i) === CHAR_CODE_T && - location.charCodeAt(++i) === CHAR_CODE_C && - location.charCodeAt(++i) === CHAR_CODE_H && - location.charCodeAt(++i) === CHAR_CODE_P && - location.charCodeAt(++i) === CHAR_CODE_A && - location.charCodeAt(++i) === CHAR_CODE_D && - location.charCodeAt(++i) === CHAR_CODE_SLASH; -} - -function isDataScheme(location, i = 0) { - return location.charCodeAt(i) === CHAR_CODE_D && - location.charCodeAt(++i) === CHAR_CODE_A && - location.charCodeAt(++i) === CHAR_CODE_T && - location.charCodeAt(++i) === CHAR_CODE_A && - location.charCodeAt(++i) === CHAR_CODE_COLON; -} - -function isContentScheme(location, i = 0) { - let firstChar = location.charCodeAt(i); - - switch (firstChar) { - // "http://" or "https://" - case CHAR_CODE_H: - if (location.charCodeAt(++i) === CHAR_CODE_T && - location.charCodeAt(++i) === CHAR_CODE_T && - location.charCodeAt(++i) === CHAR_CODE_P) { - if (location.charCodeAt(i + 1) === CHAR_CODE_S) { - ++i; - } - return isColonSlashSlash(location, i); - } - return false; - - // "file://" - case CHAR_CODE_F: - if (location.charCodeAt(++i) === CHAR_CODE_I && - location.charCodeAt(++i) === CHAR_CODE_L && - location.charCodeAt(++i) === CHAR_CODE_E) { - return isColonSlashSlash(location, i); - } - return false; - - // "app://" - case CHAR_CODE_A: - if (location.charCodeAt(++i) == CHAR_CODE_P && - location.charCodeAt(++i) == CHAR_CODE_P) { - return isColonSlashSlash(location, i); - } - return false; - - default: - return false; - } -} - -function isChromeScheme(location, i = 0) { - let firstChar = location.charCodeAt(i); - - switch (firstChar) { - // "chrome://" - case CHAR_CODE_C: - if (location.charCodeAt(++i) === CHAR_CODE_H && - location.charCodeAt(++i) === CHAR_CODE_R && - location.charCodeAt(++i) === CHAR_CODE_O && - location.charCodeAt(++i) === CHAR_CODE_M && - location.charCodeAt(++i) === CHAR_CODE_E) { - return isColonSlashSlash(location, i); - } - return false; - - // "resource://" - case CHAR_CODE_R: - if (location.charCodeAt(++i) === CHAR_CODE_E && - location.charCodeAt(++i) === CHAR_CODE_S && - location.charCodeAt(++i) === CHAR_CODE_O && - location.charCodeAt(++i) === CHAR_CODE_U && - location.charCodeAt(++i) === CHAR_CODE_R && - location.charCodeAt(++i) === CHAR_CODE_C && - location.charCodeAt(++i) === CHAR_CODE_E) { - return isColonSlashSlash(location, i); - } - return false; - - // "jar:file://" - case CHAR_CODE_J: - if (location.charCodeAt(++i) === CHAR_CODE_A && - location.charCodeAt(++i) === CHAR_CODE_R && - location.charCodeAt(++i) === CHAR_CODE_COLON && - location.charCodeAt(++i) === CHAR_CODE_F && - location.charCodeAt(++i) === CHAR_CODE_I && - location.charCodeAt(++i) === CHAR_CODE_L && - location.charCodeAt(++i) === CHAR_CODE_E) { - return isColonSlashSlash(location, i); - } - return false; - - default: - return false; - } -} - -/** - * A utility method to get the file name from a sourcemapped location - * The sourcemap location can be in any form. This method returns a - * formatted file name for different cases like Windows or OSX. - * @param source - * @returns String - */ -function getSourceMappedFile(source) { - // If sourcemapped source is a OSX path, return - // the characters after last "/". - // If sourcemapped source is a Windowss path, return - // the characters after last "\\". - if (source.lastIndexOf("/") >= 0) { - source = source.slice(source.lastIndexOf("/") + 1); - } else if (source.lastIndexOf("\\") >= 0) { - source = source.slice(source.lastIndexOf("\\") + 1); - } - return source; -} - -exports.parseURL = parseURL; -exports.getSourceNames = getSourceNames; -exports.isScratchpadScheme = isScratchpadScheme; -exports.isChromeScheme = isChromeScheme; -exports.isContentScheme = isContentScheme; -exports.isDataScheme = isDataScheme; -exports.getSourceMappedFile = getSourceMappedFile; diff --git a/packages/devtools-sham-modules/index.js b/packages/devtools-sham-modules/index.js deleted file mode 100644 index 0aff1d9852..0000000000 --- a/packages/devtools-sham-modules/index.js +++ /dev/null @@ -1,31 +0,0 @@ -const { KeyShortcuts } = require("./client/shared/key-shortcuts"); -const { DebuggerTransport } = require("./transport/transport"); -const { DebuggerClient } = require("./shared/client/main"); -const PrefsHelper = require("./client/shared/prefs").PrefsHelper; -const { TargetFactory } = require("./client/framework/target"); -const DevToolsUtils = require("./shared/DevToolsUtils"); -const AppConstants = require("./sham/appconstants"); -const EventEmitter = require("./shared/event-emitter"); -const WebsocketTransport = require("./shared/transport/websocket-transport"); -const Menu = require("./client/framework/menu"); -const MenuItem = require("./client/framework/menu-item"); -const Tree = require("./client/shared/components/tree"); -const sourceUtils = require("./client/shared/source-utils"); -const frame = require("./client/shared/components/frame"); - -module.exports = { - KeyShortcuts, - PrefsHelper, - DebuggerClient, - DebuggerTransport, - TargetFactory, - DevToolsUtils, - AppConstants, - EventEmitter, - WebsocketTransport, - Menu, - MenuItem, - Tree, - sourceUtils, - frame -}; diff --git a/packages/devtools-sham-modules/package.json b/packages/devtools-sham-modules/package.json deleted file mode 100644 index a038ed4e2c..0000000000 --- a/packages/devtools-sham-modules/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "devtools-sham-modules", - "version": "0.0.9", - "description": "Shammed DevTools Modules from M-C", - "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "devDependencies": { - "devtools-modules": "^0.0.9" - }, - "author": "", - "license": "ISC" -} diff --git a/packages/devtools-sham-modules/preferences.js b/packages/devtools-sham-modules/preferences.js deleted file mode 100644 index e6aa80c0a3..0000000000 --- a/packages/devtools-sham-modules/preferences.js +++ /dev/null @@ -1,602 +0,0 @@ -module.exports = { - "devtools": { - "devedition": { - "promo": { - "shown": { - "value": false, - "type": 128 - }, - "url": { - "value": "https://www.mozilla.org/firefox/developer/?utm_source=firefox-dev-tools&utm_medium=firefox-browser&utm_content=betadoorhanger", - "type": 32 - }, - "enabled": { - "value": false, - "type": 128 - } - } - }, - "errorconsole": { - "enabled": { - "value": false, - "type": 128 - } - }, - "toolbar": { - "enabled": { - "value": true, - "type": 128 - }, - "visible": { - "value": false, - "type": 128 - } - }, - "webide": { - "enabled": { - "value": true, - "type": 128 - } - }, - "toolbox": { - "footer": { - "height": { - "value": 250, - "type": 64 - } - }, - "sidebar": { - "width": { - "value": 500, - "type": 64 - } - }, - "host": { - "value": "bottom", - "type": 32 - }, - "previousHost": { - "value": "side", - "type": 32 - }, - "selectedTool": { - "value": "webconsole", - "type": 32 - }, - "toolbarSpec": { - "value": "[\"splitconsole\", \"paintflashing toggle\",\"tilt toggle\",\"scratchpad\",\"resize toggle\",\"eyedropper\",\"screenshot --fullpage\", \"rulers\", \"measure\"]", - "type": 32 - }, - "sideEnabled": { - "value": true, - "type": 128 - }, - "zoomValue": { - "value": "1", - "type": 32 - }, - "splitconsoleEnabled": { - "value": false, - "type": 128 - }, - "splitconsoleHeight": { - "value": 100, - "type": 64 - } - }, - "inspector": { - "enabled": { - "value": true, - "type": 128 - }, - "activeSidebar": { - "value": "ruleview", - "type": 32 - }, - "remote": { - "value": false, - "type": 128 - }, - "show_pseudo_elements": { - "value": false, - "type": 128 - }, - "imagePreviewTooltipSize": { - "value": 300, - "type": 64 - }, - "showUserAgentStyles": { - "value": false, - "type": 128 - }, - "showAllAnonymousContent": { - "value": false, - "type": 128 - }, - "mdnDocsTooltip": { - "enabled": { - "value": true, - "type": 128 - } - } - }, - "defaultColorUnit": { - "value": "authored", - "type": 32 - }, - "debugger": { - "enabled": { - "value": true, - "type": 128 - }, - "workers": { - "value": false, - "type": 128 - }, - "promise": { - "value": false, - "type": 128 - } - }, - "memory": { - "enabled": { - "value": false, - "type": 128 - } - }, - "performance": { - "enabled": { - "value": true, - "type": 128 - }, - "ui": { - "experimental": { - "value": false, - "type": 128 - } - } - }, - "cache": { - "disabled": { - "value": false, - "type": 128 - } - }, - "serviceWorkers": { - "testing": { - "enabled": { - "value": false, - "type": 128 - } - } - }, - "netmonitor": { - "enabled": { - "value": true, - "type": 128 - }, - "statistics": { - "value": true, - "type": 128 - }, - "filters": { - "value": "[\"all\"]", - "type": 32 - }, - "har": { - "defaultLogDir": { - "value": "", - "type": 32 - }, - "defaultFileName": { - "value": "Archive %y-%m-%d %H-%M-%S", - "type": 32 - }, - "jsonp": { - "value": false, - "type": 128 - }, - "jsonpCallback": { - "value": "", - "type": 32 - }, - "includeResponseBodies": { - "value": true, - "type": 128 - }, - "compress": { - "value": false, - "type": 128 - }, - "forceExport": { - "value": false, - "type": 128 - }, - "pageLoadedTimeout": { - "value": 1500, - "type": 64 - }, - "enableAutoExportToFile": { - "value": false, - "type": 128 - } - } - }, - "tilt": { - "enabled": { - "value": true, - "type": 128 - }, - "intro_transition": { - "value": true, - "type": 128 - }, - "outro_transition": { - "value": true, - "type": 128 - } - }, - "scratchpad": { - "recentFilesMax": { - "value": 10, - "type": 64 - }, - "lineNumbers": { - "value": true, - "type": 128 - }, - "wrapText": { - "value": false, - "type": 128 - }, - "showTrailingSpace": { - "value": false, - "type": 128 - }, - "editorFontSize": { - "value": 12, - "type": 64 - }, - "enableAutocompletion": { - "value": true, - "type": 128 - } - }, - "storage": { - "enabled": { - "value": false, - "type": 128 - } - }, - "styleeditor": { - "enabled": { - "value": true, - "type": 128 - }, - "showMediaSidebar": { - "value": true, - "type": 128 - }, - "mediaSidebarWidth": { - "value": 238, - "type": 64 - }, - "navSidebarWidth": { - "value": 245, - "type": 64 - }, - "transitions": { - "value": true, - "type": 128 - } - }, - "shadereditor": { - "enabled": { - "value": false, - "type": 128 - } - }, - "canvasdebugger": { - "enabled": { - "value": false, - "type": 128 - } - }, - "webaudioeditor": { - "enabled": { - "value": false, - "type": 128 - }, - "inspectorWidth": { - "value": 300, - "type": 64 - } - }, - "webconsole": { - "filter": { - "network": { - "value": true, - "type": 128 - }, - "networkinfo": { - "value": false, - "type": 128 - }, - "netwarn": { - "value": true, - "type": 128 - }, - "netxhr": { - "value": false, - "type": 128 - }, - "csserror": { - "value": true, - "type": 128 - }, - "cssparser": { - "value": false, - "type": 128 - }, - "csslog": { - "value": false, - "type": 128 - }, - "exception": { - "value": true, - "type": 128 - }, - "jswarn": { - "value": true, - "type": 128 - }, - "jslog": { - "value": false, - "type": 128 - }, - "error": { - "value": true, - "type": 128 - }, - "warn": { - "value": true, - "type": 128 - }, - "info": { - "value": true, - "type": 128 - }, - "log": { - "value": true, - "type": 128 - }, - "secerror": { - "value": true, - "type": 128 - }, - "secwarn": { - "value": true, - "type": 128 - }, - "serviceworkers": { - "value": true, - "type": 128 - }, - "sharedworkers": { - "value": false, - "type": 128 - }, - "windowlessworkers": { - "value": false, - "type": 128 - }, - "servererror": { - "value": false, - "type": 128 - }, - "serverwarn": { - "value": false, - "type": 128 - }, - "serverinfo": { - "value": false, - "type": 128 - }, - "serverlog": { - "value": false, - "type": 128 - } - }, - "fontSize": { - "value": 0, - "type": 64 - }, - "inputHistoryCount": { - "value": 50, - "type": 64 - }, - "persistlog": { - "value": false, - "type": 128 - }, - "timestampMessages": { - "value": false, - "type": 128 - } - }, - "browserconsole": { - "filter": { - "network": { - "value": true, - "type": 128 - }, - "networkinfo": { - "value": false, - "type": 128 - }, - "netwarn": { - "value": true, - "type": 128 - }, - "netxhr": { - "value": false, - "type": 128 - }, - "csserror": { - "value": true, - "type": 128 - }, - "cssparser": { - "value": false, - "type": 128 - }, - "csslog": { - "value": false, - "type": 128 - }, - "exception": { - "value": true, - "type": 128 - }, - "jswarn": { - "value": true, - "type": 128 - }, - "jslog": { - "value": true, - "type": 128 - }, - "error": { - "value": true, - "type": 128 - }, - "warn": { - "value": true, - "type": 128 - }, - "info": { - "value": true, - "type": 128 - }, - "log": { - "value": true, - "type": 128 - }, - "secerror": { - "value": true, - "type": 128 - }, - "secwarn": { - "value": true, - "type": 128 - }, - "serviceworkers": { - "value": true, - "type": 128 - }, - "sharedworkers": { - "value": true, - "type": 128 - }, - "windowlessworkers": { - "value": true, - "type": 128 - }, - "servererror": { - "value": false, - "type": 128 - }, - "serverwarn": { - "value": false, - "type": 128 - }, - "serverinfo": { - "value": false, - "type": 128 - }, - "serverlog": { - "value": false, - "type": 128 - } - } - }, - "hud": { - "loglimit": { - "network": { - "value": 1000, - "type": 64 - }, - "cssparser": { - "value": 1000, - "type": 64 - }, - "exception": { - "value": 1000, - "type": 64 - }, - "console": { - "value": 1000, - "type": 64 - } - } - }, - "eyedropper": { - "zoom": { - "value": 6, - "type": 64 - } - }, - "editor": { - "tabsize": { - "value": 2, - "type": 64 - }, - "expandtab": { - "value": true, - "type": 128 - }, - "keymap": { - "value": "default", - "type": 32 - }, - "autoclosebrackets": { - "value": true, - "type": 128 - }, - "detectindentation": { - "value": true, - "type": 128 - }, - "enableCodeFolding": { - "value": true, - "type": 128 - }, - "autocomplete": { - "value": true, - "type": 128 - } - }, - "fontinspector": { - "enabled": { - "value": true, - "type": 128 - } - }, - "telemetry": { - "tools": { - "opened": { - "version": { - "value": "{}", - "type": 32 - } - } - } - }, - "jsonview": { - "enabled": { - "value": false, - "type": 128 - } - } - } -} diff --git a/packages/devtools-sham-modules/sdk/core/namespace.js b/packages/devtools-sham-modules/sdk/core/namespace.js deleted file mode 100644 index 3ceb73b72b..0000000000 --- a/packages/devtools-sham-modules/sdk/core/namespace.js +++ /dev/null @@ -1,43 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -module.metadata = { - "stability": "unstable" -}; - -const create = Object.create; -const prototypeOf = Object.getPrototypeOf; - -/** - * Returns a new namespace, function that may can be used to access an - * namespaced object of the argument argument. Namespaced object are associated - * with owner objects via weak references. Namespaced objects inherit from the - * owners ancestor namespaced object. If owner's ancestor is `null` then - * namespaced object inherits from given `prototype`. Namespaces can be used - * to define internal APIs that can be shared via enclosing `namespace` - * function. - * @examples - * const internals = ns(); - * internals(object).secret = secret; - */ -function ns() { - const map = new WeakMap(); - return function namespace(target) { - if (!target) // If `target` is not an object return `target` itself. - return target; - // If target has no namespaced object yet, create one that inherits from - // the target prototype's namespaced object. - if (!map.has(target)) - map.set(target, create(namespace(prototypeOf(target) || null))); - - return map.get(target); - }; -}; - -// `Namespace` is a e4x function in the scope, so we export the function also as -// `ns` as alias to avoid clashing. -exports.ns = ns; -exports.Namespace = ns; diff --git a/packages/devtools-sham-modules/sdk/event/core.js b/packages/devtools-sham-modules/sdk/event/core.js deleted file mode 100644 index c16dd2df57..0000000000 --- a/packages/devtools-sham-modules/sdk/event/core.js +++ /dev/null @@ -1,193 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -"use strict"; - -module.metadata = { - "stability": "unstable" -}; - -const UNCAUGHT_ERROR = 'An error event was emitted for which there was no listener.'; -const BAD_LISTENER = 'The event listener must be a function.'; - -const { ns } = require('../core/namespace'); - -const event = ns(); - -const EVENT_TYPE_PATTERN = /^on([A-Z]\w+$)/; -exports.EVENT_TYPE_PATTERN = EVENT_TYPE_PATTERN; - -// Utility function to access given event `target` object's event listeners for -// the specific event `type`. If listeners for this type does not exists they -// will be created. -const observers = function observers(target, type) { - if (!target) throw TypeError("Event target must be an object"); - let listeners = event(target); - return type in listeners ? listeners[type] : listeners[type] = []; -}; - -/** - * Registers an event `listener` that is called every time events of - * specified `type` is emitted on the given event `target`. - * @param {Object} target - * Event target object. - * @param {String} type - * The type of event. - * @param {Function} listener - * The listener function that processes the event. - */ -function on(target, type, listener) { - if (typeof(listener) !== 'function') - throw new Error(BAD_LISTENER); - - let listeners = observers(target, type); - if (!~listeners.indexOf(listener)) - listeners.push(listener); -} -exports.on = on; - - -var onceWeakMap = new WeakMap(); - - -/** - * Registers an event `listener` that is called only the next time an event - * of the specified `type` is emitted on the given event `target`. - * @param {Object} target - * Event target object. - * @param {String} type - * The type of the event. - * @param {Function} listener - * The listener function that processes the event. - */ -function once(target, type, listener) { - let replacement = function observer(...args) { - off(target, type, observer); - onceWeakMap.delete(listener); - listener.apply(target, args); - }; - onceWeakMap.set(listener, replacement); - on(target, type, replacement); -} -exports.once = once; - -/** - * Execute each of the listeners in order with the supplied arguments. - * All the exceptions that are thrown by listeners during the emit - * are caught and can be handled by listeners of 'error' event. Thrown - * exceptions are passed as an argument to an 'error' event listener. - * If no 'error' listener is registered exception will be logged into an - * error console. - * @param {Object} target - * Event target object. - * @param {String} type - * The type of event. - * @params {Object|Number|String|Boolean} args - * Arguments that will be passed to listeners. - */ -function emit (target, type, ...args) { - emitOnObject(target, type, target, ...args); -} -exports.emit = emit; - -/** - * A variant of emit that allows setting the this property for event listeners - */ -function emitOnObject(target, type, thisArg, ...args) { - let all = observers(target, '*').length; - let state = observers(target, type); - let listeners = state.slice(); - let count = listeners.length; - let index = 0; - - // If error event and there are no handlers (explicit or catch-all) - // then print error message to the console. - if (count === 0 && type === 'error' && all === 0) - console.exception(args[0]); - while (index < count) { - try { - let listener = listeners[index]; - // Dispatch only if listener is still registered. - if (~state.indexOf(listener)) - listener.apply(thisArg, args); - } - catch (error) { - // If exception is not thrown by a error listener and error listener is - // registered emit `error` event. Otherwise dump exception to the console. - if (type !== 'error') emit(target, 'error', error); - else console.exception(error); - } - index++; - } - // Also emit on `"*"` so that one could listen for all events. - if (type !== '*') emit(target, '*', type, ...args); -} -exports.emitOnObject = emitOnObject; - -/** - * Removes an event `listener` for the given event `type` on the given event - * `target`. If no `listener` is passed removes all listeners of the given - * `type`. If `type` is not passed removes all the listeners of the given - * event `target`. - * @param {Object} target - * The event target object. - * @param {String} type - * The type of event. - * @param {Function} listener - * The listener function that processes the event. - */ -function off(target, type, listener) { - let length = arguments.length; - if (length === 3) { - if (onceWeakMap.has(listener)) { - listener = onceWeakMap.get(listener); - onceWeakMap.delete(listener); - } - - let listeners = observers(target, type); - let index = listeners.indexOf(listener); - if (~index) - listeners.splice(index, 1); - } - else if (length === 2) { - observers(target, type).splice(0); - } - else if (length === 1) { - let listeners = event(target); - Object.keys(listeners).forEach(type => delete listeners[type]); - } -} -exports.off = off; - -/** - * Returns a number of event listeners registered for the given event `type` - * on the given event `target`. - */ -function count(target, type) { - return observers(target, type).length; -} -exports.count = count; - -/** - * Registers listeners on the given event `target` from the given `listeners` - * dictionary. Iterates over the listeners and if property name matches name - * pattern `onEventType` and property is a function, then registers it as - * an `eventType` listener on `target`. - * - * @param {Object} target - * The type of event. - * @param {Object} listeners - * Dictionary of listeners. - */ -function setListeners(target, listeners) { - Object.keys(listeners || {}).forEach(key => { - let match = EVENT_TYPE_PATTERN.exec(key); - let type = match && match[1].toLowerCase(); - if (!type) return; - - let listener = listeners[key]; - if (typeof(listener) === 'function') - on(target, type, listener); - }); -} -exports.setListeners = setListeners; diff --git a/packages/devtools-sham-modules/sham/appconstants.js b/packages/devtools-sham-modules/sham/appconstants.js deleted file mode 100644 index 7177306e4c..0000000000 --- a/packages/devtools-sham-modules/sham/appconstants.js +++ /dev/null @@ -1,5 +0,0 @@ -/* - * A sham for https://dxr.mozilla.org/mozilla-central/source/toolkit/modules/AppConstants.jsm - */ - -module.exports = { AppConstants: {} }; diff --git a/packages/devtools-sham-modules/sham/chrome.js b/packages/devtools-sham-modules/sham/chrome.js deleted file mode 100644 index 61ea8107d8..0000000000 --- a/packages/devtools-sham-modules/sham/chrome.js +++ /dev/null @@ -1,63 +0,0 @@ -/* - * A sham for https://developer.mozilla.org/en-US/Add-ons/SDK/Low-Level_APIs/chrome - */ - -var { inDOMUtils } = require("./inDOMUtils"); - -var ourServices = { - inIDOMUtils: inDOMUtils, - nsIClipboardHelper: { - copyString: () => {} - }, - nsIXULChromeRegistry: { - isLocaleRTL: () => {return false;} - }, - nsIDOMParser: { - - }, -}; - -module.exports = { - Cc: name => { - if(typeof console !== "undefined") { - console.log('Cc sham for', name); - } - return { - getService: (name) => ourServices[name], - createInstance: (iface) => ourServices[iface], - }; - }, - CC: (name, iface, method) => { - if(typeof console !== "undefined") { - console.log('CC sham for', name, iface, method); - } - return { - }; - }, - Ci: { - nsIThread: { - "DISPATCH_NORMAL":0, - "DISPATCH_SYNC":1 - }, - nsIDOMNode: typeof HTMLElement !== "undefined" ? HTMLElement : null, - nsIFocusManager: { - MOVEFOCUS_BACKWARD: 2, - MOVEFOCUS_FORWARD: 1, - }, - nsIDOMKeyEvent: { - - }, - nsIDOMCSSRule: {"UNKNOWN_RULE":0,"STYLE_RULE":1,"CHARSET_RULE":2,"IMPORT_RULE":3,"MEDIA_RULE":4,"FONT_FACE_RULE":5,"PAGE_RULE":6,"KEYFRAMES_RULE":7,"KEYFRAME_RULE":8,"MOZ_KEYFRAMES_RULE":7,"MOZ_KEYFRAME_RULE":8,"NAMESPACE_RULE":10,"COUNTER_STYLE_RULE":11,"SUPPORTS_RULE":12,"FONT_FEATURE_VALUES_RULE":14}, - inIDOMUtils: "inIDOMUtils", - nsIClipboardHelper: "nsIClipboardHelper", - nsIXULChromeRegistry: "nsIXULChromeRegistry", - }, - Cu: { - reportError: msg => { (typeof console !== "undefined") ? console.error(msg) : dump(msg) }, - callFunctionWithAsyncStack: fn => fn(), - }, - Cr: {}, - components: { - isSuccessCode: () => (returnCode & 0x80000000) === 0, - } -}; diff --git a/packages/devtools-sham-modules/sham/css-color-db.js b/packages/devtools-sham-modules/sham/css-color-db.js deleted file mode 100644 index 517310f718..0000000000 --- a/packages/devtools-sham-modules/sham/css-color-db.js +++ /dev/null @@ -1,152 +0,0 @@ -// auto-generated from nsColorNameList.h -var cssColors = { - aliceblue: [240, 248, 255], - antiquewhite: [250, 235, 215], - aqua: [0, 255, 255], - aquamarine: [127, 255, 212], - azure: [240, 255, 255], - beige: [245, 245, 220], - bisque: [255, 228, 196], - black: [0, 0, 0], - blanchedalmond: [255, 235, 205], - blue: [0, 0, 255], - blueviolet: [138, 43, 226], - brown: [165, 42, 42], - burlywood: [222, 184, 135], - cadetblue: [95, 158, 160], - chartreuse: [127, 255, 0], - chocolate: [210, 105, 30], - coral: [255, 127, 80], - cornflowerblue: [100, 149, 237], - cornsilk: [255, 248, 220], - crimson: [220, 20, 60], - cyan: [0, 255, 255], - darkblue: [0, 0, 139], - darkcyan: [0, 139, 139], - darkgoldenrod: [184, 134, 11], - darkgray: [169, 169, 169], - darkgreen: [0, 100, 0], - darkgrey: [169, 169, 169], - darkkhaki: [189, 183, 107], - darkmagenta: [139, 0, 139], - darkolivegreen: [85, 107, 47], - darkorange: [255, 140, 0], - darkorchid: [153, 50, 204], - darkred: [139, 0, 0], - darksalmon: [233, 150, 122], - darkseagreen: [143, 188, 143], - darkslateblue: [72, 61, 139], - darkslategray: [47, 79, 79], - darkslategrey: [47, 79, 79], - darkturquoise: [0, 206, 209], - darkviolet: [148, 0, 211], - deeppink: [255, 20, 147], - deepskyblue: [0, 191, 255], - dimgray: [105, 105, 105], - dimgrey: [105, 105, 105], - dodgerblue: [30, 144, 255], - firebrick: [178, 34, 34], - floralwhite: [255, 250, 240], - forestgreen: [34, 139, 34], - fuchsia: [255, 0, 255], - gainsboro: [220, 220, 220], - ghostwhite: [248, 248, 255], - gold: [255, 215, 0], - goldenrod: [218, 165, 32], - gray: [128, 128, 128], - grey: [128, 128, 128], - green: [0, 128, 0], - greenyellow: [173, 255, 47], - honeydew: [240, 255, 240], - hotpink: [255, 105, 180], - indianred: [205, 92, 92], - indigo: [75, 0, 130], - ivory: [255, 255, 240], - khaki: [240, 230, 140], - lavender: [230, 230, 250], - lavenderblush: [255, 240, 245], - lawngreen: [124, 252, 0], - lemonchiffon: [255, 250, 205], - lightblue: [173, 216, 230], - lightcoral: [240, 128, 128], - lightcyan: [224, 255, 255], - lightgoldenrodyellow: [250, 250, 210], - lightgray: [211, 211, 211], - lightgreen: [144, 238, 144], - lightgrey: [211, 211, 211], - lightpink: [255, 182, 193], - lightsalmon: [255, 160, 122], - lightseagreen: [32, 178, 170], - lightskyblue: [135, 206, 250], - lightslategray: [119, 136, 153], - lightslategrey: [119, 136, 153], - lightsteelblue: [176, 196, 222], - lightyellow: [255, 255, 224], - lime: [0, 255, 0], - limegreen: [50, 205, 50], - linen: [250, 240, 230], - magenta: [255, 0, 255], - maroon: [128, 0, 0], - mediumaquamarine: [102, 205, 170], - mediumblue: [0, 0, 205], - mediumorchid: [186, 85, 211], - mediumpurple: [147, 112, 219], - mediumseagreen: [60, 179, 113], - mediumslateblue: [123, 104, 238], - mediumspringgreen: [0, 250, 154], - mediumturquoise: [72, 209, 204], - mediumvioletred: [199, 21, 133], - midnightblue: [25, 25, 112], - mintcream: [245, 255, 250], - mistyrose: [255, 228, 225], - moccasin: [255, 228, 181], - navajowhite: [255, 222, 173], - navy: [0, 0, 128], - oldlace: [253, 245, 230], - olive: [128, 128, 0], - olivedrab: [107, 142, 35], - orange: [255, 165, 0], - orangered: [255, 69, 0], - orchid: [218, 112, 214], - palegoldenrod: [238, 232, 170], - palegreen: [152, 251, 152], - paleturquoise: [175, 238, 238], - palevioletred: [219, 112, 147], - papayawhip: [255, 239, 213], - peachpuff: [255, 218, 185], - peru: [205, 133, 63], - pink: [255, 192, 203], - plum: [221, 160, 221], - powderblue: [176, 224, 230], - purple: [128, 0, 128], - rebeccapurple: [102, 51, 153], - red: [255, 0, 0], - rosybrown: [188, 143, 143], - royalblue: [65, 105, 225], - saddlebrown: [139, 69, 19], - salmon: [250, 128, 114], - sandybrown: [244, 164, 96], - seagreen: [46, 139, 87], - seashell: [255, 245, 238], - sienna: [160, 82, 45], - silver: [192, 192, 192], - skyblue: [135, 206, 235], - slateblue: [106, 90, 205], - slategray: [112, 128, 144], - slategrey: [112, 128, 144], - snow: [255, 250, 250], - springgreen: [0, 255, 127], - steelblue: [70, 130, 180], - tan: [210, 180, 140], - teal: [0, 128, 128], - thistle: [216, 191, 216], - tomato: [255, 99, 71], - turquoise: [64, 224, 208], - violet: [238, 130, 238], - wheat: [245, 222, 179], - white: [255, 255, 255], - whitesmoke: [245, 245, 245], - yellow: [255, 255, 0], - yellowgreen: [154, 205, 50], -}; -module.exports = { cssColors }; diff --git a/packages/devtools-sham-modules/sham/css-property-db.js b/packages/devtools-sham-modules/sham/css-property-db.js deleted file mode 100644 index c89f654d60..0000000000 --- a/packages/devtools-sham-modules/sham/css-property-db.js +++ /dev/null @@ -1,2133 +0,0 @@ -// auto-generated by means you would rather not know -var cssProperties = { - "-moz-appearance": { - inherited: false, - supports: 0, - values: ["-moz-gtk-info-bar", "-moz-mac-disclosure-button-closed", "-moz-mac-disclosure-button-open", "-moz-mac-fullscreen-button", "-moz-mac-help-button", "-moz-mac-vibrancy-dark", "-moz-mac-vibrancy-light", "-moz-win-borderless-glass", "-moz-win-browsertabbar-toolbox", "-moz-win-communications-toolbox", "-moz-win-exclude-glass", "-moz-win-glass", "-moz-win-media-toolbox", "-moz-window-button-box", "-moz-window-button-box-maximized", "-moz-window-button-close", "-moz-window-button-maximize", "-moz-window-button-minimize", "-moz-window-button-restore", "-moz-window-frame-bottom", "-moz-window-frame-left", "-moz-window-frame-right", "-moz-window-titlebar", "-moz-window-titlebar-maximized", "button", "button-arrow-down", "button-arrow-next", "button-arrow-previous", "button-arrow-up", "button-bevel", "button-focus", "caret", "checkbox", "checkbox-container", "checkbox-label", "checkmenuitem", "dialog", "dualbutton", "groupbox", "inherit", "initial", "listbox", "listitem", "menuarrow", "menubar", "menucheckbox", "menuimage", "menuitem", "menuitemtext", "menulist", "menulist-button", "menulist-text", "menulist-textfield", "menupopup", "menuradio", "menuseparator", "meterbar", "meterchunk", "none", "number-input", "progressbar", "progressbar-vertical", "progresschunk", "progresschunk-vertical", "radio", "radio-container", "radio-label", "radiomenuitem", "range", "range-thumb", "resizer", "resizerpanel", "scale-horizontal", "scale-vertical", "scalethumb-horizontal", "scalethumb-vertical", "scalethumbend", "scalethumbstart", "scalethumbtick", "scrollbar", "scrollbar-small", "scrollbarbutton-down", "scrollbarbutton-left", "scrollbarbutton-right", "scrollbarbutton-up", "scrollbarthumb-horizontal", "scrollbarthumb-vertical", "scrollbartrack-horizontal", "scrollbartrack-vertical", "searchfield", "separator", "spinner", "spinner-downbutton", "spinner-textfield", "spinner-upbutton", "splitter", "statusbar", "statusbarpanel", "tab", "tab-scroll-arrow-back", "tab-scroll-arrow-forward", "tabpanel", "tabpanels", "textfield", "textfield-multiline", "toolbar", "toolbarbutton", "toolbarbutton-dropdown", "toolbargripper", "toolbox", "tooltip", "treeheader", "treeheadercell", "treeheadersortarrow", "treeitem", "treeline", "treetwisty", "treetwistyopen", "treeview", "unset", "window", ], - }, - "-moz-outline-radius-topleft": { - inherited: false, - supports: 3, - values: ["inherit", "initial", "unset", ], - }, - "-moz-outline-radius-topright": { - inherited: false, - supports: 3, - values: ["inherit", "initial", "unset", ], - }, - "-moz-outline-radius-bottomright": { - inherited: false, - supports: 3, - values: ["inherit", "initial", "unset", ], - }, - "-moz-outline-radius-bottomleft": { - inherited: false, - supports: 3, - values: ["inherit", "initial", "unset", ], - }, - "-moz-tab-size": { - inherited: true, - supports: 1024, - values: ["inherit", "initial", "unset", ], - }, - "animation-delay": { - inherited: false, - supports: 64, - values: ["inherit", "initial", "unset", ], - }, - "animation-direction": { - inherited: false, - supports: 0, - values: ["alternate", "alternate-reverse", "inherit", "initial", "normal", "reverse", "unset", ], - }, - "animation-duration": { - inherited: false, - supports: 64, - values: ["inherit", "initial", "unset", ], - }, - "animation-fill-mode": { - inherited: false, - supports: 0, - values: ["backwards", "both", "forwards", "inherit", "initial", "none", "unset", ], - }, - "animation-iteration-count": { - inherited: false, - supports: 1024, - values: ["infinite", "inherit", "initial", "unset", ], - }, - "animation-name": { - inherited: false, - supports: 0, - values: ["inherit", "initial", "none", "unset", ], - }, - "animation-play-state": { - inherited: false, - supports: 0, - values: ["inherit", "initial", "paused", "running", "unset", ], - }, - "animation-timing-function": { - inherited: false, - supports: 256, - values: ["cubic-bezier", "ease", "ease-in", "ease-in-out", "ease-out", "inherit", "initial", "linear", "step-end", "step-start", "steps", "unset", ], - }, - "background-attachment": { - inherited: false, - supports: 0, - values: ["fixed", "inherit", "initial", "local", "scroll", "unset", ], - }, - "background-clip": { - inherited: false, - supports: 0, - values: ["border-box", "content-box", "inherit", "initial", "padding-box", "unset", ], - }, - "background-color": { - inherited: false, - supports: 4, - values: ["aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", "maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "rebeccapurple", "red", "rgb", "rgba", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "springgreen", "steelblue", "tan", "teal", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], - }, - "background-image": { - inherited: false, - supports: 648, - values: ["-moz-element", "-moz-image-rect", "-moz-linear-gradient", "-moz-radial-gradient", "-moz-repeating-linear-gradient", "-moz-repeating-radial-gradient", "inherit", "initial", "linear-gradient", "none", "radial-gradient", "repeating-linear-gradient", "repeating-radial-gradient", "unset", "url", ], - }, - "background-blend-mode": { - inherited: false, - supports: 0, - values: ["color", "color-burn", "color-dodge", "darken", "difference", "exclusion", "hard-light", "hue", "inherit", "initial", "lighten", "luminosity", "multiply", "normal", "overlay", "saturation", "screen", "soft-light", "unset", ], - }, - "background-origin": { - inherited: false, - supports: 0, - values: ["border-box", "content-box", "inherit", "initial", "padding-box", "unset", ], - }, - "background-position": { - inherited: false, - supports: 3, - values: ["inherit", "initial", "unset", ], - }, - "background-repeat": { - inherited: false, - supports: 0, - values: ["inherit", "initial", "no-repeat", "repeat", "repeat-x", "repeat-y", "unset", ], - }, - "background-size": { - inherited: false, - supports: 3, - values: ["inherit", "initial", "unset", ], - }, - "-moz-binding": { - inherited: false, - supports: 8, - values: ["inherit", "initial", "none", "unset", "url", ], - }, - "block-size": { - inherited: false, - supports: 3, - values: ["-moz-calc", "auto", "calc", "inherit", "initial", "unset", ], - }, - "border-block-end-color": { - inherited: false, - supports: 4, - values: ["-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", "maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "rebeccapurple", "red", "rgb", "rgba", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "springgreen", "steelblue", "tan", "teal", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], - }, - "border-block-end-style": { - inherited: false, - supports: 0, - values: ["dashed", "dotted", "double", "groove", "hidden", "inherit", "initial", "inset", "none", "outset", "ridge", "solid", "unset", ], - }, - "border-block-end-width": { - inherited: false, - supports: 1, - values: ["-moz-calc", "calc", "inherit", "initial", "medium", "thick", "thin", "unset", ], - }, - "border-block-start-color": { - inherited: false, - supports: 4, - values: ["-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", "maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "rebeccapurple", "red", "rgb", "rgba", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "springgreen", "steelblue", "tan", "teal", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], - }, - "border-block-start-style": { - inherited: false, - supports: 0, - values: ["dashed", "dotted", "double", "groove", "hidden", "inherit", "initial", "inset", "none", "outset", "ridge", "solid", "unset", ], - }, - "border-block-start-width": { - inherited: false, - supports: 1, - values: ["-moz-calc", "calc", "inherit", "initial", "medium", "thick", "thin", "unset", ], - }, - "border-bottom-color": { - inherited: false, - supports: 4, - values: ["-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", "maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "rebeccapurple", "red", "rgb", "rgba", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "springgreen", "steelblue", "tan", "teal", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], - }, - "-moz-border-bottom-colors": { - inherited: false, - supports: 4, - values: ["inherit", "initial", "unset", ], - }, - "border-bottom-style": { - inherited: false, - supports: 0, - values: ["dashed", "dotted", "double", "groove", "hidden", "inherit", "initial", "inset", "none", "outset", "ridge", "solid", "unset", ], - }, - "border-bottom-width": { - inherited: false, - supports: 1, - values: ["-moz-calc", "calc", "inherit", "initial", "medium", "thick", "thin", "unset", ], - }, - "border-collapse": { - inherited: true, - supports: 0, - values: ["collapse", "inherit", "initial", "separate", "unset", ], - }, - "border-image-source": { - inherited: false, - supports: 648, - values: ["-moz-element", "-moz-image-rect", "-moz-linear-gradient", "-moz-radial-gradient", "-moz-repeating-linear-gradient", "-moz-repeating-radial-gradient", "inherit", "initial", "linear-gradient", "none", "radial-gradient", "repeating-linear-gradient", "repeating-radial-gradient", "unset", "url", ], - }, - "border-image-slice": { - inherited: false, - supports: 1026, - values: ["inherit", "initial", "unset", ], - }, - "border-image-width": { - inherited: false, - supports: 1027, - values: ["inherit", "initial", "unset", ], - }, - "border-image-outset": { - inherited: false, - supports: 1025, - values: ["inherit", "initial", "unset", ], - }, - "border-image-repeat": { - inherited: false, - supports: 0, - values: ["inherit", "initial", "unset", ], - }, - "border-inline-end-color": { - inherited: false, - supports: 4, - values: ["-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", "maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "rebeccapurple", "red", "rgb", "rgba", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "springgreen", "steelblue", "tan", "teal", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], - }, - "border-inline-end-style": { - inherited: false, - supports: 0, - values: ["dashed", "dotted", "double", "groove", "hidden", "inherit", "initial", "inset", "none", "outset", "ridge", "solid", "unset", ], - }, - "border-inline-end-width": { - inherited: false, - supports: 1, - values: ["-moz-calc", "calc", "inherit", "initial", "medium", "thick", "thin", "unset", ], - }, - "border-inline-start-color": { - inherited: false, - supports: 4, - values: ["-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", "maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "rebeccapurple", "red", "rgb", "rgba", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "springgreen", "steelblue", "tan", "teal", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], - }, - "border-inline-start-style": { - inherited: false, - supports: 0, - values: ["dashed", "dotted", "double", "groove", "hidden", "inherit", "initial", "inset", "none", "outset", "ridge", "solid", "unset", ], - }, - "border-inline-start-width": { - inherited: false, - supports: 1, - values: ["-moz-calc", "calc", "inherit", "initial", "medium", "thick", "thin", "unset", ], - }, - "border-left-color": { - inherited: false, - supports: 4, - values: ["-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", "maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "rebeccapurple", "red", "rgb", "rgba", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "springgreen", "steelblue", "tan", "teal", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], - }, - "-moz-border-left-colors": { - inherited: false, - supports: 4, - values: ["inherit", "initial", "unset", ], - }, - "border-left-style": { - inherited: false, - supports: 0, - values: ["dashed", "dotted", "double", "groove", "hidden", "inherit", "initial", "inset", "none", "outset", "ridge", "solid", "unset", ], - }, - "border-left-width": { - inherited: false, - supports: 1, - values: ["-moz-calc", "calc", "inherit", "initial", "medium", "thick", "thin", "unset", ], - }, - "border-right-color": { - inherited: false, - supports: 4, - values: ["-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", "maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "rebeccapurple", "red", "rgb", "rgba", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "springgreen", "steelblue", "tan", "teal", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], - }, - "-moz-border-right-colors": { - inherited: false, - supports: 4, - values: ["inherit", "initial", "unset", ], - }, - "border-right-style": { - inherited: false, - supports: 0, - values: ["dashed", "dotted", "double", "groove", "hidden", "inherit", "initial", "inset", "none", "outset", "ridge", "solid", "unset", ], - }, - "border-right-width": { - inherited: false, - supports: 1, - values: ["-moz-calc", "calc", "inherit", "initial", "medium", "thick", "thin", "unset", ], - }, - "border-spacing": { - inherited: true, - supports: 1, - values: ["inherit", "initial", "unset", ], - }, - "border-top-color": { - inherited: false, - supports: 4, - values: ["-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", "maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "rebeccapurple", "red", "rgb", "rgba", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "springgreen", "steelblue", "tan", "teal", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], - }, - "-moz-border-top-colors": { - inherited: false, - supports: 4, - values: ["inherit", "initial", "unset", ], - }, - "border-top-style": { - inherited: false, - supports: 0, - values: ["dashed", "dotted", "double", "groove", "hidden", "inherit", "initial", "inset", "none", "outset", "ridge", "solid", "unset", ], - }, - "border-top-width": { - inherited: false, - supports: 1, - values: ["-moz-calc", "calc", "inherit", "initial", "medium", "thick", "thin", "unset", ], - }, - "border-top-left-radius": { - inherited: false, - supports: 3, - values: ["inherit", "initial", "unset", ], - }, - "border-top-right-radius": { - inherited: false, - supports: 3, - values: ["inherit", "initial", "unset", ], - }, - "border-bottom-right-radius": { - inherited: false, - supports: 3, - values: ["inherit", "initial", "unset", ], - }, - "border-bottom-left-radius": { - inherited: false, - supports: 3, - values: ["inherit", "initial", "unset", ], - }, - "bottom": { - inherited: false, - supports: 3, - values: ["-moz-calc", "auto", "calc", "inherit", "initial", "unset", ], - }, - "box-decoration-break": { - inherited: false, - supports: 0, - values: ["clone", "inherit", "initial", "slice", "unset", ], - }, - "box-shadow": { - inherited: false, - supports: 5, - values: ["inherit", "initial", "unset", ], - }, - "box-sizing": { - inherited: false, - supports: 0, - values: ["border-box", "content-box", "inherit", "initial", "padding-box", "unset", ], - }, - "caption-side": { - inherited: true, - supports: 0, - values: ["bottom", "bottom-outside", "inherit", "initial", "left", "right", "top", "top-outside", "unset", ], - }, - "clear": { - inherited: false, - supports: 0, - values: ["both", "inherit", "initial", "inline-end", "inline-start", "left", "none", "right", "unset", ], - }, - "clip": { - inherited: false, - supports: 0, - values: ["inherit", "initial", "unset", ], - }, - "color": { - inherited: true, - supports: 4, - values: ["aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", "maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "rebeccapurple", "red", "rgb", "rgba", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "springgreen", "steelblue", "tan", "teal", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], - }, - "-moz-column-count": { - inherited: false, - supports: 1024, - values: ["auto", "inherit", "initial", "unset", ], - }, - "-moz-column-fill": { - inherited: false, - supports: 0, - values: ["auto", "balance", "inherit", "initial", "unset", ], - }, - "-moz-column-width": { - inherited: false, - supports: 1, - values: ["-moz-calc", "auto", "calc", "inherit", "initial", "unset", ], - }, - "-moz-column-gap": { - inherited: false, - supports: 1, - values: ["-moz-calc", "calc", "inherit", "initial", "normal", "unset", ], - }, - "-moz-column-rule-color": { - inherited: false, - supports: 4, - values: ["-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", "maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "rebeccapurple", "red", "rgb", "rgba", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "springgreen", "steelblue", "tan", "teal", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], - }, - "-moz-column-rule-style": { - inherited: false, - supports: 0, - values: ["dashed", "dotted", "double", "groove", "hidden", "inherit", "initial", "inset", "none", "outset", "ridge", "solid", "unset", ], - }, - "-moz-column-rule-width": { - inherited: false, - supports: 1, - values: ["-moz-calc", "calc", "inherit", "initial", "medium", "thick", "thin", "unset", ], - }, - "contain": { - inherited: false, - supports: 0, - values: ["inherit", "initial", "layout", "none", "paint", "strict", "style", "unset", ], - }, - "content": { - inherited: false, - supports: 8, - values: ["inherit", "initial", "unset", ], - }, - "-moz-control-character-visibility": { - inherited: true, - supports: 0, - values: ["hidden", "inherit", "initial", "unset", "visible", ], - }, - "counter-increment": { - inherited: false, - supports: 0, - values: ["inherit", "initial", "unset", ], - }, - "counter-reset": { - inherited: false, - supports: 0, - values: ["inherit", "initial", "unset", ], - }, - "cursor": { - inherited: true, - supports: 8, - values: ["inherit", "initial", "unset", ], - }, - "direction": { - inherited: true, - supports: 0, - values: ["inherit", "initial", "ltr", "rtl", "unset", ], - }, - "display": { - inherited: false, - supports: 0, - values: ["-moz-box", "-moz-deck", "-moz-grid", "-moz-grid-group", "-moz-grid-line", "-moz-groupbox", "-moz-inline-box", "-moz-inline-grid", "-moz-inline-stack", "-moz-popup", "-moz-stack", "block", "contents", "flex", "grid", "inherit", "initial", "inline", "inline-block", "inline-flex", "inline-grid", "inline-table", "list-item", "none", "ruby", "ruby-base", "ruby-base-container", "ruby-text", "ruby-text-container", "table", "table-caption", "table-cell", "table-column", "table-column-group", "table-footer-group", "table-header-group", "table-row", "table-row-group", "unset", ], - }, - "empty-cells": { - inherited: true, - supports: 0, - values: ["hide", "inherit", "initial", "show", "unset", ], - }, - "align-content": { - inherited: false, - supports: 0, - values: ["inherit", "initial", "unset", ], - }, - "align-items": { - inherited: false, - supports: 0, - values: ["inherit", "initial", "unset", ], - }, - "align-self": { - inherited: false, - supports: 0, - values: ["inherit", "initial", "unset", ], - }, - "flex-basis": { - inherited: false, - supports: 3, - values: ["-moz-available", "-moz-calc", "-moz-fit-content", "-moz-max-content", "-moz-min-content", "auto", "calc", "inherit", "initial", "unset", ], - }, - "flex-direction": { - inherited: false, - supports: 0, - values: ["column", "column-reverse", "inherit", "initial", "row", "row-reverse", "unset", ], - }, - "flex-grow": { - inherited: false, - supports: 1024, - values: ["inherit", "initial", "unset", ], - }, - "flex-shrink": { - inherited: false, - supports: 1024, - values: ["inherit", "initial", "unset", ], - }, - "flex-wrap": { - inherited: false, - supports: 0, - values: ["inherit", "initial", "nowrap", "unset", "wrap", "wrap-reverse", ], - }, - "order": { - inherited: false, - supports: 1024, - values: ["inherit", "initial", "unset", ], - }, - "justify-content": { - inherited: false, - supports: 0, - values: ["inherit", "initial", "unset", ], - }, - "justify-items": { - inherited: false, - supports: 0, - values: ["inherit", "initial", "unset", ], - }, - "justify-self": { - inherited: false, - supports: 0, - values: ["inherit", "initial", "unset", ], - }, - "float": { - inherited: false, - supports: 0, - values: ["inherit", "initial", "inline-end", "inline-start", "left", "none", "right", "unset", ], - }, - "-moz-float-edge": { - inherited: false, - supports: 0, - values: ["content-box", "inherit", "initial", "margin-box", "unset", ], - }, - "font-family": { - inherited: true, - supports: 0, - values: ["inherit", "initial", "unset", ], - }, - "font-feature-settings": { - inherited: true, - supports: 0, - values: ["inherit", "initial", "unset", ], - }, - "font-kerning": { - inherited: true, - supports: 0, - values: ["auto", "inherit", "initial", "none", "normal", "unset", ], - }, - "font-language-override": { - inherited: true, - supports: 0, - values: ["inherit", "initial", "normal", "unset", ], - }, - "font-size": { - inherited: true, - supports: 3, - values: ["-moz-calc", "calc", "inherit", "initial", "large", "larger", "medium", "small", "smaller", "unset", "x-large", "x-small", "xx-large", "xx-small", ], - }, - "font-size-adjust": { - inherited: true, - supports: 1024, - values: ["inherit", "initial", "none", "unset", ], - }, - "font-stretch": { - inherited: true, - supports: 0, - values: ["condensed", "expanded", "extra-condensed", "extra-expanded", "inherit", "initial", "normal", "semi-condensed", "semi-expanded", "ultra-condensed", "ultra-expanded", "unset", ], - }, - "font-style": { - inherited: true, - supports: 0, - values: ["inherit", "initial", "italic", "normal", "oblique", "unset", ], - }, - "font-synthesis": { - inherited: true, - supports: 0, - values: ["inherit", "initial", "unset", ], - }, - "font-variant-alternates": { - inherited: true, - supports: 0, - values: ["inherit", "initial", "unset", ], - }, - "font-variant-caps": { - inherited: true, - supports: 0, - values: ["all-petite-caps", "all-small-caps", "inherit", "initial", "normal", "petite-caps", "small-caps", "titling-caps", "unicase", "unset", ], - }, - "font-variant-east-asian": { - inherited: true, - supports: 0, - values: ["inherit", "initial", "unset", ], - }, - "font-variant-ligatures": { - inherited: true, - supports: 0, - values: ["inherit", "initial", "unset", ], - }, - "font-variant-numeric": { - inherited: true, - supports: 0, - values: ["inherit", "initial", "unset", ], - }, - "font-variant-position": { - inherited: true, - supports: 0, - values: ["inherit", "initial", "normal", "sub", "super", "unset", ], - }, - "font-weight": { - inherited: true, - supports: 1024, - values: ["inherit", "initial", "unset", ], - }, - "-moz-force-broken-image-icon": { - inherited: false, - supports: 1024, - values: ["inherit", "initial", "unset", ], - }, - "grid-auto-flow": { - inherited: false, - supports: 0, - values: ["inherit", "initial", "unset", ], - }, - "grid-auto-columns": { - inherited: false, - supports: 3, - values: ["inherit", "initial", "unset", ], - }, - "grid-auto-rows": { - inherited: false, - supports: 3, - values: ["inherit", "initial", "unset", ], - }, - "grid-template-areas": { - inherited: false, - supports: 0, - values: ["inherit", "initial", "unset", ], - }, - "grid-template-columns": { - inherited: false, - supports: 3, - values: ["inherit", "initial", "unset", ], - }, - "grid-template-rows": { - inherited: false, - supports: 3, - values: ["inherit", "initial", "unset", ], - }, - "grid-column-start": { - inherited: false, - supports: 1024, - values: ["inherit", "initial", "unset", ], - }, - "grid-column-end": { - inherited: false, - supports: 1024, - values: ["inherit", "initial", "unset", ], - }, - "grid-row-start": { - inherited: false, - supports: 1024, - values: ["inherit", "initial", "unset", ], - }, - "grid-row-end": { - inherited: false, - supports: 1024, - values: ["inherit", "initial", "unset", ], - }, - "grid-column-gap": { - inherited: false, - supports: 1, - values: ["-moz-calc", "calc", "inherit", "initial", "unset", ], - }, - "grid-row-gap": { - inherited: false, - supports: 1, - values: ["-moz-calc", "calc", "inherit", "initial", "unset", ], - }, - "height": { - inherited: false, - supports: 3, - values: ["-moz-available", "-moz-calc", "-moz-fit-content", "-moz-max-content", "-moz-min-content", "auto", "calc", "inherit", "initial", "unset", ], - }, - "image-orientation": { - inherited: true, - supports: 16, - values: ["inherit", "initial", "unset", ], - }, - "-moz-image-region": { - inherited: true, - supports: 0, - values: ["inherit", "initial", "unset", ], - }, - "ime-mode": { - inherited: false, - supports: 0, - values: ["active", "auto", "disabled", "inactive", "inherit", "initial", "normal", "unset", ], - }, - "inline-size": { - inherited: false, - supports: 3, - values: ["-moz-available", "-moz-calc", "-moz-fit-content", "-moz-max-content", "-moz-min-content", "auto", "calc", "inherit", "initial", "unset", ], - }, - "left": { - inherited: false, - supports: 3, - values: ["-moz-calc", "auto", "calc", "inherit", "initial", "unset", ], - }, - "letter-spacing": { - inherited: true, - supports: 1, - values: ["-moz-calc", "calc", "inherit", "initial", "normal", "unset", ], - }, - "line-height": { - inherited: true, - supports: 1027, - values: ["-moz-block-height", "inherit", "initial", "normal", "unset", ], - }, - "list-style-image": { - inherited: true, - supports: 8, - values: ["inherit", "initial", "none", "unset", "url", ], - }, - "list-style-position": { - inherited: true, - supports: 0, - values: ["inherit", "initial", "inside", "outside", "unset", ], - }, - "list-style-type": { - inherited: true, - supports: 0, - values: ["inherit", "initial", "unset", ], - }, - "margin-block-end": { - inherited: false, - supports: 3, - values: ["-moz-calc", "auto", "calc", "inherit", "initial", "unset", ], - }, - "margin-block-start": { - inherited: false, - supports: 3, - values: ["-moz-calc", "auto", "calc", "inherit", "initial", "unset", ], - }, - "margin-bottom": { - inherited: false, - supports: 3, - values: ["-moz-calc", "auto", "calc", "inherit", "initial", "unset", ], - }, - "margin-inline-end": { - inherited: false, - supports: 3, - values: ["-moz-calc", "auto", "calc", "inherit", "initial", "unset", ], - }, - "margin-inline-start": { - inherited: false, - supports: 3, - values: ["-moz-calc", "auto", "calc", "inherit", "initial", "unset", ], - }, - "margin-left": { - inherited: false, - supports: 3, - values: ["-moz-calc", "auto", "calc", "inherit", "initial", "unset", ], - }, - "margin-right": { - inherited: false, - supports: 3, - values: ["-moz-calc", "auto", "calc", "inherit", "initial", "unset", ], - }, - "margin-top": { - inherited: false, - supports: 3, - values: ["-moz-calc", "auto", "calc", "inherit", "initial", "unset", ], - }, - "marker-offset": { - inherited: false, - supports: 1, - values: ["-moz-calc", "auto", "calc", "inherit", "initial", "unset", ], - }, - "max-block-size": { - inherited: false, - supports: 3, - values: ["-moz-calc", "calc", "inherit", "initial", "none", "unset", ], - }, - "max-height": { - inherited: false, - supports: 3, - values: ["-moz-available", "-moz-calc", "-moz-fit-content", "-moz-max-content", "-moz-min-content", "calc", "inherit", "initial", "none", "unset", ], - }, - "max-inline-size": { - inherited: false, - supports: 3, - values: ["-moz-available", "-moz-calc", "-moz-fit-content", "-moz-max-content", "-moz-min-content", "calc", "inherit", "initial", "none", "unset", ], - }, - "max-width": { - inherited: false, - supports: 3, - values: ["-moz-available", "-moz-calc", "-moz-fit-content", "-moz-max-content", "-moz-min-content", "calc", "inherit", "initial", "none", "unset", ], - }, - "min-height": { - inherited: false, - supports: 3, - values: ["-moz-available", "-moz-calc", "-moz-fit-content", "-moz-max-content", "-moz-min-content", "auto", "calc", "inherit", "initial", "unset", ], - }, - "min-block-size": { - inherited: false, - supports: 3, - values: ["-moz-calc", "auto", "calc", "inherit", "initial", "unset", ], - }, - "min-inline-size": { - inherited: false, - supports: 3, - values: ["-moz-available", "-moz-calc", "-moz-fit-content", "-moz-max-content", "-moz-min-content", "auto", "calc", "inherit", "initial", "unset", ], - }, - "min-width": { - inherited: false, - supports: 3, - values: ["-moz-available", "-moz-calc", "-moz-fit-content", "-moz-max-content", "-moz-min-content", "auto", "calc", "inherit", "initial", "unset", ], - }, - "mix-blend-mode": { - inherited: false, - supports: 0, - values: ["color", "color-burn", "color-dodge", "darken", "difference", "exclusion", "hard-light", "hue", "inherit", "initial", "lighten", "luminosity", "multiply", "normal", "overlay", "saturation", "screen", "soft-light", "unset", ], - }, - "isolation": { - inherited: false, - supports: 0, - values: ["auto", "inherit", "initial", "isolate", "unset", ], - }, - "object-fit": { - inherited: false, - supports: 0, - values: ["contain", "cover", "fill", "inherit", "initial", "none", "scale-down", "unset", ], - }, - "object-position": { - inherited: false, - supports: 3, - values: ["inherit", "initial", "unset", ], - }, - "offset-block-end": { - inherited: false, - supports: 3, - values: ["-moz-calc", "auto", "calc", "inherit", "initial", "unset", ], - }, - "offset-block-start": { - inherited: false, - supports: 3, - values: ["-moz-calc", "auto", "calc", "inherit", "initial", "unset", ], - }, - "offset-inline-end": { - inherited: false, - supports: 3, - values: ["-moz-calc", "auto", "calc", "inherit", "initial", "unset", ], - }, - "offset-inline-start": { - inherited: false, - supports: 3, - values: ["-moz-calc", "auto", "calc", "inherit", "initial", "unset", ], - }, - "opacity": { - inherited: false, - supports: 1024, - values: ["inherit", "initial", "unset", ], - }, - "-moz-orient": { - inherited: false, - supports: 0, - values: ["block", "horizontal", "inherit", "initial", "inline", "unset", "vertical", ], - }, - "outline-color": { - inherited: false, - supports: 4, - values: ["-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", "maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "rebeccapurple", "red", "rgb", "rgba", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "springgreen", "steelblue", "tan", "teal", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], - }, - "outline-style": { - inherited: false, - supports: 0, - values: ["auto", "dashed", "dotted", "double", "groove", "inherit", "initial", "inset", "none", "outset", "ridge", "solid", "unset", ], - }, - "outline-width": { - inherited: false, - supports: 1, - values: ["-moz-calc", "calc", "inherit", "initial", "medium", "thick", "thin", "unset", ], - }, - "outline-offset": { - inherited: false, - supports: 1, - values: ["-moz-calc", "calc", "inherit", "initial", "unset", ], - }, - "overflow-x": { - inherited: false, - supports: 0, - values: ["-moz-hidden-unscrollable", "auto", "hidden", "inherit", "initial", "scroll", "unset", "visible", ], - }, - "overflow-y": { - inherited: false, - supports: 0, - values: ["-moz-hidden-unscrollable", "auto", "hidden", "inherit", "initial", "scroll", "unset", "visible", ], - }, - "padding-block-end": { - inherited: false, - supports: 3, - values: ["-moz-calc", "calc", "inherit", "initial", "unset", ], - }, - "padding-block-start": { - inherited: false, - supports: 3, - values: ["-moz-calc", "calc", "inherit", "initial", "unset", ], - }, - "padding-bottom": { - inherited: false, - supports: 3, - values: ["-moz-calc", "calc", "inherit", "initial", "unset", ], - }, - "padding-inline-end": { - inherited: false, - supports: 3, - values: ["-moz-calc", "calc", "inherit", "initial", "unset", ], - }, - "padding-inline-start": { - inherited: false, - supports: 3, - values: ["-moz-calc", "calc", "inherit", "initial", "unset", ], - }, - "padding-left": { - inherited: false, - supports: 3, - values: ["-moz-calc", "calc", "inherit", "initial", "unset", ], - }, - "padding-right": { - inherited: false, - supports: 3, - values: ["-moz-calc", "calc", "inherit", "initial", "unset", ], - }, - "padding-top": { - inherited: false, - supports: 3, - values: ["-moz-calc", "calc", "inherit", "initial", "unset", ], - }, - "page-break-after": { - inherited: false, - supports: 0, - values: ["always", "auto", "avoid", "inherit", "initial", "left", "right", "unset", ], - }, - "page-break-before": { - inherited: false, - supports: 0, - values: ["always", "auto", "avoid", "inherit", "initial", "left", "right", "unset", ], - }, - "page-break-inside": { - inherited: false, - supports: 0, - values: ["auto", "avoid", "inherit", "initial", "unset", ], - }, - "paint-order": { - inherited: true, - supports: 0, - values: ["inherit", "initial", "unset", ], - }, - "pointer-events": { - inherited: true, - supports: 0, - values: ["all", "auto", "fill", "inherit", "initial", "none", "painted", "stroke", "unset", "visible", "visiblefill", "visiblepainted", "visiblestroke", ], - }, - "position": { - inherited: false, - supports: 0, - values: ["absolute", "fixed", "inherit", "initial", "relative", "static", "sticky", "unset", ], - }, - "quotes": { - inherited: true, - supports: 0, - values: ["inherit", "initial", "unset", ], - }, - "resize": { - inherited: false, - supports: 0, - values: ["both", "horizontal", "inherit", "initial", "none", "unset", "vertical", ], - }, - "right": { - inherited: false, - supports: 3, - values: ["-moz-calc", "auto", "calc", "inherit", "initial", "unset", ], - }, - "ruby-align": { - inherited: true, - supports: 0, - values: ["center", "inherit", "initial", "space-around", "space-between", "start", "unset", ], - }, - "ruby-position": { - inherited: true, - supports: 0, - values: ["inherit", "initial", "over", "under", "unset", ], - }, - "scroll-behavior": { - inherited: false, - supports: 0, - values: ["auto", "inherit", "initial", "smooth", "unset", ], - }, - "scroll-snap-coordinate": { - inherited: false, - supports: 3, - values: ["inherit", "initial", "unset", ], - }, - "scroll-snap-destination": { - inherited: false, - supports: 3, - values: ["inherit", "initial", "unset", ], - }, - "scroll-snap-points-x": { - inherited: false, - supports: 0, - values: ["inherit", "initial", "unset", ], - }, - "scroll-snap-points-y": { - inherited: false, - supports: 0, - values: ["inherit", "initial", "unset", ], - }, - "scroll-snap-type-x": { - inherited: false, - supports: 0, - values: ["inherit", "initial", "mandatory", "none", "proximity", "unset", ], - }, - "scroll-snap-type-y": { - inherited: false, - supports: 0, - values: ["inherit", "initial", "mandatory", "none", "proximity", "unset", ], - }, - "table-layout": { - inherited: false, - supports: 0, - values: ["auto", "fixed", "inherit", "initial", "unset", ], - }, - "text-align": { - inherited: true, - supports: 0, - values: ["-moz-center", "-moz-left", "-moz-right", "center", "end", "inherit", "initial", "justify", "left", "right", "start", "unset", ], - }, - "-moz-text-align-last": { - inherited: true, - supports: 0, - values: ["auto", "center", "end", "inherit", "initial", "justify", "left", "right", "start", "unset", ], - }, - "text-decoration-color": { - inherited: false, - supports: 4, - values: ["-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", "maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "rebeccapurple", "red", "rgb", "rgba", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "springgreen", "steelblue", "tan", "teal", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], - }, - "text-decoration-line": { - inherited: false, - supports: 0, - values: ["inherit", "initial", "unset", ], - }, - "text-decoration-style": { - inherited: false, - supports: 0, - values: ["-moz-none", "dashed", "dotted", "double", "inherit", "initial", "solid", "unset", "wavy", ], - }, - "text-indent": { - inherited: true, - supports: 3, - values: ["-moz-calc", "calc", "inherit", "initial", "unset", ], - }, - "text-orientation": { - inherited: true, - supports: 0, - values: ["inherit", "initial", "mixed", "sideways", "sideways-right", "unset", "upright", ], - }, - "text-overflow": { - inherited: false, - supports: 0, - values: ["inherit", "initial", "unset", ], - }, - "text-shadow": { - inherited: true, - supports: 5, - values: ["inherit", "initial", "unset", ], - }, - "-moz-text-size-adjust": { - inherited: true, - supports: 0, - values: ["auto", "inherit", "initial", "none", "unset", ], - }, - "text-transform": { - inherited: true, - supports: 0, - values: ["capitalize", "full-width", "inherit", "initial", "lowercase", "none", "unset", "uppercase", ], - }, - "transform": { - inherited: false, - supports: 0, - values: ["inherit", "initial", "unset", ], - }, - "transform-box": { - inherited: false, - supports: 0, - values: ["border-box", "fill-box", "inherit", "initial", "unset", "view-box", ], - }, - "transform-origin": { - inherited: false, - supports: 3, - values: ["inherit", "initial", "unset", ], - }, - "perspective-origin": { - inherited: false, - supports: 3, - values: ["inherit", "initial", "unset", ], - }, - "perspective": { - inherited: false, - supports: 1, - values: ["inherit", "initial", "none", "unset", ], - }, - "transform-style": { - inherited: false, - supports: 0, - values: ["flat", "inherit", "initial", "preserve-3d", "unset", ], - }, - "backface-visibility": { - inherited: false, - supports: 0, - values: ["hidden", "inherit", "initial", "unset", "visible", ], - }, - "top": { - inherited: false, - supports: 3, - values: ["-moz-calc", "auto", "calc", "inherit", "initial", "unset", ], - }, - "transition-delay": { - inherited: false, - supports: 64, - values: ["inherit", "initial", "unset", ], - }, - "transition-duration": { - inherited: false, - supports: 64, - values: ["inherit", "initial", "unset", ], - }, - "transition-property": { - inherited: false, - supports: 0, - values: ["all", "inherit", "initial", "none", "unset", ], - }, - "transition-timing-function": { - inherited: false, - supports: 256, - values: ["cubic-bezier", "ease", "ease-in", "ease-in-out", "ease-out", "inherit", "initial", "linear", "step-end", "step-start", "steps", "unset", ], - }, - "unicode-bidi": { - inherited: false, - supports: 0, - values: ["-moz-isolate", "-moz-isolate-override", "-moz-plaintext", "bidi-override", "embed", "inherit", "initial", "normal", "unset", ], - }, - "-moz-user-focus": { - inherited: true, - supports: 0, - values: ["ignore", "inherit", "initial", "none", "normal", "select-after", "select-all", "select-before", "select-menu", "select-same", "unset", ], - }, - "-moz-user-input": { - inherited: true, - supports: 0, - values: ["auto", "disabled", "enabled", "inherit", "initial", "none", "unset", ], - }, - "-moz-user-modify": { - inherited: true, - supports: 0, - values: ["inherit", "initial", "read-only", "read-write", "unset", "write-only", ], - }, - "-moz-user-select": { - inherited: false, - supports: 0, - values: ["-moz-all", "-moz-none", "-moz-text", "all", "auto", "element", "elements", "inherit", "initial", "none", "text", "toggle", "tri-state", "unset", ], - }, - "vertical-align": { - inherited: false, - supports: 3, - values: ["-moz-calc", "-moz-middle-with-baseline", "baseline", "bottom", "calc", "inherit", "initial", "middle", "sub", "super", "text-bottom", "text-top", "top", "unset", ], - }, - "visibility": { - inherited: true, - supports: 0, - values: ["collapse", "hidden", "inherit", "initial", "unset", "visible", ], - }, - "white-space": { - inherited: true, - supports: 0, - values: ["-moz-pre-space", "inherit", "initial", "normal", "nowrap", "pre", "pre-line", "pre-wrap", "unset", ], - }, - "width": { - inherited: false, - supports: 3, - values: ["-moz-available", "-moz-calc", "-moz-fit-content", "-moz-max-content", "-moz-min-content", "auto", "calc", "inherit", "initial", "unset", ], - }, - "-moz-window-dragging": { - inherited: true, - supports: 0, - values: ["drag", "inherit", "initial", "no-drag", "unset", ], - }, - "word-break": { - inherited: true, - supports: 0, - values: ["break-all", "inherit", "initial", "keep-all", "normal", "unset", ], - }, - "word-spacing": { - inherited: true, - supports: 3, - values: ["-moz-calc", "calc", "inherit", "initial", "normal", "unset", ], - }, - "word-wrap": { - inherited: true, - supports: 0, - values: ["break-word", "inherit", "initial", "normal", "unset", ], - }, - "hyphens": { - inherited: true, - supports: 0, - values: ["auto", "inherit", "initial", "manual", "none", "unset", ], - }, - "writing-mode": { - inherited: true, - supports: 0, - values: ["horizontal-tb", "inherit", "initial", "lr", "lr-tb", "rl", "rl-tb", "sideways-lr", "sideways-rl", "tb", "tb-rl", "unset", "vertical-lr", "vertical-rl", ], - }, - "z-index": { - inherited: false, - supports: 1024, - values: ["auto", "inherit", "initial", "unset", ], - }, - "-moz-box-align": { - inherited: false, - supports: 0, - values: ["baseline", "center", "end", "inherit", "initial", "start", "stretch", "unset", ], - }, - "-moz-box-direction": { - inherited: false, - supports: 0, - values: ["inherit", "initial", "normal", "reverse", "unset", ], - }, - "-moz-box-flex": { - inherited: false, - supports: 1024, - values: ["inherit", "initial", "unset", ], - }, - "-moz-box-orient": { - inherited: false, - supports: 0, - values: ["block-axis", "horizontal", "inherit", "initial", "inline-axis", "unset", "vertical", ], - }, - "-moz-box-pack": { - inherited: false, - supports: 0, - values: ["center", "end", "inherit", "initial", "justify", "start", "unset", ], - }, - "-moz-box-ordinal-group": { - inherited: false, - supports: 1024, - values: ["inherit", "initial", "unset", ], - }, - "-moz-stack-sizing": { - inherited: false, - supports: 0, - values: ["ignore", "inherit", "initial", "stretch-to-fit", "unset", ], - }, - "clip-path": { - inherited: false, - supports: 8, - values: ["inherit", "initial", "unset", ], - }, - "clip-rule": { - inherited: true, - supports: 0, - values: ["evenodd", "inherit", "initial", "nonzero", "unset", ], - }, - "color-interpolation": { - inherited: true, - supports: 0, - values: ["auto", "inherit", "initial", "linearrgb", "srgb", "unset", ], - }, - "color-interpolation-filters": { - inherited: true, - supports: 0, - values: ["auto", "inherit", "initial", "linearrgb", "srgb", "unset", ], - }, - "dominant-baseline": { - inherited: false, - supports: 0, - values: ["alphabetic", "auto", "central", "hanging", "ideographic", "inherit", "initial", "mathematical", "middle", "no-change", "reset-size", "text-after-edge", "text-before-edge", "unset", "use-script", ], - }, - "fill": { - inherited: true, - supports: 12, - values: ["inherit", "initial", "unset", ], - }, - "fill-opacity": { - inherited: true, - supports: 1024, - values: ["inherit", "initial", "unset", ], - }, - "fill-rule": { - inherited: true, - supports: 0, - values: ["evenodd", "inherit", "initial", "nonzero", "unset", ], - }, - "filter": { - inherited: false, - supports: 8, - values: ["inherit", "initial", "unset", ], - }, - "flood-color": { - inherited: false, - supports: 4, - values: ["aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", "maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "rebeccapurple", "red", "rgb", "rgba", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "springgreen", "steelblue", "tan", "teal", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], - }, - "flood-opacity": { - inherited: false, - supports: 1024, - values: ["inherit", "initial", "unset", ], - }, - "image-rendering": { - inherited: true, - supports: 0, - values: ["-moz-crisp-edges", "auto", "inherit", "initial", "optimizequality", "optimizespeed", "unset", ], - }, - "lighting-color": { - inherited: false, - supports: 4, - values: ["aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", "maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "rebeccapurple", "red", "rgb", "rgba", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "springgreen", "steelblue", "tan", "teal", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], - }, - "marker-end": { - inherited: true, - supports: 8, - values: ["inherit", "initial", "none", "unset", "url", ], - }, - "marker-mid": { - inherited: true, - supports: 8, - values: ["inherit", "initial", "none", "unset", "url", ], - }, - "marker-start": { - inherited: true, - supports: 8, - values: ["inherit", "initial", "none", "unset", "url", ], - }, - "mask": { - inherited: false, - supports: 8, - values: ["inherit", "initial", "none", "unset", "url", ], - }, - "mask-type": { - inherited: false, - supports: 0, - values: ["alpha", "inherit", "initial", "luminance", "unset", ], - }, - "shape-rendering": { - inherited: true, - supports: 0, - values: ["auto", "crispedges", "geometricprecision", "inherit", "initial", "optimizespeed", "unset", ], - }, - "stop-color": { - inherited: false, - supports: 4, - values: ["aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", "maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "rebeccapurple", "red", "rgb", "rgba", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "springgreen", "steelblue", "tan", "teal", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], - }, - "stop-opacity": { - inherited: false, - supports: 1024, - values: ["inherit", "initial", "unset", ], - }, - "stroke": { - inherited: true, - supports: 12, - values: ["inherit", "initial", "unset", ], - }, - "stroke-dasharray": { - inherited: true, - supports: 1027, - values: ["inherit", "initial", "unset", ], - }, - "stroke-dashoffset": { - inherited: true, - supports: 1027, - values: ["inherit", "initial", "unset", ], - }, - "stroke-linecap": { - inherited: true, - supports: 0, - values: ["butt", "inherit", "initial", "round", "square", "unset", ], - }, - "stroke-linejoin": { - inherited: true, - supports: 0, - values: ["bevel", "inherit", "initial", "miter", "round", "unset", ], - }, - "stroke-miterlimit": { - inherited: true, - supports: 1024, - values: ["inherit", "initial", "unset", ], - }, - "stroke-opacity": { - inherited: true, - supports: 1024, - values: ["inherit", "initial", "unset", ], - }, - "stroke-width": { - inherited: true, - supports: 1027, - values: ["inherit", "initial", "unset", ], - }, - "text-anchor": { - inherited: true, - supports: 0, - values: ["end", "inherit", "initial", "middle", "start", "unset", ], - }, - "text-rendering": { - inherited: true, - supports: 0, - values: ["auto", "geometricprecision", "inherit", "initial", "optimizelegibility", "optimizespeed", "unset", ], - }, - "vector-effect": { - inherited: false, - supports: 0, - values: ["inherit", "initial", "non-scaling-stroke", "none", "unset", ], - }, - "will-change": { - inherited: false, - supports: 0, - values: ["inherit", "initial", "unset", ], - }, - "-moz-outline-radius": { - subproperties: ["-moz-outline-radius-topleft", "-moz-outline-radius-topright", "-moz-outline-radius-bottomright", "-moz-outline-radius-bottomleft", ], - inherited: false, - supports: 3, - values: ["inherit", "initial", "unset", ], - }, - "all": { - subproperties: ["-moz-appearance", "-moz-outline-radius-topleft", "-moz-outline-radius-topright", "-moz-outline-radius-bottomright", "-moz-outline-radius-bottomleft", "-moz-tab-size", "-x-system-font", "animation-delay", "animation-direction", "animation-duration", "animation-fill-mode", "animation-iteration-count", "animation-name", "animation-play-state", "animation-timing-function", "background-attachment", "background-clip", "background-color", "background-image", "background-blend-mode", "background-origin", "background-position", "background-repeat", "background-size", "-moz-binding", "block-size", "border-block-end-color", "border-block-end-style", "border-block-end-width", "border-block-start-color", "border-block-start-style", "border-block-start-width", "border-bottom-color", "-moz-border-bottom-colors", "border-bottom-style", "border-bottom-width", "border-collapse", "border-image-source", "border-image-slice", "border-image-width", "border-image-outset", "border-image-repeat", "border-inline-end-color", "border-inline-end-style", "border-inline-end-width", "border-inline-start-color", "border-inline-start-style", "border-inline-start-width", "border-left-color", "-moz-border-left-colors", "border-left-style", "border-left-width", "border-right-color", "-moz-border-right-colors", "border-right-style", "border-right-width", "border-spacing", "border-top-color", "-moz-border-top-colors", "border-top-style", "border-top-width", "border-top-left-radius", "border-top-right-radius", "border-bottom-right-radius", "border-bottom-left-radius", "bottom", "box-decoration-break", "box-shadow", "box-sizing", "caption-side", "clear", "clip", "color", "-moz-column-count", "-moz-column-fill", "-moz-column-width", "-moz-column-gap", "-moz-column-rule-color", "-moz-column-rule-style", "-moz-column-rule-width", "contain", "content", "-moz-control-character-visibility", "counter-increment", "counter-reset", "cursor", "display", "empty-cells", "align-content", "align-items", "align-self", "flex-basis", "flex-direction", "flex-grow", "flex-shrink", "flex-wrap", "order", "justify-content", "justify-items", "justify-self", "float", "-moz-float-edge", "font-family", "font-feature-settings", "font-kerning", "font-language-override", "font-size", "font-size-adjust", "-moz-osx-font-smoothing", "font-stretch", "font-style", "font-synthesis", "font-variant-alternates", "font-variant-caps", "font-variant-east-asian", "font-variant-ligatures", "font-variant-numeric", "font-variant-position", "font-weight", "-moz-force-broken-image-icon", "grid-auto-flow", "grid-auto-columns", "grid-auto-rows", "grid-template-areas", "grid-template-columns", "grid-template-rows", "grid-column-start", "grid-column-end", "grid-row-start", "grid-row-end", "grid-column-gap", "grid-row-gap", "height", "image-orientation", "-moz-image-region", "ime-mode", "inline-size", "left", "letter-spacing", "line-height", "list-style-image", "list-style-position", "list-style-type", "margin-block-end", "margin-block-start", "margin-bottom", "margin-inline-end", "margin-inline-start", "margin-left", "margin-right", "margin-top", "marker-offset", "max-block-size", "max-height", "max-inline-size", "max-width", "-moz-min-font-size-ratio", "min-height", "min-block-size", "min-inline-size", "min-width", "mix-blend-mode", "isolation", "object-fit", "object-position", "offset-block-end", "offset-block-start", "offset-inline-end", "offset-inline-start", "opacity", "-moz-orient", "outline-color", "outline-style", "outline-width", "outline-offset", "overflow-clip-box", "overflow-x", "overflow-y", "padding-block-end", "padding-block-start", "padding-bottom", "padding-inline-end", "padding-inline-start", "padding-left", "padding-right", "padding-top", "page-break-after", "page-break-before", "page-break-inside", "paint-order", "pointer-events", "position", "quotes", "resize", "right", "ruby-align", "ruby-position", "scroll-behavior", "scroll-snap-coordinate", "scroll-snap-destination", "scroll-snap-points-x", "scroll-snap-points-y", "scroll-snap-type-x", "scroll-snap-type-y", "table-layout", "text-align", "-moz-text-align-last", "text-combine-upright", "text-decoration-color", "text-decoration-line", "text-decoration-style", "text-indent", "text-orientation", "text-overflow", "text-shadow", "-moz-text-size-adjust", "text-transform", "transform", "transform-box", "transform-origin", "perspective-origin", "perspective", "transform-style", "backface-visibility", "top", "-moz-top-layer", "touch-action", "transition-delay", "transition-duration", "transition-property", "transition-timing-function", "-moz-user-focus", "-moz-user-input", "-moz-user-modify", "-moz-user-select", "vertical-align", "visibility", "white-space", "width", "-moz-window-dragging", "-moz-window-shadow", "word-break", "word-spacing", "word-wrap", "hyphens", "writing-mode", "z-index", "-moz-box-align", "-moz-box-direction", "-moz-box-flex", "-moz-box-orient", "-moz-box-pack", "-moz-box-ordinal-group", "-moz-stack-sizing", "clip-path", "clip-rule", "color-interpolation", "color-interpolation-filters", "dominant-baseline", "fill", "fill-opacity", "fill-rule", "filter", "flood-color", "flood-opacity", "image-rendering", "lighting-color", "marker-end", "marker-mid", "marker-start", "mask", "mask-type", "shape-rendering", "stop-color", "stop-opacity", "stroke", "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin", "stroke-miterlimit", "stroke-opacity", "stroke-width", "text-anchor", "text-rendering", "vector-effect", "will-change", ], - inherited: false, - supports: 2015, - values: ["-moz-all", "-moz-available", "-moz-block-height", "-moz-box", "-moz-calc", "-moz-center", "-moz-crisp-edges", "-moz-deck", "-moz-element", "-moz-fit-content", "-moz-grid", "-moz-grid-group", "-moz-grid-line", "-moz-groupbox", "-moz-gtk-info-bar", "-moz-hidden-unscrollable", "-moz-image-rect", "-moz-inline-box", "-moz-inline-grid", "-moz-inline-stack", "-moz-left", "-moz-linear-gradient", "-moz-mac-disclosure-button-closed", "-moz-mac-disclosure-button-open", "-moz-mac-fullscreen-button", "-moz-mac-help-button", "-moz-mac-vibrancy-dark", "-moz-mac-vibrancy-light", "-moz-max-content", "-moz-middle-with-baseline", "-moz-min-content", "-moz-none", "-moz-popup", "-moz-pre-space", "-moz-radial-gradient", "-moz-repeating-linear-gradient", "-moz-repeating-radial-gradient", "-moz-right", "-moz-stack", "-moz-text", "-moz-use-text-color", "-moz-win-borderless-glass", "-moz-win-browsertabbar-toolbox", "-moz-win-communications-toolbox", "-moz-win-exclude-glass", "-moz-win-glass", "-moz-win-media-toolbox", "-moz-window-button-box", "-moz-window-button-box-maximized", "-moz-window-button-close", "-moz-window-button-maximize", "-moz-window-button-minimize", "-moz-window-button-restore", "-moz-window-frame-bottom", "-moz-window-frame-left", "-moz-window-frame-right", "-moz-window-titlebar", "-moz-window-titlebar-maximized", "absolute", "active", "aliceblue", "all", "all-petite-caps", "all-small-caps", "alpha", "alphabetic", "alternate", "alternate-reverse", "always", "antiquewhite", "aqua", "aquamarine", "auto", "avoid", "azure", "backwards", "balance", "baseline", "beige", "bevel", "bisque", "black", "blanchedalmond", "block", "block-axis", "blue", "blueviolet", "border-box", "both", "bottom", "bottom-outside", "break-all", "break-word", "brown", "burlywood", "butt", "button", "button-arrow-down", "button-arrow-next", "button-arrow-previous", "button-arrow-up", "button-bevel", "button-focus", "cadetblue", "calc", "capitalize", "caret", "center", "central", "chartreuse", "checkbox", "checkbox-container", "checkbox-label", "checkmenuitem", "chocolate", "clone", "collapse", "color", "color-burn", "color-dodge", "column", "column-reverse", "condensed", "contain", "content-box", "contents", "coral", "cornflowerblue", "cornsilk", "cover", "crimson", "crispedges", "cubic-bezier", "currentColor", "cyan", "darkblue", "darkcyan", "darken", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "dashed", "deeppink", "deepskyblue", "dialog", "difference", "dimgray", "dimgrey", "disabled", "dodgerblue", "dotted", "double", "drag", "dualbutton", "ease", "ease-in", "ease-in-out", "ease-out", "element", "elements", "enabled", "end", "evenodd", "exclusion", "expanded", "extra-condensed", "extra-expanded", "fill", "fill-box", "firebrick", "fixed", "flat", "flex", "floralwhite", "forestgreen", "forwards", "fuchsia", "full-width", "gainsboro", "geometricprecision", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "grid", "groove", "groupbox", "hanging", "hard-light", "hidden", "hide", "honeydew", "horizontal", "horizontal-tb", "hotpink", "hsl", "hsla", "hue", "ideographic", "ignore", "inactive", "indianred", "indigo", "infinite", "inherit", "initial", "inline", "inline-axis", "inline-block", "inline-end", "inline-flex", "inline-grid", "inline-start", "inline-table", "inset", "inside", "isolate", "italic", "ivory", "justify", "keep-all", "khaki", "large", "larger", "lavender", "lavenderblush", "lawngreen", "layout", "left", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lighten", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow", "lime", "limegreen", "linear", "linear-gradient", "linearrgb", "linen", "list-item", "listbox", "listitem", "local", "lowercase", "lr", "lr-tb", "luminance", "luminosity", "magenta", "mandatory", "manual", "margin-box", "maroon", "mathematical", "medium", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "menuarrow", "menubar", "menucheckbox", "menuimage", "menuitem", "menuitemtext", "menulist", "menulist-button", "menulist-text", "menulist-textfield", "menupopup", "menuradio", "menuseparator", "meterbar", "meterchunk", "middle", "midnightblue", "mintcream", "mistyrose", "miter", "mixed", "moccasin", "multiply", "navajowhite", "navy", "no-change", "no-drag", "no-repeat", "non-scaling-stroke", "none", "nonzero", "normal", "nowrap", "number-input", "oblique", "oldlace", "olive", "olivedrab", "optimizelegibility", "optimizequality", "optimizespeed", "orange", "orangered", "orchid", "outset", "outside", "over", "overlay", "padding-box", "paint", "painted", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "paused", "peachpuff", "peru", "petite-caps", "pink", "plum", "powderblue", "pre", "pre-line", "pre-wrap", "preserve-3d", "progressbar", "progressbar-vertical", "progresschunk", "progresschunk-vertical", "proximity", "purple", "radial-gradient", "radio", "radio-container", "radio-label", "radiomenuitem", "range", "range-thumb", "read-only", "read-write", "rebeccapurple", "red", "relative", "repeat", "repeat-x", "repeat-y", "repeating-linear-gradient", "repeating-radial-gradient", "reset-size", "resizer", "resizerpanel", "reverse", "rgb", "rgba", "ridge", "right", "rl", "rl-tb", "rosybrown", "round", "row", "row-reverse", "royalblue", "ruby", "ruby-base", "ruby-base-container", "ruby-text", "ruby-text-container", "running", "saddlebrown", "salmon", "sandybrown", "saturation", "scale-down", "scale-horizontal", "scale-vertical", "scalethumb-horizontal", "scalethumb-vertical", "scalethumbend", "scalethumbstart", "scalethumbtick", "screen", "scroll", "scrollbar", "scrollbar-small", "scrollbarbutton-down", "scrollbarbutton-left", "scrollbarbutton-right", "scrollbarbutton-up", "scrollbarthumb-horizontal", "scrollbarthumb-vertical", "scrollbartrack-horizontal", "scrollbartrack-vertical", "seagreen", "searchfield", "seashell", "select-after", "select-all", "select-before", "select-menu", "select-same", "semi-condensed", "semi-expanded", "separate", "separator", "show", "sideways", "sideways-lr", "sideways-right", "sideways-rl", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "slice", "small", "small-caps", "smaller", "smooth", "snow", "soft-light", "solid", "space-around", "space-between", "spinner", "spinner-downbutton", "spinner-textfield", "spinner-upbutton", "splitter", "springgreen", "square", "srgb", "start", "static", "statusbar", "statusbarpanel", "steelblue", "step-end", "step-start", "steps", "sticky", "stretch", "stretch-to-fit", "strict", "stroke", "style", "sub", "super", "tab", "tab-scroll-arrow-back", "tab-scroll-arrow-forward", "table", "table-caption", "table-cell", "table-column", "table-column-group", "table-footer-group", "table-header-group", "table-row", "table-row-group", "tabpanel", "tabpanels", "tan", "tb", "tb-rl", "teal", "text", "text-after-edge", "text-before-edge", "text-bottom", "text-top", "textfield", "textfield-multiline", "thick", "thin", "thistle", "titling-caps", "toggle", "tomato", "toolbar", "toolbarbutton", "toolbarbutton-dropdown", "toolbargripper", "toolbox", "tooltip", "top", "top-outside", "transparent", "treeheader", "treeheadercell", "treeheadersortarrow", "treeitem", "treeline", "treetwisty", "treetwistyopen", "treeview", "tri-state", "turquoise", "ultra-condensed", "ultra-expanded", "under", "unicase", "unset", "uppercase", "upright", "url", "use-script", "vertical", "vertical-lr", "vertical-rl", "view-box", "violet", "visible", "visiblefill", "visiblepainted", "visiblestroke", "wavy", "wheat", "white", "whitesmoke", "window", "wrap", "wrap-reverse", "write-only", "x-large", "x-small", "xx-large", "xx-small", "yellow", "yellowgreen", ], - }, - "animation": { - subproperties: ["animation-duration", "animation-timing-function", "animation-delay", "animation-direction", "animation-fill-mode", "animation-iteration-count", "animation-play-state", "animation-name", ], - inherited: false, - supports: 1344, - values: ["alternate", "alternate-reverse", "backwards", "both", "cubic-bezier", "ease", "ease-in", "ease-in-out", "ease-out", "forwards", "infinite", "inherit", "initial", "linear", "none", "normal", "paused", "reverse", "running", "step-end", "step-start", "steps", "unset", ], - }, - "background": { - subproperties: ["background-color", "background-image", "background-repeat", "background-attachment", "background-position", "background-clip", "background-origin", "background-size", ], - inherited: false, - supports: 655, - values: ["-moz-element", "-moz-image-rect", "-moz-linear-gradient", "-moz-radial-gradient", "-moz-repeating-linear-gradient", "-moz-repeating-radial-gradient", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "border-box", "brown", "burlywood", "cadetblue", "chartreuse", "chocolate", "content-box", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick", "fixed", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow", "lime", "limegreen", "linear-gradient", "linen", "local", "magenta", "maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "no-repeat", "none", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "padding-box", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "radial-gradient", "rebeccapurple", "red", "repeat", "repeat-x", "repeat-y", "repeating-linear-gradient", "repeating-radial-gradient", "rgb", "rgba", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "scroll", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "springgreen", "steelblue", "tan", "teal", "thistle", "tomato", "transparent", "turquoise", "unset", "url", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], - }, - "border": { - subproperties: ["border-top-width", "border-right-width", "border-bottom-width", "border-left-width", "border-top-style", "border-right-style", "border-bottom-style", "border-left-style", "border-top-color", "border-right-color", "border-bottom-color", "border-left-color", "-moz-border-top-colors", "-moz-border-right-colors", "-moz-border-bottom-colors", "-moz-border-left-colors", "border-image-source", "border-image-slice", "border-image-width", "border-image-outset", "border-image-repeat", ], - inherited: false, - supports: 5, - values: ["-moz-calc", "-moz-element", "-moz-image-rect", "-moz-linear-gradient", "-moz-radial-gradient", "-moz-repeating-linear-gradient", "-moz-repeating-radial-gradient", "-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "calc", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "dashed", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "dotted", "double", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "groove", "hidden", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "inset", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow", "lime", "limegreen", "linear-gradient", "linen", "magenta", "maroon", "medium", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "none", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "outset", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "radial-gradient", "rebeccapurple", "red", "repeating-linear-gradient", "repeating-radial-gradient", "rgb", "rgba", "ridge", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "solid", "springgreen", "steelblue", "tan", "teal", "thick", "thin", "thistle", "tomato", "transparent", "turquoise", "unset", "url", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], - }, - "border-block-end": { - subproperties: ["border-block-end-width", "border-block-end-style", "border-block-end-color", ], - inherited: false, - supports: 5, - values: ["-moz-calc", "-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "calc", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "dashed", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "dotted", "double", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "groove", "hidden", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "inset", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", "maroon", "medium", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "none", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "outset", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "rebeccapurple", "red", "rgb", "rgba", "ridge", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "solid", "springgreen", "steelblue", "tan", "teal", "thick", "thin", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], - }, - "border-block-start": { - subproperties: ["border-block-start-width", "border-block-start-style", "border-block-start-color", ], - inherited: false, - supports: 5, - values: ["-moz-calc", "-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "calc", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "dashed", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "dotted", "double", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "groove", "hidden", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "inset", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", "maroon", "medium", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "none", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "outset", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "rebeccapurple", "red", "rgb", "rgba", "ridge", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "solid", "springgreen", "steelblue", "tan", "teal", "thick", "thin", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], - }, - "border-bottom": { - subproperties: ["border-bottom-width", "border-bottom-style", "border-bottom-color", ], - inherited: false, - supports: 5, - values: ["-moz-calc", "-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "calc", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "dashed", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "dotted", "double", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "groove", "hidden", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "inset", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", "maroon", "medium", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "none", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "outset", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "rebeccapurple", "red", "rgb", "rgba", "ridge", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "solid", "springgreen", "steelblue", "tan", "teal", "thick", "thin", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], - }, - "border-color": { - subproperties: ["border-top-color", "border-right-color", "border-bottom-color", "border-left-color", ], - inherited: false, - supports: 4, - values: ["-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", "maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "rebeccapurple", "red", "rgb", "rgba", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "springgreen", "steelblue", "tan", "teal", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], - }, - "border-image": { - subproperties: ["border-image-source", "border-image-slice", "border-image-width", "border-image-outset", "border-image-repeat", ], - inherited: false, - supports: 1675, - values: ["-moz-element", "-moz-image-rect", "-moz-linear-gradient", "-moz-radial-gradient", "-moz-repeating-linear-gradient", "-moz-repeating-radial-gradient", "inherit", "initial", "linear-gradient", "none", "radial-gradient", "repeating-linear-gradient", "repeating-radial-gradient", "unset", "url", ], - }, - "border-inline-end": { - subproperties: ["border-inline-end-width", "border-inline-end-style", "border-inline-end-color", ], - inherited: false, - supports: 5, - values: ["-moz-calc", "-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "calc", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "dashed", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "dotted", "double", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "groove", "hidden", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "inset", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", "maroon", "medium", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "none", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "outset", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "rebeccapurple", "red", "rgb", "rgba", "ridge", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "solid", "springgreen", "steelblue", "tan", "teal", "thick", "thin", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], - }, - "border-inline-start": { - subproperties: ["border-inline-start-width", "border-inline-start-style", "border-inline-start-color", ], - inherited: false, - supports: 5, - values: ["-moz-calc", "-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "calc", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "dashed", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "dotted", "double", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "groove", "hidden", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "inset", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", "maroon", "medium", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "none", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "outset", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "rebeccapurple", "red", "rgb", "rgba", "ridge", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "solid", "springgreen", "steelblue", "tan", "teal", "thick", "thin", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], - }, - "border-left": { - subproperties: ["border-left-width", "border-left-style", "border-left-color", ], - inherited: false, - supports: 5, - values: ["-moz-calc", "-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "calc", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "dashed", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "dotted", "double", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "groove", "hidden", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "inset", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", "maroon", "medium", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "none", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "outset", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "rebeccapurple", "red", "rgb", "rgba", "ridge", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "solid", "springgreen", "steelblue", "tan", "teal", "thick", "thin", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], - }, - "border-right": { - subproperties: ["border-right-width", "border-right-style", "border-right-color", ], - inherited: false, - supports: 5, - values: ["-moz-calc", "-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "calc", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "dashed", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "dotted", "double", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "groove", "hidden", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "inset", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", "maroon", "medium", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "none", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "outset", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "rebeccapurple", "red", "rgb", "rgba", "ridge", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "solid", "springgreen", "steelblue", "tan", "teal", "thick", "thin", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], - }, - "border-style": { - subproperties: ["border-top-style", "border-right-style", "border-bottom-style", "border-left-style", ], - inherited: false, - supports: 0, - values: ["dashed", "dotted", "double", "groove", "hidden", "inherit", "initial", "inset", "none", "outset", "ridge", "solid", "unset", ], - }, - "border-top": { - subproperties: ["border-top-width", "border-top-style", "border-top-color", ], - inherited: false, - supports: 5, - values: ["-moz-calc", "-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "calc", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "dashed", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "dotted", "double", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "groove", "hidden", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "inset", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", "maroon", "medium", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "none", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "outset", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "rebeccapurple", "red", "rgb", "rgba", "ridge", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "solid", "springgreen", "steelblue", "tan", "teal", "thick", "thin", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], - }, - "border-width": { - subproperties: ["border-top-width", "border-right-width", "border-bottom-width", "border-left-width", ], - inherited: false, - supports: 1, - values: ["-moz-calc", "calc", "inherit", "initial", "medium", "thick", "thin", "unset", ], - }, - "border-radius": { - subproperties: ["border-top-left-radius", "border-top-right-radius", "border-bottom-right-radius", "border-bottom-left-radius", ], - inherited: false, - supports: 3, - values: ["inherit", "initial", "unset", ], - }, - "-moz-columns": { - subproperties: ["-moz-column-count", "-moz-column-width", ], - inherited: false, - supports: 1025, - values: ["-moz-calc", "auto", "calc", "inherit", "initial", "unset", ], - }, - "-moz-column-rule": { - subproperties: ["-moz-column-rule-width", "-moz-column-rule-style", "-moz-column-rule-color", ], - inherited: false, - supports: 5, - values: ["-moz-calc", "-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "calc", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "dashed", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "dotted", "double", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "groove", "hidden", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "inset", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", "maroon", "medium", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "none", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "outset", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "rebeccapurple", "red", "rgb", "rgba", "ridge", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "solid", "springgreen", "steelblue", "tan", "teal", "thick", "thin", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], - }, - "flex": { - subproperties: ["flex-grow", "flex-shrink", "flex-basis", ], - inherited: false, - supports: 1027, - values: ["-moz-available", "-moz-calc", "-moz-fit-content", "-moz-max-content", "-moz-min-content", "auto", "calc", "inherit", "initial", "unset", ], - }, - "flex-flow": { - subproperties: ["flex-direction", "flex-wrap", ], - inherited: false, - supports: 0, - values: ["column", "column-reverse", "inherit", "initial", "nowrap", "row", "row-reverse", "unset", "wrap", "wrap-reverse", ], - }, - "font": { - subproperties: ["font-family", "font-style", "font-weight", "font-size", "line-height", "font-size-adjust", "font-stretch", "-x-system-font", "font-feature-settings", "font-language-override", "font-kerning", "font-synthesis", "font-variant-alternates", "font-variant-caps", "font-variant-east-asian", "font-variant-ligatures", "font-variant-numeric", "font-variant-position", ], - inherited: true, - supports: 1027, - values: ["-moz-block-height", "-moz-calc", "all-petite-caps", "all-small-caps", "auto", "calc", "condensed", "expanded", "extra-condensed", "extra-expanded", "inherit", "initial", "italic", "large", "larger", "medium", "none", "normal", "oblique", "petite-caps", "semi-condensed", "semi-expanded", "small", "small-caps", "smaller", "sub", "super", "titling-caps", "ultra-condensed", "ultra-expanded", "unicase", "unset", "x-large", "x-small", "xx-large", "xx-small", ], - }, - "font-variant": { - subproperties: ["font-variant-alternates", "font-variant-caps", "font-variant-east-asian", "font-variant-ligatures", "font-variant-numeric", "font-variant-position", ], - inherited: true, - supports: 0, - values: ["all-petite-caps", "all-small-caps", "inherit", "initial", "normal", "petite-caps", "small-caps", "sub", "super", "titling-caps", "unicase", "unset", ], - }, - "grid-template": { - subproperties: ["grid-template-areas", "grid-template-columns", "grid-template-rows", ], - inherited: false, - supports: 3, - values: ["inherit", "initial", "unset", ], - }, - "grid": { - subproperties: ["grid-template-areas", "grid-template-columns", "grid-template-rows", "grid-auto-flow", "grid-auto-columns", "grid-auto-rows", "grid-column-gap", "grid-row-gap", ], - inherited: false, - supports: 3, - values: ["-moz-calc", "calc", "inherit", "initial", "unset", ], - }, - "grid-column": { - subproperties: ["grid-column-start", "grid-column-end", ], - inherited: false, - supports: 1024, - values: ["inherit", "initial", "unset", ], - }, - "grid-row": { - subproperties: ["grid-row-start", "grid-row-end", ], - inherited: false, - supports: 1024, - values: ["inherit", "initial", "unset", ], - }, - "grid-area": { - subproperties: ["grid-row-start", "grid-column-start", "grid-row-end", "grid-column-end", ], - inherited: false, - supports: 1024, - values: ["inherit", "initial", "unset", ], - }, - "grid-gap": { - subproperties: ["grid-column-gap", "grid-row-gap", ], - inherited: false, - supports: 1, - values: ["-moz-calc", "calc", "inherit", "initial", "unset", ], - }, - "list-style": { - subproperties: ["list-style-type", "list-style-image", "list-style-position", ], - inherited: true, - supports: 8, - values: ["inherit", "initial", "inside", "none", "outside", "unset", "url", ], - }, - "margin": { - subproperties: ["margin-top", "margin-right", "margin-bottom", "margin-left", ], - inherited: false, - supports: 3, - values: ["-moz-calc", "auto", "calc", "inherit", "initial", "unset", ], - }, - "outline": { - subproperties: ["outline-width", "outline-style", "outline-color", ], - inherited: false, - supports: 5, - values: ["-moz-calc", "-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "auto", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "calc", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "dashed", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "dotted", "double", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "groove", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "inset", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", "maroon", "medium", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "none", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "outset", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "rebeccapurple", "red", "rgb", "rgba", "ridge", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "solid", "springgreen", "steelblue", "tan", "teal", "thick", "thin", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], - }, - "overflow": { - subproperties: ["overflow-x", "overflow-y", ], - inherited: false, - supports: 0, - values: ["-moz-hidden-unscrollable", "auto", "hidden", "inherit", "initial", "scroll", "unset", "visible", ], - }, - "padding": { - subproperties: ["padding-top", "padding-right", "padding-bottom", "padding-left", ], - inherited: false, - supports: 3, - values: ["-moz-calc", "calc", "inherit", "initial", "unset", ], - }, - "scroll-snap-type": { - subproperties: ["scroll-snap-type-x", "scroll-snap-type-y", ], - inherited: false, - supports: 0, - values: ["inherit", "initial", "mandatory", "none", "proximity", "unset", ], - }, - "text-decoration": { - subproperties: ["text-decoration-color", "text-decoration-line", "text-decoration-style", ], - inherited: false, - supports: 4, - values: ["-moz-none", "-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "dashed", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "dotted", "double", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", "maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "rebeccapurple", "red", "rgb", "rgba", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "solid", "springgreen", "steelblue", "tan", "teal", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wavy", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], - }, - "transition": { - subproperties: ["transition-property", "transition-duration", "transition-timing-function", "transition-delay", ], - inherited: false, - supports: 320, - values: ["all", "cubic-bezier", "ease", "ease-in", "ease-in-out", "ease-out", "inherit", "initial", "linear", "none", "step-end", "step-start", "steps", "unset", ], - }, - "marker": { - subproperties: ["marker-start", "marker-mid", "marker-end", ], - inherited: true, - supports: 8, - values: ["inherit", "initial", "none", "unset", "url", ], - }, - "-moz-transform": { - alias: true, - subproperties: ["transform", ], - inherited: false, - supports: 0, - values: ["inherit", "initial", "unset", ], - }, - "-moz-transform-origin": { - alias: true, - inherited: false, - supports: 3, - values: ["inherit", "initial", "unset", ], - }, - "-moz-perspective-origin": { - alias: true, - inherited: false, - supports: 3, - values: ["inherit", "initial", "unset", ], - }, - "-moz-perspective": { - alias: true, - inherited: false, - supports: 1, - values: ["inherit", "initial", "none", "unset", ], - }, - "-moz-transform-style": { - alias: true, - inherited: false, - supports: 0, - values: ["flat", "inherit", "initial", "preserve-3d", "unset", ], - }, - "-moz-backface-visibility": { - alias: true, - inherited: false, - supports: 0, - values: ["hidden", "inherit", "initial", "unset", "visible", ], - }, - "-moz-border-image": { - alias: true, - subproperties: ["border-image-source", "border-image-slice", "border-image-width", "border-image-outset", "border-image-repeat", ], - inherited: false, - supports: 1675, - values: ["-moz-element", "-moz-image-rect", "-moz-linear-gradient", "-moz-radial-gradient", "-moz-repeating-linear-gradient", "-moz-repeating-radial-gradient", "inherit", "initial", "linear-gradient", "none", "radial-gradient", "repeating-linear-gradient", "repeating-radial-gradient", "unset", "url", ], - }, - "-moz-transition": { - alias: true, - subproperties: ["transition-property", "transition-duration", "transition-timing-function", "transition-delay", ], - inherited: false, - supports: 320, - values: ["all", "cubic-bezier", "ease", "ease-in", "ease-in-out", "ease-out", "inherit", "initial", "linear", "none", "step-end", "step-start", "steps", "unset", ], - }, - "-moz-transition-delay": { - alias: true, - inherited: false, - supports: 64, - values: ["inherit", "initial", "unset", ], - }, - "-moz-transition-duration": { - alias: true, - inherited: false, - supports: 64, - values: ["inherit", "initial", "unset", ], - }, - "-moz-transition-property": { - alias: true, - inherited: false, - supports: 0, - values: ["all", "inherit", "initial", "none", "unset", ], - }, - "-moz-transition-timing-function": { - alias: true, - inherited: false, - supports: 256, - values: ["cubic-bezier", "ease", "ease-in", "ease-in-out", "ease-out", "inherit", "initial", "linear", "step-end", "step-start", "steps", "unset", ], - }, - "-moz-animation": { - alias: true, - subproperties: ["animation-duration", "animation-timing-function", "animation-delay", "animation-direction", "animation-fill-mode", "animation-iteration-count", "animation-play-state", "animation-name", ], - inherited: false, - supports: 1344, - values: ["alternate", "alternate-reverse", "backwards", "both", "cubic-bezier", "ease", "ease-in", "ease-in-out", "ease-out", "forwards", "infinite", "inherit", "initial", "linear", "none", "normal", "paused", "reverse", "running", "step-end", "step-start", "steps", "unset", ], - }, - "-moz-animation-delay": { - alias: true, - inherited: false, - supports: 64, - values: ["inherit", "initial", "unset", ], - }, - "-moz-animation-direction": { - alias: true, - inherited: false, - supports: 0, - values: ["alternate", "alternate-reverse", "inherit", "initial", "normal", "reverse", "unset", ], - }, - "-moz-animation-duration": { - alias: true, - inherited: false, - supports: 64, - values: ["inherit", "initial", "unset", ], - }, - "-moz-animation-fill-mode": { - alias: true, - inherited: false, - supports: 0, - values: ["backwards", "both", "forwards", "inherit", "initial", "none", "unset", ], - }, - "-moz-animation-iteration-count": { - alias: true, - inherited: false, - supports: 1024, - values: ["infinite", "inherit", "initial", "unset", ], - }, - "-moz-animation-name": { - alias: true, - inherited: false, - supports: 0, - values: ["inherit", "initial", "none", "unset", ], - }, - "-moz-animation-play-state": { - alias: true, - inherited: false, - supports: 0, - values: ["inherit", "initial", "paused", "running", "unset", ], - }, - "-moz-animation-timing-function": { - alias: true, - inherited: false, - supports: 256, - values: ["cubic-bezier", "ease", "ease-in", "ease-in-out", "ease-out", "inherit", "initial", "linear", "step-end", "step-start", "steps", "unset", ], - }, - "-moz-box-sizing": { - alias: true, - inherited: false, - supports: 0, - values: ["border-box", "content-box", "inherit", "initial", "padding-box", "unset", ], - }, - "-moz-font-feature-settings": { - alias: true, - inherited: true, - supports: 0, - values: ["inherit", "initial", "unset", ], - }, - "-moz-font-language-override": { - alias: true, - inherited: true, - supports: 0, - values: ["inherit", "initial", "normal", "unset", ], - }, - "-moz-padding-end": { - alias: true, - inherited: false, - supports: 3, - values: ["-moz-calc", "calc", "inherit", "initial", "unset", ], - }, - "-moz-padding-start": { - alias: true, - inherited: false, - supports: 3, - values: ["-moz-calc", "calc", "inherit", "initial", "unset", ], - }, - "-moz-margin-end": { - alias: true, - inherited: false, - supports: 3, - values: ["-moz-calc", "auto", "calc", "inherit", "initial", "unset", ], - }, - "-moz-margin-start": { - alias: true, - inherited: false, - supports: 3, - values: ["-moz-calc", "auto", "calc", "inherit", "initial", "unset", ], - }, - "-moz-border-end": { - alias: true, - subproperties: ["border-inline-end-width", "border-inline-end-style", "border-inline-end-color", ], - inherited: false, - supports: 5, - values: ["-moz-calc", "-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "calc", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "dashed", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "dotted", "double", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "groove", "hidden", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "inset", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", "maroon", "medium", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "none", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "outset", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "rebeccapurple", "red", "rgb", "rgba", "ridge", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "solid", "springgreen", "steelblue", "tan", "teal", "thick", "thin", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], - }, - "-moz-border-end-color": { - alias: true, - inherited: false, - supports: 4, - values: ["-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", "maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "rebeccapurple", "red", "rgb", "rgba", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "springgreen", "steelblue", "tan", "teal", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], - }, - "-moz-border-end-style": { - alias: true, - inherited: false, - supports: 0, - values: ["dashed", "dotted", "double", "groove", "hidden", "inherit", "initial", "inset", "none", "outset", "ridge", "solid", "unset", ], - }, - "-moz-border-end-width": { - alias: true, - inherited: false, - supports: 1, - values: ["-moz-calc", "calc", "inherit", "initial", "medium", "thick", "thin", "unset", ], - }, - "-moz-border-start": { - alias: true, - subproperties: ["border-inline-start-width", "border-inline-start-style", "border-inline-start-color", ], - inherited: false, - supports: 5, - values: ["-moz-calc", "-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "calc", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "dashed", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "dotted", "double", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "groove", "hidden", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "inset", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", "maroon", "medium", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "none", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "outset", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "rebeccapurple", "red", "rgb", "rgba", "ridge", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "solid", "springgreen", "steelblue", "tan", "teal", "thick", "thin", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], - }, - "-moz-border-start-color": { - alias: true, - inherited: false, - supports: 4, - values: ["-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", "maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "rebeccapurple", "red", "rgb", "rgba", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "springgreen", "steelblue", "tan", "teal", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], - }, - "-moz-border-start-style": { - alias: true, - inherited: false, - supports: 0, - values: ["dashed", "dotted", "double", "groove", "hidden", "inherit", "initial", "inset", "none", "outset", "ridge", "solid", "unset", ], - }, - "-moz-border-start-width": { - alias: true, - inherited: false, - supports: 1, - values: ["-moz-calc", "calc", "inherit", "initial", "medium", "thick", "thin", "unset", ], - }, - "-moz-hyphens": { - alias: true, - inherited: true, - supports: 0, - values: ["auto", "inherit", "initial", "manual", "none", "unset", ], - }, - "-webkit-animation": { - alias: true, - subproperties: ["animation-duration", "animation-timing-function", "animation-delay", "animation-direction", "animation-fill-mode", "animation-iteration-count", "animation-play-state", "animation-name", ], - inherited: false, - supports: 1344, - values: ["alternate", "alternate-reverse", "backwards", "both", "cubic-bezier", "ease", "ease-in", "ease-in-out", "ease-out", "forwards", "infinite", "inherit", "initial", "linear", "none", "normal", "paused", "reverse", "running", "step-end", "step-start", "steps", "unset", ], - }, - "-webkit-animation-delay": { - alias: true, - inherited: false, - supports: 64, - values: ["inherit", "initial", "unset", ], - }, - "-webkit-animation-direction": { - alias: true, - inherited: false, - supports: 0, - values: ["alternate", "alternate-reverse", "inherit", "initial", "normal", "reverse", "unset", ], - }, - "-webkit-animation-duration": { - alias: true, - inherited: false, - supports: 64, - values: ["inherit", "initial", "unset", ], - }, - "-webkit-animation-fill-mode": { - alias: true, - inherited: false, - supports: 0, - values: ["backwards", "both", "forwards", "inherit", "initial", "none", "unset", ], - }, - "-webkit-animation-iteration-count": { - alias: true, - inherited: false, - supports: 1024, - values: ["infinite", "inherit", "initial", "unset", ], - }, - "-webkit-animation-name": { - alias: true, - inherited: false, - supports: 0, - values: ["inherit", "initial", "none", "unset", ], - }, - "-webkit-animation-play-state": { - alias: true, - inherited: false, - supports: 0, - values: ["inherit", "initial", "paused", "running", "unset", ], - }, - "-webkit-animation-timing-function": { - alias: true, - inherited: false, - supports: 256, - values: ["cubic-bezier", "ease", "ease-in", "ease-in-out", "ease-out", "inherit", "initial", "linear", "step-end", "step-start", "steps", "unset", ], - }, - "-webkit-text-size-adjust": { - alias: true, - inherited: true, - supports: 0, - values: ["auto", "inherit", "initial", "none", "unset", ], - }, - "-webkit-transform": { - alias: true, - inherited: false, - supports: 0, - values: ["inherit", "initial", "unset", ], - }, - "-webkit-transform-origin": { - alias: true, - inherited: false, - supports: 3, - values: ["inherit", "initial", "unset", ], - }, - "-webkit-transform-style": { - alias: true, - inherited: false, - supports: 0, - values: ["flat", "inherit", "initial", "preserve-3d", "unset", ], - }, - "-webkit-backface-visibility": { - alias: true, - inherited: false, - supports: 0, - values: ["hidden", "inherit", "initial", "unset", "visible", ], - }, - "-webkit-perspective": { - alias: true, - inherited: false, - supports: 1, - values: ["inherit", "initial", "none", "unset", ], - }, - "-webkit-perspective-origin": { - alias: true, - inherited: false, - supports: 3, - values: ["inherit", "initial", "unset", ], - }, - "-webkit-transition": { - alias: true, - subproperties: ["transition-property", "transition-duration", "transition-timing-function", "transition-delay", ], - inherited: false, - supports: 320, - values: ["all", "cubic-bezier", "ease", "ease-in", "ease-in-out", "ease-out", "inherit", "initial", "linear", "none", "step-end", "step-start", "steps", "unset", ], - }, - "-webkit-transition-delay": { - alias: true, - inherited: false, - supports: 64, - values: ["inherit", "initial", "unset", ], - }, - "-webkit-transition-duration": { - alias: true, - inherited: false, - supports: 64, - values: ["inherit", "initial", "unset", ], - }, - "-webkit-transition-property": { - alias: true, - inherited: false, - supports: 0, - values: ["all", "inherit", "initial", "none", "unset", ], - }, - "-webkit-transition-timing-function": { - alias: true, - inherited: false, - supports: 256, - values: ["cubic-bezier", "ease", "ease-in", "ease-in-out", "ease-out", "inherit", "initial", "linear", "step-end", "step-start", "steps", "unset", ], - }, - "-webkit-border-radius": { - alias: true, - subproperties: ["border-top-left-radius", "border-top-right-radius", "border-bottom-right-radius", "border-bottom-left-radius", ], - inherited: false, - supports: 3, - values: ["inherit", "initial", "unset", ], - }, - "-webkit-border-top-left-radius": { - alias: true, - inherited: false, - supports: 3, - values: ["inherit", "initial", "unset", ], - }, - "-webkit-border-top-right-radius": { - alias: true, - inherited: false, - supports: 3, - values: ["inherit", "initial", "unset", ], - }, - "-webkit-border-bottom-left-radius": { - alias: true, - inherited: false, - supports: 3, - values: ["inherit", "initial", "unset", ], - }, - "-webkit-border-bottom-right-radius": { - alias: true, - inherited: false, - supports: 3, - values: ["inherit", "initial", "unset", ], - }, - "-webkit-appearance": { - alias: true, - inherited: false, - supports: 0, - values: ["-moz-gtk-info-bar", "-moz-mac-disclosure-button-closed", "-moz-mac-disclosure-button-open", "-moz-mac-fullscreen-button", "-moz-mac-help-button", "-moz-mac-vibrancy-dark", "-moz-mac-vibrancy-light", "-moz-win-borderless-glass", "-moz-win-browsertabbar-toolbox", "-moz-win-communications-toolbox", "-moz-win-exclude-glass", "-moz-win-glass", "-moz-win-media-toolbox", "-moz-window-button-box", "-moz-window-button-box-maximized", "-moz-window-button-close", "-moz-window-button-maximize", "-moz-window-button-minimize", "-moz-window-button-restore", "-moz-window-frame-bottom", "-moz-window-frame-left", "-moz-window-frame-right", "-moz-window-titlebar", "-moz-window-titlebar-maximized", "button", "button-arrow-down", "button-arrow-next", "button-arrow-previous", "button-arrow-up", "button-bevel", "button-focus", "caret", "checkbox", "checkbox-container", "checkbox-label", "checkmenuitem", "dialog", "dualbutton", "groupbox", "inherit", "initial", "listbox", "listitem", "menuarrow", "menubar", "menucheckbox", "menuimage", "menuitem", "menuitemtext", "menulist", "menulist-button", "menulist-text", "menulist-textfield", "menupopup", "menuradio", "menuseparator", "meterbar", "meterchunk", "none", "number-input", "progressbar", "progressbar-vertical", "progresschunk", "progresschunk-vertical", "radio", "radio-container", "radio-label", "radiomenuitem", "range", "range-thumb", "resizer", "resizerpanel", "scale-horizontal", "scale-vertical", "scalethumb-horizontal", "scalethumb-vertical", "scalethumbend", "scalethumbstart", "scalethumbtick", "scrollbar", "scrollbar-small", "scrollbarbutton-down", "scrollbarbutton-left", "scrollbarbutton-right", "scrollbarbutton-up", "scrollbarthumb-horizontal", "scrollbarthumb-vertical", "scrollbartrack-horizontal", "scrollbartrack-vertical", "searchfield", "separator", "spinner", "spinner-downbutton", "spinner-textfield", "spinner-upbutton", "splitter", "statusbar", "statusbarpanel", "tab", "tab-scroll-arrow-back", "tab-scroll-arrow-forward", "tabpanel", "tabpanels", "textfield", "textfield-multiline", "toolbar", "toolbarbutton", "toolbarbutton-dropdown", "toolbargripper", "toolbox", "tooltip", "treeheader", "treeheadercell", "treeheadersortarrow", "treeitem", "treeline", "treetwisty", "treetwistyopen", "treeview", "unset", "window", ], - }, - "-webkit-background-clip": { - alias: true, - inherited: false, - supports: 0, - values: ["border-box", "content-box", "inherit", "initial", "padding-box", "unset", ], - }, - "-webkit-background-origin": { - alias: true, - inherited: false, - supports: 0, - values: ["border-box", "content-box", "inherit", "initial", "padding-box", "unset", ], - }, - "-webkit-background-size": { - alias: true, - inherited: false, - supports: 3, - values: ["inherit", "initial", "unset", ], - }, - "-webkit-border-image": { - alias: true, - subproperties: ["border-image-source", "border-image-slice", "border-image-width", "border-image-outset", "border-image-repeat", ], - inherited: false, - supports: 1675, - values: ["-moz-element", "-moz-image-rect", "-moz-linear-gradient", "-moz-radial-gradient", "-moz-repeating-linear-gradient", "-moz-repeating-radial-gradient", "inherit", "initial", "linear-gradient", "none", "radial-gradient", "repeating-linear-gradient", "repeating-radial-gradient", "unset", "url", ], - }, - "-webkit-border-image-outset": { - alias: true, - inherited: false, - supports: 1025, - values: ["inherit", "initial", "unset", ], - }, - "-webkit-border-image-repeat": { - alias: true, - inherited: false, - supports: 0, - values: ["inherit", "initial", "unset", ], - }, - "-webkit-border-image-slice": { - alias: true, - inherited: false, - supports: 1026, - values: ["inherit", "initial", "unset", ], - }, - "-webkit-border-image-source": { - alias: true, - inherited: false, - supports: 648, - values: ["-moz-element", "-moz-image-rect", "-moz-linear-gradient", "-moz-radial-gradient", "-moz-repeating-linear-gradient", "-moz-repeating-radial-gradient", "inherit", "initial", "linear-gradient", "none", "radial-gradient", "repeating-linear-gradient", "repeating-radial-gradient", "unset", "url", ], - }, - "-webkit-border-image-width": { - alias: true, - inherited: false, - supports: 1027, - values: ["inherit", "initial", "unset", ], - }, - "-webkit-box-shadow": { - alias: true, - inherited: false, - supports: 5, - values: ["inherit", "initial", "unset", ], - }, - "-webkit-box-sizing": { - alias: true, - inherited: false, - supports: 0, - values: ["border-box", "content-box", "inherit", "initial", "padding-box", "unset", ], - }, - "-webkit-box-flex": { - alias: true, - inherited: false, - supports: 1024, - values: ["inherit", "initial", "unset", ], - }, - "-webkit-box-ordinal-group": { - alias: true, - inherited: false, - supports: 1024, - values: ["inherit", "initial", "unset", ], - }, - "-webkit-box-align": { - alias: true, - inherited: false, - supports: 0, - values: ["inherit", "initial", "unset", ], - }, - "-webkit-box-pack": { - alias: true, - inherited: false, - supports: 0, - values: ["inherit", "initial", "unset", ], - }, - "-webkit-user-select": { - alias: true, - inherited: false, - supports: 0, - values: ["-moz-all", "-moz-none", "-moz-text", "all", "auto", "element", "elements", "inherit", "initial", "none", "text", "toggle", "tri-state", "unset", ], - }, -}; -module.exports = { cssProperties }; diff --git a/packages/devtools-sham-modules/sham/fileutils.js b/packages/devtools-sham-modules/sham/fileutils.js deleted file mode 100644 index ecb17dadd7..0000000000 --- a/packages/devtools-sham-modules/sham/fileutils.js +++ /dev/null @@ -1,3 +0,0 @@ -/* - * A sham for https://dxr.mozilla.org/mozilla-central/source/toolkit/modules/FileUtils.jsm - */ diff --git a/packages/devtools-sham-modules/sham/inDOMUtils.js b/packages/devtools-sham-modules/sham/inDOMUtils.js deleted file mode 100644 index 4abfa296e5..0000000000 --- a/packages/devtools-sham-modules/sham/inDOMUtils.js +++ /dev/null @@ -1,294 +0,0 @@ -// A sham for inDOMUtils. - -"use strict"; - -var { CSSLexer } = require("./parse-css"); -var { cssColors } = require("./css-color-db"); -var { cssProperties } = require("./css-property-db"); - -var cssRGBMap; - -// From inIDOMUtils.idl. -var EXCLUDE_SHORTHANDS = (1 << 0); -var INCLUDE_ALIASES = (1 << 1); -var TYPE_LENGTH = 0; -var TYPE_PERCENTAGE = 1; -var TYPE_COLOR = 2; -var TYPE_URL = 3; -var TYPE_ANGLE = 4; -var TYPE_FREQUENCY = 5; -var TYPE_TIME = 6; -var TYPE_GRADIENT = 7; -var TYPE_TIMING_FUNCTION = 8; -var TYPE_IMAGE_RECT = 9; -var TYPE_NUMBER = 10; - -function getCSSLexer(text) { - return new CSSLexer(text); -} - -function rgbToColorName(r, g, b) { - if (!cssRGBMap) { - cssRGBMap = new Map(); - for (let name in cssColors) { - cssRGBMap.set(JSON.stringify(cssColors[name]), name); - } - } - let value = cssRGBMap.get(JSON.stringify([r, g, b])); - if (!value) { - throw new Error("no such color"); - } - return value; -} - -// Taken from dom/tests/mochitest/ajax/mochikit/MochiKit/Color.js -function _hslValue(n1, n2, hue) { - if (hue > 6.0) { - hue -= 6.0; - } else if (hue < 0.0) { - hue += 6.0; - } - var val; - if (hue < 1.0) { - val = n1 + (n2 - n1) * hue; - } else if (hue < 3.0) { - val = n2; - } else if (hue < 4.0) { - val = n1 + (n2 - n1) * (4.0 - hue); - } else { - val = n1; - } - return val; -} - -// Taken from dom/tests/mochitest/ajax/mochikit/MochiKit/Color.js -// and then modified. -function hslToRGB([hue, saturation, lightness]) { - var red; - var green; - var blue; - if (saturation === 0) { - red = lightness; - green = lightness; - blue = lightness; - } else { - var m2; - if (lightness <= 0.5) { - m2 = lightness * (1.0 + saturation); - } else { - m2 = lightness + saturation - (lightness * saturation); - } - var m1 = (2.0 * lightness) - m2; - var f = _hslValue; - var h6 = hue * 6.0; - red = f(m1, m2, h6 + 2); - green = f(m1, m2, h6); - blue = f(m1, m2, h6 - 2); - } - return [red, green, blue]; -} - -function colorToRGBA(name) { - name = name.trim().toLowerCase(); - if (name in cssColors) { - return cssColors[name]; - } - - if (name === "transparent") { - return [0, 0, 0, 0]; - } - - let lexer = getCSSLexer(name); - - let getToken = function() { - while (true) { - let token = lexer.nextToken(); - if (!token || token.tokenType !== "comment" || - token.tokenType !== "whitespace") { - return token; - } - } - }; - - let requireComma = function(token) { - if (token.tokenType !== "symbol" || token.text !== ",") { - return null; - } - return getToken(); - }; - - let func = getToken(); - if (!func || func.tokenType !== "function") { - return null; - } - let alpha = false; - if (func.text === "rgb" || func.text === "hsl") { - // Nothing. - } else if (func.text === "rgba" || func.text === "hsla") { - alpha = true; - } else { - return null; - } - - let vals = []; - for (let i = 0; i < 3; ++i) { - let token = getToken(); - if (i > 0) { - token = requireComma(token); - } - if (token.tokenType !== "number" || !token.isInteger) { - return null; - } - let num = token.number; - if (num < 0) { - num = 0; - } else if (num > 255) { - num = 255; - } - vals.push(num); - } - - if (func.text === "hsl" || func.text === "hsla") { - vals = hslToRGB(vals); - } - - if (alpha) { - let token = requireComma(getToken()); - if (token.tokenType !== "number") { - return null; - } - let num = token.number; - if (num < 0) { - num = 0; - } else if (num > 1) { - num = 1; - } - vals.push(num); - } else { - vals.push(1); - } - - let parenToken = getToken(); - if (!parenToken || parenToken.tokenType !== "symbol" || - parenToken.text !== ")") { - return null; - } - if (getToken() !== null) { - return null; - } - - return vals; -} - -function isValidCSSColor(name) { - return colorToRGBA(name) !== null; -} - -function isVariable(name) { - return name.startsWith("--"); -} - -function cssPropertyIsShorthand(name) { - if (isVariable(name)) { - return false; - } - if (!(name in cssProperties)) { - throw Error("unknown property " + name); - } - return !!cssProperties[name].subproperties; -} - -function getSubpropertiesForCSSProperty(name) { - if (isVariable(name)) { - return [name]; - } - if (!(name in cssProperties)) { - throw Error("unknown property " + name); - } - if ("subproperties" in cssProperties[name]) { - return cssProperties[name].subproperties.slice(); - } - return [name]; -} - -function getCSSValuesForProperty(name) { - if (isVariable(name)) { - return ["initial", "inherit", "unset"]; - } - if (!(name in cssProperties)) { - throw Error("unknown property " + name); - } - return cssProperties[name].values.slice(); -} - -function getCSSPropertyNames(flags) { - let names = Object.keys(cssProperties); - if ((flags & EXCLUDE_SHORTHANDS) !== 0) { - names = names.filter((name) => cssProperties[name].subproperties); - } - if ((flags & INCLUDE_ALIASES) === 0) { - names = names.filter((name) => !cssProperties[name].alias); - } - return names; -} - -function cssPropertySupportsType(name, type) { - if (isVariable(name)) { - return false; - } - if (!(name in cssProperties)) { - throw Error("unknown property " + name); - } - return (cssProperties[name].supports & (1 << type)) !== 0; -} - -function isInheritedProperty(name) { - if (isVariable(name)) { - return true; - } - if (!(name in cssProperties)) { - return false; - } - return cssProperties[name].inherited; -} - -function cssPropertyIsValid(name, value) { - if (isVariable(name)) { - return true; - } - if (!(name in cssProperties)) { - return false; - } - let elt = document.createElement("div"); - elt.style = name + ":" + value; - return elt.style.length > 0; -} - -exports.inDOMUtils = { - getCSSLexer, - rgbToColorName, - colorToRGBA, - isValidCSSColor, - cssPropertyIsShorthand, - getSubpropertiesForCSSProperty, - getCSSValuesForProperty, - getCSSPropertyNames, - cssPropertySupportsType, - isInheritedProperty, - cssPropertyIsValid, - - // Constants. - EXCLUDE_SHORTHANDS, - INCLUDE_ALIASES, - TYPE_LENGTH, - TYPE_PERCENTAGE, - TYPE_COLOR, - TYPE_URL, - TYPE_ANGLE, - TYPE_FREQUENCY, - TYPE_TIME, - TYPE_GRADIENT, - TYPE_TIMING_FUNCTION, - TYPE_IMAGE_RECT, - TYPE_NUMBER, -}; diff --git a/packages/devtools-sham-modules/sham/netutil.js b/packages/devtools-sham-modules/sham/netutil.js deleted file mode 100644 index 1960b1a882..0000000000 --- a/packages/devtools-sham-modules/sham/netutil.js +++ /dev/null @@ -1,3 +0,0 @@ -/* - * A sham for https://dxr.mozilla.org/mozilla-central/source/netwerk/base/NetUtil.jsm - */ diff --git a/packages/devtools-sham-modules/sham/osfile.js b/packages/devtools-sham-modules/sham/osfile.js deleted file mode 100644 index 8d9b5627b7..0000000000 --- a/packages/devtools-sham-modules/sham/osfile.js +++ /dev/null @@ -1,3 +0,0 @@ -/* - * A sham for https://dxr.mozilla.org/mozilla-central/source/toolkit/components/osfile/osfile.jsm - */ diff --git a/packages/devtools-sham-modules/sham/parse-css.js b/packages/devtools-sham-modules/sham/parse-css.js deleted file mode 100644 index 755c6f08d8..0000000000 --- a/packages/devtools-sham-modules/sham/parse-css.js +++ /dev/null @@ -1,1429 +0,0 @@ -"use strict"; - -(function (root, factory) { - // Universal Module Definition (UMD) to support AMD, CommonJS/Node.js, - // Rhino, and plain browser loading. - if (typeof define === 'function' && define.amd) { - define(['exports'], factory); - } else if (typeof exports !== 'undefined') { - factory(exports); - } else { - factory(root); - } -}(this, function (exports) { - -function between(num, first, last) { return num >= first && num <= last; } -function digit(code) { return between(code, 0x30,0x39); } -function hexdigit(code) { return digit(code) || between(code, 0x41,0x46) || between(code, 0x61,0x66); } -function uppercaseletter(code) { return between(code, 0x41,0x5a); } -function lowercaseletter(code) { return between(code, 0x61,0x7a); } -function letter(code) { return uppercaseletter(code) || lowercaseletter(code); } -function nonascii(code) { return code >= 0x80; } -function namestartchar(code) { return letter(code) || nonascii(code) || code == 0x5f; } -function namechar(code) { return namestartchar(code) || digit(code) || code == 0x2d; } -function nonprintable(code) { return between(code, 0,8) || code == 0xb || between(code, 0xe,0x1f) || code == 0x7f; } -function newline(code) { return code == 0xa; } -function whitespace(code) { return newline(code) || code == 9 || code == 0x20; } - -var maximumallowedcodepoint = 0x10ffff; - -var InvalidCharacterError = function(message) { - this.message = message; -}; -InvalidCharacterError.prototype = new Error; -InvalidCharacterError.prototype.name = 'InvalidCharacterError'; - -function stringFromCode(code) { - if(code <= 0xffff) return String.fromCharCode(code); - // Otherwise, encode astral char as surrogate pair. - code -= Math.pow(2, 20); - var lead = Math.floor(code/Math.pow(2, 10)) + 0xd800; - var trail = code % Math.pow(2, 10) + 0xdc00; - return String.fromCharCode(lead) + String.fromCharCode(trail); -} - -function* tokenize(str, options) { - if (options === undefined) { - options = {}; - } - if (options.loc === undefined) { - options.loc = false; - } - if (options.offsets === undefined) { - options.offsets = false; - } - if (options.keepComments === undefined) { - options.keepComments = false; - } - if (options.startOffset === undefined) { - options.startOffset = 0; - } - - var i = options.startOffset - 1; - var code; - - // Line number information. - var line = 0; - var column = 0; - // The only use of lastLineLength is in reconsume(). - var lastLineLength = 0; - var incrLineno = function() { - line += 1; - lastLineLength = column; - column = 0; - }; - var locStart = {line:line, column:column}; - var offsetStart = i; - - var codepoint = function(i) { - if(i >= str.length) { - return -1; - } - return str.charCodeAt(i); - }; - var next = function(num) { - if(num === undefined) - num = 1; - if(num > 3) - throw "Spec Error: no more than three codepoints of lookahead."; - - var rcode; - for (var offset = i + 1; num-- > 0; ++offset) { - rcode = codepoint(offset); - if (rcode === 0xd && codepoint(offset+1) === 0xa) { - ++offset; - rcode = 0xa; - } else if (rcode === 0xd || rcode === 0xc) { - rcode = 0xa; - } else if (rcode === 0x0) { - rcode = 0xfffd; - } - } - - return rcode; - }; - var consume = function(num) { - if(num === undefined) - num = 1; - while(num-- > 0) { - ++i; - code = codepoint(i); - if (code === 0xd && codepoint(i+1) === 0xa) { - ++i; - code = 0xa; - } else if (code === 0xd || code === 0xc) { - code = 0xa; - } else if (code === 0x0) { - code = 0xfffd; - } - if(newline(code)) incrLineno(); - else column++; - } - return true; - }; - var reconsume = function() { - i -= 1; // This is ok even in the \r\n case. - if (newline(code)) { - line -= 1; - column = lastLineLength; - } else { - column -= 1; - } - return true; - }; - var eof = function(codepoint) { - if(codepoint === undefined) codepoint = code; - return codepoint == -1; - }; - var donothing = function() {}; - var parseerror = function() { console.log("Parse error at index " + i + ", processing codepoint 0x" + code.toString(16) + ".");return true; }; - - var consumeAToken = function() { - consume(); - if (!options.keepComments) { - while(code == 0x2f && next() == 0x2a) { - consumeAComment(); - consume(); - } - } - locStart.line = line; - locStart.column = column; - offsetStart = i; - if(whitespace(code)) { - while(whitespace(next())) consume(); - return new WhitespaceToken; - } - else if(code == 0x2f && next() == 0x2a) return consumeAComment(); - else if(code == 0x22) return consumeAStringToken(); - else if(code == 0x23) { - if(namechar(next()) || areAValidEscape(next(1), next(2))) { - var token = new HashToken(); - if(wouldStartAnIdentifier(next(1), next(2), next(3))) { - token.type = "id"; - token.tokenType = "id"; - } - token.value = consumeAName(); - token.text = token.value; - return token; - } else { - return new DelimToken(code); - } - } - else if(code == 0x24) { - if(next() == 0x3d) { - consume(); - return new SuffixMatchToken(); - } else { - return new DelimToken(code); - } - } - else if(code == 0x27) return consumeAStringToken(); - else if(code == 0x28) return new OpenParenToken(); - else if(code == 0x29) return new CloseParenToken(); - else if(code == 0x2a) { - if(next() == 0x3d) { - consume(); - return new SubstringMatchToken(); - } else { - return new DelimToken(code); - } - } - else if(code == 0x2b) { - if(startsWithANumber()) { - reconsume(); - return consumeANumericToken(); - } else { - return new DelimToken(code); - } - } - else if(code == 0x2c) return new CommaToken(); - else if(code == 0x2d) { - if(startsWithANumber()) { - reconsume(); - return consumeANumericToken(); - } else if(next(1) == 0x2d && next(2) == 0x3e) { - consume(2); - return new CDCToken(); - } else if(startsWithAnIdentifier()) { - reconsume(); - return consumeAnIdentlikeToken(); - } else { - return new DelimToken(code); - } - } - else if(code == 0x2e) { - if(startsWithANumber()) { - reconsume(); - return consumeANumericToken(); - } else { - return new DelimToken(code); - } - } - else if(code == 0x3a) return new ColonToken; - else if(code == 0x3b) return new SemicolonToken; - else if(code == 0x3c) { - if(next(1) == 0x21 && next(2) == 0x2d && next(3) == 0x2d) { - consume(3); - return new CDOToken(); - } else { - return new DelimToken(code); - } - } - else if(code == 0x40) { - if(wouldStartAnIdentifier(next(1), next(2), next(3))) { - return new AtKeywordToken(consumeAName()); - } else { - return new DelimToken(code); - } - } - else if(code == 0x5b) return new OpenSquareToken(); - else if(code == 0x5c) { - if(startsWithAValidEscape()) { - reconsume(); - return consumeAnIdentlikeToken(); - } else { - parseerror(); - return new DelimToken(code); - } - } - else if(code == 0x5d) return new CloseSquareToken(); - else if(code == 0x5e) { - if(next() == 0x3d) { - consume(); - return new PrefixMatchToken(); - } else { - return new DelimToken(code); - } - } - else if(code == 0x7b) return new OpenCurlyToken(); - else if(code == 0x7c) { - if(next() == 0x3d) { - consume(); - return new DashMatchToken(); - // } else if(next() == 0x7c) { - // consume(); - // return new ColumnToken(); - } else { - return new DelimToken(code); - } - } - else if(code == 0x7d) return new CloseCurlyToken(); - else if(code == 0x7e) { - if(next() == 0x3d) { - consume(); - return new IncludeMatchToken(); - } else { - return new DelimToken(code); - } - } - else if(digit(code)) { - reconsume(); - return consumeANumericToken(); - } - else if(namestartchar(code)) { - reconsume(); - return consumeAnIdentlikeToken(); - } - else if(eof()) return new EOFToken(); - else return new DelimToken(code); - }; - - var consumeAComment = function() { - consume(); - var comment = ""; - while(true) { - consume(); - if(code == 0x2a && next() == 0x2f) { - consume(); - break; - } else if(eof()) { - break; - } - comment += stringFromCode(code); - } - return new CommentToken(comment); - }; - - var consumeANumericToken = function() { - var num = consumeANumber(); - var token; - if(wouldStartAnIdentifier(next(1), next(2), next(3))) { - token = new DimensionToken(); - token.value = num.value; - token.repr = num.repr; - token.type = num.type; - token.unit = consumeAName(); - token.text = token.unit; - } else if(next() == 0x25) { - consume(); - token = new PercentageToken(); - token.value = num.value; - token.repr = num.repr; - } else { - var token = new NumberToken(); - token.value = num.value; - token.repr = num.repr; - token.type = num.type; - } - token.number = token.value; - token.isInteger = token.type === "integer"; - // FIXME hasSign - return token; - }; - - var consumeAnIdentlikeToken = function() { - var str = consumeAName(); - if(str.toLowerCase() == "url" && next() == 0x28) { - consume(); - while(whitespace(next(1)) && whitespace(next(2))) - consume(); - if((next() == 0x22 || next() == 0x27) || - (whitespace(next()) && (next(2) == 0x22 || next(2) == 0x27))) { - while(whitespace(next())) - consume(); - consume(); - let str = consumeAStringToken(); - while(whitespace(next())) - consume(); - // The closing paren. - consume(); - return new URLToken(str.text); - } else { - return consumeAURLToken(); - } - } else if(next() == 0x28) { - consume(); - return new FunctionToken(str); - } else { - return new IdentToken(str); - } - }; - - var consumeAStringToken = function(endingCodePoint) { - if(endingCodePoint === undefined) endingCodePoint = code; - var string = ""; - while(consume()) { - if(code == endingCodePoint || eof()) { - return new StringToken(string); - } else if(newline(code)) { - reconsume(); - return new BadStringToken(string); - } else if(code == 0x5c) { - if(eof(next())) { - donothing(); - } else if(newline(next())) { - consume(); - } else { - string += stringFromCode(consumeEscape()); - } - } else { - string += stringFromCode(code); - } - } - }; - - var consumeAURLToken = function() { - var token = new URLToken(""); - while(whitespace(next())) consume(); - if(eof(next())) return token; - while(consume()) { - if(code == 0x29 || eof()) { - break; - } else if(whitespace(code)) { - while(whitespace(next())) - consume(); - if(next() == 0x29 || eof(next())) { - consume(); - break; - } else { - consumeTheRemnantsOfABadURL(); - return new BadURLToken(); - } - } else if(code == 0x22 || code == 0x27 || code == 0x28 || nonprintable(code)) { - parseerror(); - consumeTheRemnantsOfABadURL(); - return new BadURLToken(); - } else if(code == 0x5c) { - if(startsWithAValidEscape()) { - token.value += stringFromCode(consumeEscape()); - } else { - parseerror(); - consumeTheRemnantsOfABadURL(); - return new BadURLToken(); - } - } else { - token.value += stringFromCode(code); - } - } - token.text = token.value; - return token; - }; - - var consumeEscape = function() { - // Assume the the current character is the \ - // and the next code point is not a newline. - consume(); - if(hexdigit(code)) { - // Consume 1-6 hex digits - var digits = [code]; - for(var total = 0; total < 5; total++) { - if(hexdigit(next())) { - consume(); - digits.push(code); - } else { - break; - } - } - if(whitespace(next())) consume(); - var value = parseInt(digits.map(function(x){return String.fromCharCode(x);}).join(''), 16); - if( value > maximumallowedcodepoint ) value = 0xfffd; - return value; - } else if(eof()) { - return 0xfffd; - } else { - return code; - } - }; - - var areAValidEscape = function(c1, c2) { - if(c1 != 0x5c) return false; - if(newline(c2)) return false; - return true; - }; - var startsWithAValidEscape = function() { - return areAValidEscape(code, next()); - }; - - var wouldStartAnIdentifier = function(c1, c2, c3) { - if(c1 == 0x2d) { - return namestartchar(c2) || c2 == 0x2d || areAValidEscape(c2, c3); - } else if(namestartchar(c1)) { - return true; - } else if(c1 == 0x5c) { - return areAValidEscape(c1, c2); - } else { - return false; - } - }; - var startsWithAnIdentifier = function() { - return wouldStartAnIdentifier(code, next(1), next(2)); - }; - - var wouldStartANumber = function(c1, c2, c3) { - if(c1 == 0x2b || c1 == 0x2d) { - if(digit(c2)) return true; - if(c2 == 0x2e && digit(c3)) return true; - return false; - } else if(c1 == 0x2e) { - if(digit(c2)) return true; - return false; - } else if(digit(c1)) { - return true; - } else { - return false; - } - }; - var startsWithANumber = function() { - return wouldStartANumber(code, next(1), next(2)); - }; - - var consumeAName = function() { - var result = ""; - while(consume()) { - if(namechar(code)) { - result += stringFromCode(code); - } else if(startsWithAValidEscape()) { - result += stringFromCode(consumeEscape()); - } else { - reconsume(); - return result; - } - } - }; - - var consumeANumber = function() { - var repr = []; - var type = "integer"; - if(next() == 0x2b || next() == 0x2d) { - consume(); - repr += stringFromCode(code); - } - while(digit(next())) { - consume(); - repr += stringFromCode(code); - } - if(next(1) == 0x2e && digit(next(2))) { - consume(); - repr += stringFromCode(code); - consume(); - repr += stringFromCode(code); - type = "number"; - while(digit(next())) { - consume(); - repr += stringFromCode(code); - } - } - var c1 = next(1), c2 = next(2), c3 = next(3); - if((c1 == 0x45 || c1 == 0x65) && digit(c2)) { - consume(); - repr += stringFromCode(code); - consume(); - repr += stringFromCode(code); - type = "number"; - while(digit(next())) { - consume(); - repr += stringFromCode(code); - } - } else if((c1 == 0x45 || c1 == 0x65) && (c2 == 0x2b || c2 == 0x2d) && digit(c3)) { - consume(); - repr += stringFromCode(code); - consume(); - repr += stringFromCode(code); - consume(); - repr += stringFromCode(code); - type = "number"; - while(digit(next())) { - consume(); - repr += stringFromCode(code); - } - } - var value = convertAStringToANumber(repr); - return {type:type, value:value, repr:repr}; - }; - - var convertAStringToANumber = function(string) { - // CSS's number rules are identical to JS, afaik. - return +string; - }; - - var consumeTheRemnantsOfABadURL = function() { - while(consume()) { - if(code == 0x2d || eof()) { - return; - } else if(startsWithAValidEscape()) { - consumeEscape(); - donothing(); - } else { - donothing(); - } - } - }; - - - - var iterationCount = 0; - while(!eof(next())) { - var token = consumeAToken(); - if (options.loc) { - token.loc = {}; - token.loc.start = {line:locStart.line, column:locStart.column}; - token.loc.end = {line:line, column:column}; - } - if (options.offsets) { - token.startOffset = offsetStart; - token.endOffset = i + 1; - } - yield token; - iterationCount++; - if(iterationCount > str.length*2) return "I'm infinite-looping!"; - } -} - -function CSSParserToken() { throw "Abstract Base Class"; } -CSSParserToken.prototype.toJSON = function() { - return {token: this.tokenType}; -}; -CSSParserToken.prototype.toString = function() { return this.tokenType; }; -CSSParserToken.prototype.toSource = function() { return ''+this; }; - -function BadStringToken(text) { - this.text = text; - return this; -} -BadStringToken.prototype = Object.create(CSSParserToken.prototype); -BadStringToken.prototype.tokenType = "bad_string"; - -function BadURLToken() { return this; } -BadURLToken.prototype = Object.create(CSSParserToken.prototype); -BadURLToken.prototype.tokenType = "bad_url"; - -function WhitespaceToken() { return this; } -WhitespaceToken.prototype = Object.create(CSSParserToken.prototype); -WhitespaceToken.prototype.tokenType = "whitespace"; -WhitespaceToken.prototype.toString = function() { return "WS"; }; -WhitespaceToken.prototype.toSource = function() { return " "; }; - -function CDOToken() { return this; } -CDOToken.prototype = Object.create(CSSParserToken.prototype); -CDOToken.prototype.tokenType = "htmlcomment"; -CDOToken.prototype.toSource = function() { return ""; }; - -function ColonToken() { return this; } -ColonToken.prototype = Object.create(CSSParserToken.prototype); -ColonToken.prototype.tokenType = "symbol"; -ColonToken.prototype.text = ":"; - -function SemicolonToken() { return this; } -SemicolonToken.prototype = Object.create(CSSParserToken.prototype); -SemicolonToken.prototype.tokenType = "symbol"; -SemicolonToken.prototype.text = ";"; - -function CommaToken() { return this; } -CommaToken.prototype = Object.create(CSSParserToken.prototype); -CommaToken.prototype.tokenType = "symbol"; -CommaToken.prototype.text = ","; - -function GroupingToken() { throw "Abstract Base Class"; } -GroupingToken.prototype = Object.create(CSSParserToken.prototype); - -function OpenCurlyToken() { this.value = "{"; this.mirror = "}"; return this; } -OpenCurlyToken.prototype = Object.create(GroupingToken.prototype); -OpenCurlyToken.prototype.tokenType = "symbol"; -OpenCurlyToken.prototype.text = "{"; - -function CloseCurlyToken() { this.value = "}"; this.mirror = "{"; return this; } -CloseCurlyToken.prototype = Object.create(GroupingToken.prototype); -CloseCurlyToken.prototype.tokenType = "symbol"; -CloseCurlyToken.prototype.text = "}"; - -function OpenSquareToken() { this.value = "["; this.mirror = "]"; return this; } -OpenSquareToken.prototype = Object.create(GroupingToken.prototype); -OpenSquareToken.prototype.tokenType = "symbol"; -OpenSquareToken.prototype.text = "["; - -function CloseSquareToken() { this.value = "]"; this.mirror = "["; return this; } -CloseSquareToken.prototype = Object.create(GroupingToken.prototype); -CloseSquareToken.prototype.tokenType = "symbol"; -CloseSquareToken.prototype.text = "]"; - -function OpenParenToken() { this.value = "("; this.mirror = ")"; return this; } -OpenParenToken.prototype = Object.create(GroupingToken.prototype); -OpenParenToken.prototype.tokenType = "symbol"; -OpenParenToken.prototype.text = "("; - -function CloseParenToken() { this.value = ")"; this.mirror = "("; return this; } -CloseParenToken.prototype = Object.create(GroupingToken.prototype); -CloseParenToken.prototype.tokenType = "symbol"; -CloseParenToken.prototype.text = ")"; - -function IncludeMatchToken() { return this; } -IncludeMatchToken.prototype = Object.create(CSSParserToken.prototype); -IncludeMatchToken.prototype.tokenType = "includes"; - -function DashMatchToken() { return this; } -DashMatchToken.prototype = Object.create(CSSParserToken.prototype); -DashMatchToken.prototype.tokenType = "dashmatch"; - -function PrefixMatchToken() { return this; } -PrefixMatchToken.prototype = Object.create(CSSParserToken.prototype); -PrefixMatchToken.prototype.tokenType = "beginsmatch"; - -function SuffixMatchToken() { return this; } -SuffixMatchToken.prototype = Object.create(CSSParserToken.prototype); -SuffixMatchToken.prototype.tokenType = "endsmatch"; - -function SubstringMatchToken() { return this; } -SubstringMatchToken.prototype = Object.create(CSSParserToken.prototype); -SubstringMatchToken.prototype.tokenType = "containsmatch"; - -function ColumnToken() { return this; } -ColumnToken.prototype = Object.create(CSSParserToken.prototype); -ColumnToken.prototype.tokenType = "||"; - -function EOFToken() { return this; } -EOFToken.prototype = Object.create(CSSParserToken.prototype); -EOFToken.prototype.tokenType = "EOF"; -EOFToken.prototype.toSource = function() { return ""; }; - -function DelimToken(code) { - this.value = stringFromCode(code); - this.text = this.value; - return this; -} -DelimToken.prototype = Object.create(CSSParserToken.prototype); -DelimToken.prototype.tokenType = "symbol"; -DelimToken.prototype.toString = function() { return "DELIM("+this.value+")"; }; -DelimToken.prototype.toJSON = function() { - var json = this.constructor.prototype.constructor.prototype.toJSON.call(this); - json.value = this.value; - return json; -}; -DelimToken.prototype.toSource = function() { - if(this.value == "\\") - return "\\\n"; - else - return this.value; -}; - -function StringValuedToken() { throw "Abstract Base Class"; } -StringValuedToken.prototype = Object.create(CSSParserToken.prototype); -StringValuedToken.prototype.ASCIIMatch = function(str) { - return this.value.toLowerCase() == str.toLowerCase(); -}; -StringValuedToken.prototype.toJSON = function() { - var json = this.constructor.prototype.constructor.prototype.toJSON.call(this); - json.value = this.value; - return json; -}; - -function IdentToken(val) { - this.value = val; - this.text = val; -} -IdentToken.prototype = Object.create(StringValuedToken.prototype); -IdentToken.prototype.tokenType = "ident"; -IdentToken.prototype.toString = function() { return "IDENT("+this.value+")"; }; -IdentToken.prototype.toSource = function() { - return escapeIdent(this.value); -}; - -function FunctionToken(val) { - this.value = val; - this.text = val; - this.mirror = ")"; -} -FunctionToken.prototype = Object.create(StringValuedToken.prototype); -FunctionToken.prototype.tokenType = "function"; -FunctionToken.prototype.toString = function() { return "FUNCTION("+this.value+")"; }; -FunctionToken.prototype.toSource = function() { - return escapeIdent(this.value) + "("; -}; - -function AtKeywordToken(val) { - this.value = val; - this.text = val; -} -AtKeywordToken.prototype = Object.create(StringValuedToken.prototype); -AtKeywordToken.prototype.tokenType = "at"; -AtKeywordToken.prototype.toString = function() { return "AT("+this.value+")"; }; -AtKeywordToken.prototype.toSource = function() { - return "@" + escapeIdent(this.value); -}; - -function HashToken(val) { - this.value = val; - this.text = val; - this.type = "unrestricted"; -} -HashToken.prototype = Object.create(StringValuedToken.prototype); -HashToken.prototype.tokenType = "hash"; -HashToken.prototype.toString = function() { return "HASH("+this.value+")"; }; -HashToken.prototype.toJSON = function() { - var json = this.constructor.prototype.constructor.prototype.toJSON.call(this); - json.value = this.value; - json.type = this.type; - return json; -}; -HashToken.prototype.toSource = function() { - if(this.type == "id") { - return "#" + escapeIdent(this.value); - } else { - return "#" + escapeHash(this.value); - } -}; - -function StringToken(val) { - this.value = val; - this.text = val; -} -StringToken.prototype = Object.create(StringValuedToken.prototype); -StringToken.prototype.tokenType = "string"; -StringToken.prototype.toString = function() { - return '"' + escapeString(this.value) + '"'; -}; - -function CommentToken(val) { - this.value = val; -} -CommentToken.prototype = Object.create(StringValuedToken.prototype); -CommentToken.prototype.tokenType = "comment"; -CommentToken.prototype.toString = function() { - return '/*' + this.value + '*/'; -} -CommentToken.prototype.toSource = CommentToken.prototype.toString; - -function URLToken(val) { - this.value = val; - this.text = val; -} -URLToken.prototype = Object.create(StringValuedToken.prototype); -URLToken.prototype.tokenType = "url"; -URLToken.prototype.toString = function() { return "URL("+this.value+")"; }; -URLToken.prototype.toSource = function() { - return 'url("' + escapeString(this.value) + '")'; -}; - -function NumberToken() { - this.value = null; - this.type = "integer"; - this.repr = ""; -} -NumberToken.prototype = Object.create(CSSParserToken.prototype); -NumberToken.prototype.tokenType = "number"; -NumberToken.prototype.toString = function() { - if(this.type == "integer") - return "INT("+this.value+")"; - return "NUMBER("+this.value+")"; -}; -NumberToken.prototype.toJSON = function() { - var json = this.constructor.prototype.constructor.prototype.toJSON.call(this); - json.value = this.value; - json.type = this.type; - json.repr = this.repr; - return json; -}; -NumberToken.prototype.toSource = function() { return this.repr; }; - -function PercentageToken() { - this.value = null; - this.repr = ""; -} -PercentageToken.prototype = Object.create(CSSParserToken.prototype); -PercentageToken.prototype.tokenType = "percentage"; -PercentageToken.prototype.toString = function() { return "PERCENTAGE("+this.value+")"; }; -PercentageToken.prototype.toJSON = function() { - var json = this.constructor.prototype.constructor.prototype.toJSON.call(this); - json.value = this.value; - json.repr = this.repr; - return json; -}; -PercentageToken.prototype.toSource = function() { return this.repr + "%"; }; - -function DimensionToken() { - this.value = null; - this.type = "integer"; - this.repr = ""; - this.unit = ""; -} -DimensionToken.prototype = Object.create(CSSParserToken.prototype); -DimensionToken.prototype.tokenType = "dimension"; -DimensionToken.prototype.toString = function() { return "DIM("+this.value+","+this.unit+")"; }; -DimensionToken.prototype.toJSON = function() { - var json = this.constructor.prototype.constructor.prototype.toJSON.call(this); - json.value = this.value; - json.type = this.type; - json.repr = this.repr; - json.unit = this.unit; - return json; -}; -DimensionToken.prototype.toSource = function() { - var source = this.repr; - var unit = escapeIdent(this.unit); - if(unit[0].toLowerCase() == "e" && (unit[1] == "-" || between(unit.charCodeAt(1), 0x30, 0x39))) { - // Unit is ambiguous with scinot - // Remove the leading "e", replace with escape. - unit = "\\65 " + unit.slice(1, unit.length); - } - return source+unit; -}; - -function escapeIdent(string) { - string = ''+string; - var result = ''; - var firstcode = string.charCodeAt(0); - for(var i = 0; i < string.length; i++) { - var code = string.charCodeAt(i); - if(code === 0x0) { - throw new InvalidCharacterError('Invalid character: the input contains U+0000.'); - } - - if( - between(code, 0x1, 0x1f) || code == 0x7f || - (i === 0 && between(code, 0x30, 0x39)) || - (i == 1 && between(code, 0x30, 0x39) && firstcode == 0x2d) - ) { - result += '\\' + code.toString(16) + ' '; - } else if( - code >= 0x80 || - code == 0x2d || - code == 0x5f || - between(code, 0x30, 0x39) || - between(code, 0x41, 0x5a) || - between(code, 0x61, 0x7a) - ) { - result += string[i]; - } else { - result += '\\' + string[i]; - } - } - return result; -} - -function escapeHash(string) { - // Escapes the contents of "unrestricted"-type hash tokens. - // Won't preserve the ID-ness of "id"-type hash tokens; - // use escapeIdent() for that. - string = ''+string; - var result = ''; - for(var i = 0; i < string.length; i++) { - var code = string.charCodeAt(i); - if(code === 0x0) { - throw new InvalidCharacterError('Invalid character: the input contains U+0000.'); - } - - if( - code >= 0x80 || - code == 0x2d || - code == 0x5f || - between(code, 0x30, 0x39) || - between(code, 0x41, 0x5a) || - between(code, 0x61, 0x7a) - ) { - result += string[i]; - } else { - result += '\\' + code.toString(16) + ' '; - } - } - return result; -} - -function escapeString(string) { - string = ''+string; - var result = ''; - for(var i = 0; i < string.length; i++) { - var code = string.charCodeAt(i); - - if(code === 0x0) { - throw new InvalidCharacterError('Invalid character: the input contains U+0000.'); - } - - if(between(code, 0x1, 0x1f) || code == 0x7f) { - result += '\\' + code.toString(16) + ' '; - } else if(code == 0x22 || code == 0x5c) { - result += '\\' + string[i]; - } else { - result += string[i]; - } - } - return result; -} - -// Exportation. -exports.tokenize = tokenize; -exports.IdentToken = IdentToken; -exports.FunctionToken = FunctionToken; -exports.AtKeywordToken = AtKeywordToken; -exports.HashToken = HashToken; -exports.StringToken = StringToken; -exports.BadStringToken = BadStringToken; -exports.URLToken = URLToken; -exports.BadURLToken = BadURLToken; -exports.DelimToken = DelimToken; -exports.NumberToken = NumberToken; -exports.PercentageToken = PercentageToken; -exports.DimensionToken = DimensionToken; -exports.IncludeMatchToken = IncludeMatchToken; -exports.DashMatchToken = DashMatchToken; -exports.PrefixMatchToken = PrefixMatchToken; -exports.SuffixMatchToken = SuffixMatchToken; -exports.SubstringMatchToken = SubstringMatchToken; -exports.ColumnToken = ColumnToken; -exports.WhitespaceToken = WhitespaceToken; -exports.CDOToken = CDOToken; -exports.CDCToken = CDCToken; -exports.ColonToken = ColonToken; -exports.SemicolonToken = SemicolonToken; -exports.CommaToken = CommaToken; -exports.OpenParenToken = OpenParenToken; -exports.CloseParenToken = CloseParenToken; -exports.OpenSquareToken = OpenSquareToken; -exports.CloseSquareToken = CloseSquareToken; -exports.OpenCurlyToken = OpenCurlyToken; -exports.CloseCurlyToken = CloseCurlyToken; -exports.EOFToken = EOFToken; -exports.CSSParserToken = CSSParserToken; -exports.GroupingToken = GroupingToken; - -function TokenStream(tokens) { - // Assume that tokens is a iterator. - this.tokens = tokens; - this.token = undefined; - this.stored = []; -} -TokenStream.prototype.consume = function(num) { - if(num === undefined) num = 1; - while (num-- > 0) { - if (this.stored.length > 0) { - this.token = this.stored.shift(); - } else { - var n = this.tokens.next(); - while (!n.done && n.value instanceof CommentToken) { - n = this.tokens.next(); - } - if (n.done) { - this.token = new EOFToken(); - break; - } - this.token = n.value; - } - } - //console.log(this.i, this.token); - return true; -}; -TokenStream.prototype.next = function() { - if (this.stored.length === 0) { - var n = this.tokens.next(); - while (!n.done && n.value instanceof CommentToken) { - n = this.tokens.next(); - } - if (n.done) - return new EOFToken(); - this.stored.push(n.value); - } - return this.stored[0]; -}; -TokenStream.prototype.reconsume = function() { - this.stored.unshift(this.token); -}; - -function parseerror(s, msg) { - console.log("Parse error at token " + s.i + ": " + s.token + ".\n" + msg); - return true; -} -function donothing(){ return true; } - -function consumeAListOfRules(s, topLevel) { - var rules = []; - var rule; - while(s.consume()) { - if(s.token instanceof WhitespaceToken) { - continue; - } else if(s.token instanceof EOFToken) { - return rules; - } else if(s.token instanceof CDOToken || s.token instanceof CDCToken) { - if(topLevel == "top-level") continue; - s.reconsume(); - if(rule = consumeAQualifiedRule(s)) rules.push(rule); - } else if(s.token instanceof AtKeywordToken) { - s.reconsume(); - if(rule = consumeAnAtRule(s)) rules.push(rule); - } else { - s.reconsume(); - if(rule = consumeAQualifiedRule(s)) rules.push(rule); - } - } -} - -function consumeAnAtRule(s) { - s.consume(); - var rule = new AtRule(s.token.value); - while(s.consume()) { - if(s.token instanceof SemicolonToken || s.token instanceof EOFToken) { - return rule; - } else if(s.token instanceof OpenCurlyToken) { - rule.value = consumeASimpleBlock(s); - return rule; - } else { - s.reconsume(); - rule.prelude.push(consumeAComponentValue(s)); - } - } -} - -function consumeAQualifiedRule(s) { - var rule = new QualifiedRule(); - while(s.consume()) { - if(s.token instanceof EOFToken) { - parseerror(s, "Hit EOF when trying to parse the prelude of a qualified rule."); - return; - } else if(s.token instanceof OpenCurlyToken) { - rule.value = consumeASimpleBlock(s); - return rule; - } else { - s.reconsume(); - rule.prelude.push(consumeAComponentValue(s)); - } - } -} - -function consumeAListOfDeclarations(s) { - var decls = []; - while(s.consume()) { - if(s.token instanceof WhitespaceToken || s.token instanceof SemicolonToken) { - donothing(); - } else if(s.token instanceof EOFToken) { - return decls; - } else if(s.token instanceof AtKeywordToken) { - s.reconsume(); - decls.push(consumeAnAtRule(s)); - } else if(s.token instanceof IdentToken) { - var temp = [s.token]; - while(!(s.next() instanceof SemicolonToken || s.next() instanceof EOFToken)) - temp.push(consumeAComponentValue(s)); - var decl; - if(decl = consumeADeclaration(new TokenStream(temp))) decls.push(decl); - } else { - parseerror(s); - s.reconsume(); - while(!(s.next() instanceof SemicolonToken || s.next() instanceof EOFToken)) - consumeAComponentValue(s); - } - } -} - -function consumeADeclaration(s) { - // Assumes that the next input token will be an ident token. - s.consume(); - var decl = new Declaration(s.token.value); - while(s.next() instanceof WhitespaceToken) s.consume(); - if(!(s.next() instanceof ColonToken)) { - parseerror(s); - return; - } else { - s.consume(); - } - while(!(s.next() instanceof EOFToken)) { - decl.value.push(consumeAComponentValue(s)); - } - var foundImportant = false; - for(var i = decl.value.length - 1; i >= 0; i--) { - if(decl.value[i] instanceof WhitespaceToken) { - continue; - } else if(decl.value[i] instanceof IdentToken && decl.value[i].ASCIIMatch("important")) { - foundImportant = true; - } else if(foundImportant && decl.value[i] instanceof DelimToken && decl.value[i].value == "!") { - decl.value.splice(i, decl.value.length); - decl.important = true; - break; - } else { - break; - } - } - return decl; -} - -function consumeAComponentValue(s) { - s.consume(); - if(s.token instanceof OpenCurlyToken || s.token instanceof OpenSquareToken || s.token instanceof OpenParenToken) - return consumeASimpleBlock(s); - if(s.token instanceof FunctionToken) - return consumeAFunction(s); - return s.token; -} - -function consumeASimpleBlock(s) { - var mirror = s.token.mirror; - var block = new SimpleBlock(s.token.value); - block.startToken = s.token; - while(s.consume()) { - if(s.token instanceof EOFToken || (s.token instanceof GroupingToken && s.token.value == mirror)) - return block; - else { - s.reconsume(); - block.value.push(consumeAComponentValue(s)); - } - } -} - -function consumeAFunction(s) { - var func = new Func(s.token.value); - while(s.consume()) { - if(s.token instanceof EOFToken || s.token instanceof CloseParenToken) - return func; - else { - s.reconsume(); - func.value.push(consumeAComponentValue(s)); - } - } -} - -function normalizeInput(input) { - if(typeof input == "string") - return new TokenStream(tokenize(input)); - if(input instanceof TokenStream) - return input; - if(typeof (input.next) == "function") - return new TokenStream(input); - if(input.length !== undefined) - return new TokenStream(input[Symbol.iterator]()); - else throw SyntaxError(input); -} - -function parseAStylesheet(s) { - s = normalizeInput(s); - var sheet = new Stylesheet(); - sheet.value = consumeAListOfRules(s, "top-level"); - return sheet; -} - -function parseAListOfRules(s) { - s = normalizeInput(s); - return consumeAListOfRules(s); -} - -function parseARule(s) { - s = normalizeInput(s); - while(s.next() instanceof WhitespaceToken) s.consume(); - if(s.next() instanceof EOFToken) throw SyntaxError(); - var rule; - var startToken = s.next(); - if(startToken instanceof AtKeywordToken) { - rule = consumeAnAtRule(s); - } else { - rule = consumeAQualifiedRule(s); - if(!rule) throw SyntaxError(); - } - rule.startToken = startToken; - rule.endToken = s.token; - return rule; -} - -function parseADeclaration(s) { - s = normalizeInput(s); - while(s.next() instanceof WhitespaceToken) s.consume(); - if(!(s.next() instanceof IdentToken)) throw SyntaxError(); - var decl = consumeADeclaration(s); - if(decl) - return decl; - else - throw SyntaxError(); -} - -function parseAListOfDeclarations(s) { - s = normalizeInput(s); - return consumeAListOfDeclarations(s); -} - -function parseAComponentValue(s) { - s = normalizeInput(s); - while(s.next() instanceof WhitespaceToken) s.consume(); - if(s.next() instanceof EOFToken) throw SyntaxError(); - var val = consumeAComponentValue(s); - if(!val) throw SyntaxError(); - while(s.next() instanceof WhitespaceToken) s.consume(); - if(s.next() instanceof EOFToken) - return val; - throw SyntaxError(); -} - -function parseAListOfComponentValues(s) { - s = normalizeInput(s); - var vals = []; - while(true) { - var val = consumeAComponentValue(s); - if(val instanceof EOFToken) - return vals; - else - vals.push(val); - } -} - -function parseACommaSeparatedListOfComponentValues(s) { - s = normalizeInput(s); - var listOfCVLs = []; - while(true) { - var vals = []; - while(true) { - var val = consumeAComponentValue(s); - if(val instanceof EOFToken) { - listOfCVLs.push(vals); - return listOfCVLs; - } else if(val instanceof CommaToken) { - listOfCVLs.push(vals); - break; - } else { - vals.push(val); - } - } - } -} - - -function CSSParserRule() { throw "Abstract Base Class"; } -CSSParserRule.prototype.toString = function(indent) { - return JSON.stringify(this,null,indent); -}; -CSSParserRule.prototype.toJSON = function() { - return {type:this.type, value:this.value}; -}; - -function Stylesheet() { - this.value = []; - return this; -} -Stylesheet.prototype = Object.create(CSSParserRule.prototype); -Stylesheet.prototype.type = "STYLESHEET"; - -function AtRule(name) { - this.name = name; - this.prelude = []; - this.value = null; - return this; -} -AtRule.prototype = Object.create(CSSParserRule.prototype); -AtRule.prototype.type = "AT-RULE"; -AtRule.prototype.toJSON = function() { - var json = this.constructor.prototype.constructor.prototype.toJSON.call(this); - json.name = this.name; - json.prelude = this.prelude; - return json; -}; - -function QualifiedRule() { - this.prelude = []; - this.value = []; - return this; -} -QualifiedRule.prototype = Object.create(CSSParserRule.prototype); -QualifiedRule.prototype.type = "QUALIFIED-RULE"; -QualifiedRule.prototype.toJSON = function() { - var json = this.constructor.prototype.constructor.prototype.toJSON.call(this); - json.prelude = this.prelude; - return json; -}; - -function Declaration(name) { - this.name = name; - this.value = []; - this.important = false; - return this; -} -Declaration.prototype = Object.create(CSSParserRule.prototype); -Declaration.prototype.type = "DECLARATION"; -Declaration.prototype.toJSON = function() { - var json = this.constructor.prototype.constructor.prototype.toJSON.call(this); - json.name = this.name; - json.important = this.important; - return json; -}; - -function SimpleBlock(type) { - this.name = type; - this.value = []; - return this; -} -SimpleBlock.prototype = Object.create(CSSParserRule.prototype); -SimpleBlock.prototype.type = "BLOCK"; -SimpleBlock.prototype.toJSON = function() { - var json = this.constructor.prototype.constructor.prototype.toJSON.call(this); - json.name = this.name; - return json; -}; - -function Func(name) { - this.name = name; - this.value = []; - return this; -} -Func.prototype = Object.create(CSSParserRule.prototype); -Func.prototype.type = "FUNCTION"; -Func.prototype.toJSON = function() { - var json = this.constructor.prototype.constructor.prototype.toJSON.call(this); - json.name = this.name; - return json; -}; - -function CSSLexer(text) { - this.stream = tokenize(text, { - loc: true, - offsets: true, - keepComments: true - }); - this.lineNumber = 0; - this.columnNumber = 0; - return this; -} - -CSSLexer.prototype.performEOFFixup = function(input, preserveBackslash) { - // Just lie for now. - return ""; -}; - -CSSLexer.prototype.nextToken = function() { - if (!this.stream) { - return null; - } - let v = this.stream.next(); - if (v.done || v.value.tokenType === "EOF") { - this.stream = null; - return null; - } - this.lineNumber = v.value.loc.start.line; - this.columnNumber = v.value.loc.start.column; - return v.value; -}; - -// Exportation. -exports.CSSParserRule = CSSParserRule; -exports.Stylesheet = Stylesheet; -exports.AtRule = AtRule; -exports.QualifiedRule = QualifiedRule; -exports.Declaration = Declaration; -exports.SimpleBlock = SimpleBlock; -exports.Func = Func; -exports.parseAStylesheet = parseAStylesheet; -exports.parseAListOfRules = parseAListOfRules; -exports.parseARule = parseARule; -exports.parseADeclaration = parseADeclaration; -exports.parseAListOfDeclarations = parseAListOfDeclarations; -exports.parseAComponentValue = parseAComponentValue; -exports.parseAListOfComponentValues = parseAListOfComponentValues; -exports.parseACommaSeparatedListOfComponentValues = parseACommaSeparatedListOfComponentValues; -exports.CSSLexer = CSSLexer; - -})); diff --git a/packages/devtools-sham-modules/sham/promise.js b/packages/devtools-sham-modules/sham/promise.js deleted file mode 100644 index e634a7a609..0000000000 --- a/packages/devtools-sham-modules/sham/promise.js +++ /dev/null @@ -1,25 +0,0 @@ -/* - * A sham for https://dxr.mozilla.org/mozilla-central/source/toolkit/modules/Promise.jsm - */ - -/** - * Promise.jsm is mostly the Promise web API with a `defer` method. Just drop this in here, - * and use the native web API (although building with webpack/babel, it may replace this - * with it's own version if we want to target environments that do not have `Promise`. - */ - -let p = typeof window != "undefined" ? window.Promise : Promise; -p.defer = function defer() { - var resolve, reject; - var promise = new Promise(function() { - resolve = arguments[0]; - reject = arguments[1]; - }); - return { - resolve: resolve, - reject: reject, - promise: promise - }; -} - -module.exports = p; diff --git a/packages/devtools-sham-modules/sham/services/prefs.js b/packages/devtools-sham-modules/sham/services/prefs.js deleted file mode 100644 index ddb98ef763..0000000000 --- a/packages/devtools-sham-modules/sham/services/prefs.js +++ /dev/null @@ -1,128 +0,0 @@ -let DEFAULTS = require("../../preferences.js"); - -// TODO Can make this localStorage or something in the future? -let storage = JSON.parse(JSON.stringify(DEFAULTS)); - -const PREF_INVALID = exports.PREF_INVALID = 0; -const PREF_STRING = exports.PREF_STRING = 32; -const PREF_INT = exports.PREF_INT = 64; -const PREF_BOOL = exports.PREF_BOOL = 128; - -/** - * Returns a `Pref` object containing the following properties: - * - * `value` - The primitive value of the stored preference. - * `type` - The enum type of the pref. Can be PREF_INVALID, PREF_STRING, PREF_INT, or PREF_BOOL. - */ -function findPref (pref) { - let branchNames = pref.split("."); - let branch = storage; - - for (let branchName of branchNames) { - branch = branch[branchName]; - if (!branch) { - branch = {}; - } - } - - return branch; -} - -function setPrefValue (pref, value) { - let obj = findPref(pref); - obj.value = value; -} - -function getPrefValue (pref) { - return findPref(pref).value; -} - - -const addObserver = exports.addObserver = function (domain, observer, holdWeak) { - console.log("TODO implement addObserver"); -}; - -const removeObserver = exports.removeObserver = function (domain, observer, holdWeak) { - console.log("TODO implement removeObserver"); -}; - -const resetPrefs = exports.resetPrefs = function () { - storage = JSON.parse(JSON.stringify(DEFAULTS)); -}; - -const getPrefType = exports.getPrefType = function (pref) { - return findPref(pref).type; -}; - -const setBoolPref = exports.setBoolPref = function (pref, value) { - if (typeof value !== "boolean") { - throw new Error("Cannot setBoolPref without a boolean."); - } - if (getPrefType(pref) && getPrefType(pref) !== PREF_BOOL) { - throw new Error("Can only call setBoolPref on boolean type prefs."); - } - setPrefValue(pref, value); -}; - -exports.setCharPref = function (pref, value) { - if (typeof value !== "string") { - throw new Error("Cannot setCharPref without a string."); - } - if (getPrefType(pref) && getPrefType(pref) !== PREF_STRING) { - throw new Error("Can only call setCharPref on string type prefs."); - } - setPrefValue(pref, value); -}; - -exports.setIntPref = function (pref, value) { - if (typeof value !== "number" && (parseInt(value) !== value)) { - throw new Error("Cannot setCharPref without an integer."); - } - if (getPrefType(pref) && getPrefType(pref) !== PREF_INT) { - throw new Error("Can only call setIntPref on number type prefs."); - } - setPrefValue(pref, value); -}; - -exports.getBoolPref = function (pref) { - if (getPrefType(pref) !== PREF_BOOL) { - console.log(`No cached boolean pref for ${pref}`); - return undefined; - } - return getPrefValue(pref); -}; - -exports.getCharPref = function (pref) { - if (getPrefType(pref) !== PREF_STRING) { - console.log(`No cached char pref for ${pref}`); - return undefined; - } - return getPrefValue(pref); -}; - -exports.getIntPref = function (pref) { - if (getPrefType(pref) !== PREF_INT) { - console.log(`No cached int pref for ${pref}`); - return undefined; - } - return getPrefValue(pref); -}; - -exports.getComplexValue = function (pref) { - // XXX: Implement me - return { - data: '' - } -}; - -exports.getBranch = function (pref) { - return { - addObserver: () => {}, - removeObserver: () => {}, - } -}; - -exports.prefHasUserValue = function (pref) { - // XXX: Implement me - return false; -}; diff --git a/packages/devtools-sham-modules/shared/DevToolsUtils.js b/packages/devtools-sham-modules/shared/DevToolsUtils.js deleted file mode 100644 index 86ca7a56e8..0000000000 --- a/packages/devtools-sham-modules/shared/DevToolsUtils.js +++ /dev/null @@ -1,749 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* General utilities used throughout devtools. */ -var { Ci, Cu, Cc, components } = require("../sham/chrome"); -const { Services } = require("devtools-modules"); -var promise = require("../sham/promise"); - -const { FileUtils } = require("../sham/fileutils"); - -/** - * Turn the error |aError| into a string, without fail. - */ -exports.safeErrorString = function safeErrorString(aError) { - try { - let errorString = aError.toString(); - if (typeof errorString == "string") { - // Attempt to attach a stack to |errorString|. If it throws an error, or - // isn't a string, don't use it. - try { - if (aError.stack) { - let stack = aError.stack.toString(); - if (typeof stack == "string") { - errorString += "\nStack: " + stack; - } - } - } catch (ee) { } - - // Append additional line and column number information to the output, - // since it might not be part of the stringified error. - if (typeof aError.lineNumber == "number" && typeof aError.columnNumber == "number") { - errorString += "Line: " + aError.lineNumber + ", column: " + aError.columnNumber; - } - - return errorString; - } - } catch (ee) { } - - // We failed to find a good error description, so do the next best thing. - return Object.prototype.toString.call(aError); -}; - -/** - * Report that |aWho| threw an exception, |aException|. - */ -exports.reportException = function reportException(aWho, aException) { - let msg = aWho + " threw an exception: " + exports.safeErrorString(aException); - - console.log(msg); - -// if (Cu && console.error) { -// /* -// * Note that the xpcshell test harness registers an observer for -// * console messages, so when we're running tests, this will cause -// * the test to quit. -// */ -// console.error(msg); -// } -}; - -/** - * Given a handler function that may throw, return an infallible handler - * function that calls the fallible handler, and logs any exceptions it - * throws. - * - * @param aHandler function - * A handler function, which may throw. - * @param aName string - * A name for aHandler, for use in error messages. If omitted, we use - * aHandler.name. - * - * (SpiderMonkey does generate good names for anonymous functions, but we - * don't have a way to get at them from JavaScript at the moment.) - */ -exports.makeInfallible = function makeInfallible(aHandler, aName) { - if (!aName) - aName = aHandler.name; - - return function(/* arguments */) { - // try { - return aHandler.apply(this, arguments); - // } catch (ex) { - // let who = "Handler function"; - // if (aName) { - // who += " " + aName; - // } - // return exports.reportException(who, ex); - // } - }; -}; - -/** - * Waits for the next tick in the event loop to execute a callback. - */ -exports.executeSoon = function executeSoon(aFn) { - setTimeout(aFn, 0); -}; - -/** - * Waits for the next tick in the event loop. - * - * @return Promise - * A promise that is resolved after the next tick in the event loop. - */ -exports.waitForTick = function waitForTick() { - let deferred = promise.defer(); - exports.executeSoon(deferred.resolve); - return deferred.promise; -}; - -/** - * Waits for the specified amount of time to pass. - * - * @param number aDelay - * The amount of time to wait, in milliseconds. - * @return Promise - * A promise that is resolved after the specified amount of time passes. - */ -exports.waitForTime = function waitForTime(aDelay) { - let deferred = promise.defer(); - setTimeout(deferred.resolve, aDelay); - return deferred.promise; -}; - -/** - * Like Array.prototype.forEach, but doesn't cause jankiness when iterating over - * very large arrays by yielding to the browser and continuing execution on the - * next tick. - * - * @param Array aArray - * The array being iterated over. - * @param Function aFn - * The function called on each item in the array. If a promise is - * returned by this function, iterating over the array will be paused - * until the respective promise is resolved. - * @returns Promise - * A promise that is resolved once the whole array has been iterated - * over, and all promises returned by the aFn callback are resolved. - */ -exports.yieldingEach = function yieldingEach(aArray, aFn) { - const deferred = promise.defer(); - - let i = 0; - let len = aArray.length; - let outstanding = [deferred.promise]; - - (function loop() { - const start = Date.now(); - - while (i < len) { - // Don't block the main thread for longer than 16 ms at a time. To - // maintain 60fps, you have to render every frame in at least 16ms; we - // aren't including time spent in non-JS here, but this is Good - // Enough(tm). - if (Date.now() - start > 16) { - exports.executeSoon(loop); - return; - } - - try { - outstanding.push(aFn(aArray[i], i++)); - } catch (e) { - deferred.reject(e); - return; - } - } - - deferred.resolve(); - }()); - - return promise.all(outstanding); -}; - -/** - * Like XPCOMUtils.defineLazyGetter, but with a |this| sensitive getter that - * allows the lazy getter to be defined on a prototype and work correctly with - * instances. - * - * @param Object aObject - * The prototype object to define the lazy getter on. - * @param String aKey - * The key to define the lazy getter on. - * @param Function aCallback - * The callback that will be called to determine the value. Will be - * called with the |this| value of the current instance. - */ -exports.defineLazyPrototypeGetter = -function defineLazyPrototypeGetter(aObject, aKey, aCallback) { - Object.defineProperty(aObject, aKey, { - configurable: true, - get: function() { - const value = aCallback.call(this); - - Object.defineProperty(this, aKey, { - configurable: true, - writable: true, - value: value - }); - - return value; - } - }); -}; - -/** - * Safely get the property value from a Debugger.Object for a given key. Walks - * the prototype chain until the property is found. - * - * @param Debugger.Object aObject - * The Debugger.Object to get the value from. - * @param String aKey - * The key to look for. - * @return Any - */ -exports.getProperty = function getProperty(aObj, aKey) { - let root = aObj; - try { - do { - const desc = aObj.getOwnPropertyDescriptor(aKey); - if (desc) { - if ("value" in desc) { - return desc.value; - } - // Call the getter if it's safe. - return exports.hasSafeGetter(desc) ? desc.get.call(root).return : undefined; - } - aObj = aObj.proto; - } while (aObj); - } catch (e) { - // If anything goes wrong report the error and return undefined. - exports.reportException("getProperty", e); - } - return undefined; -}; - -/** - * Determines if a descriptor has a getter which doesn't call into JavaScript. - * - * @param Object aDesc - * The descriptor to check for a safe getter. - * @return Boolean - * Whether a safe getter was found. - */ -exports.hasSafeGetter = function hasSafeGetter(aDesc) { - // Scripted functions that are CCWs will not appear scripted until after - // unwrapping. - try { - let fn = aDesc.get.unwrap(); - return fn && fn.callable && fn.class == "Function" && fn.script === undefined; - } catch (e) { - // Avoid exception 'Object in compartment marked as invisible to Debugger' - return false; - } -}; - -/** - * Check if it is safe to read properties and execute methods from the given JS - * object. Safety is defined as being protected from unintended code execution - * from content scripts (or cross-compartment code). - * - * See bugs 945920 and 946752 for discussion. - * - * @type Object aObj - * The object to check. - * @return Boolean - * True if it is safe to read properties from aObj, or false otherwise. - */ -exports.isSafeJSObject = function isSafeJSObject(aObj) { - // If we are running on a worker thread, Cu is not available. In this case, - // we always return false, just to be on the safe side. - if (isWorker) { - return false; - } - - if (Cu.getGlobalForObject(aObj) == - Cu.getGlobalForObject(exports.isSafeJSObject)) { - return true; // aObj is not a cross-compartment wrapper. - } - - let principal = Cu.getObjectPrincipal(aObj); - if (Services.scriptSecurityManager.isSystemPrincipal(principal)) { - return true; // allow chrome objects - } - - return Cu.isXrayWrapper(aObj); -}; - -exports.dumpn = function dumpn(str) { - if (exports.dumpn.wantLogging) { - console.log("DBG-SERVER: " + str + "\n"); - } -}; - -// We want wantLogging to be writable. The exports object is frozen by the -// loader, so define it on dumpn instead. -exports.dumpn.wantLogging = false; - -/** - * A verbose logger for low-level tracing. - */ -exports.dumpv = function(msg) { - if (exports.dumpv.wantVerbose) { - exports.dumpn(msg); - } -}; - -// We want wantLogging to be writable. The exports object is frozen by the -// loader, so define it on dumpn instead. -exports.dumpv.wantVerbose = false; - -/** - * Utility function for updating an object with the properties of - * other objects. - * - * @param aTarget Object - * The object being updated. - * @param aNewAttrs Object - * The rest params are objects to update aTarget with. You - * can pass as many as you like. - */ -exports.update = function update(aTarget, ...aArgs) { - for (let attrs of aArgs) { - for (let key in attrs) { - let desc = Object.getOwnPropertyDescriptor(attrs, key); - - if (desc) { - Object.defineProperty(aTarget, key, desc); - } - } - } - - return aTarget; -}; - -/** - * Utility function for getting the values from an object as an array - * - * @param aObject Object - * The object to iterate over - */ -exports.values = function values(aObject) { - return Object.keys(aObject).map(k => aObject[k]); -}; - -/** - * Defines a getter on a specified object that will be created upon first use. - * - * @param aObject - * The object to define the lazy getter on. - * @param aName - * The name of the getter to define on aObject. - * @param aLambda - * A function that returns what the getter should return. This will - * only ever be called once. - */ -exports.defineLazyGetter = function defineLazyGetter(aObject, aName, aLambda) { - Object.defineProperty(aObject, aName, { - get: function() { - delete aObject[aName]; - return aObject[aName] = aLambda.apply(aObject); - }, - configurable: true, - enumerable: true - }); -}; - -// DEPRECATED: use DevToolsUtils.assert(condition, message) instead! -let haveLoggedDeprecationMessage = false; -exports.dbg_assert = function dbg_assert(cond, e) { - if (!haveLoggedDeprecationMessage) { - haveLoggedDeprecationMessage = true; - const deprecationMessage = "DevToolsUtils.dbg_assert is deprecated! Use DevToolsUtils.assert instead!" - + Error().stack; - console.log(deprecationMessage); - if (typeof console === "object" && console && console.warn) { - console.warn(deprecationMessage); - } - } - - if (!cond) { - return e; - } -}; - -const { AppConstants } = require("../sham/appconstants"); - -/** - * No operation. The empty function. - */ -exports.noop = function() { }; - -function reallyAssert(condition, message) { - if (!condition) { - const err = new Error("Assertion failure: " + message); - exports.reportException("DevToolsUtils.assert", err); - throw err; - } -} - -/** - * DevToolsUtils.assert(condition, message) - * - * @param Boolean condition - * @param String message - * - * Assertions are enabled when any of the following are true: - * - This is a DEBUG_JS_MODULES build - * - This is a DEBUG build - * - DevToolsUtils.testing is set to true - * - * If assertions are enabled, then `condition` is checked and if false-y, the - * assertion failure is logged and then an error is thrown. - * - * If assertions are not enabled, then this function is a no-op. - * - * This is an improvement over `dbg_assert`, which doesn't actually cause any - * fatal behavior, and is therefore much easier to accidentally ignore. - */ -Object.defineProperty(exports, "assert", { - get: () => (AppConstants.DEBUG || AppConstants.DEBUG_JS_MODULES || this.testing) - ? reallyAssert - : exports.noop, -}); - -/** - * Defines a getter on a specified object for a module. The module will not - * be imported until first use. - * - * @param aObject - * The object to define the lazy getter on. - * @param aName - * The name of the getter to define on aObject for the module. - * @param aResource - * The URL used to obtain the module. - * @param aSymbol - * The name of the symbol exported by the module. - * This parameter is optional and defaults to aName. - */ -exports.defineLazyModuleGetter = function defineLazyModuleGetter(aObject, aName, - aResource, - aSymbol) -{ - this.defineLazyGetter(aObject, aName, function XPCU_moduleLambda() { - var temp = {}; - Cu.import(aResource, temp); - return temp[aSymbol || aName]; - }); -}; - -const { NetUtil } = require("../sham/netutil"); - -const { TextDecoder, OS } = require("../sham/osfile"); - -const NetworkHelper = require("./webconsole/network-helper"); - -/** - * Performs a request to load the desired URL and returns a promise. - * - * @param aURL String - * The URL we will request. - * @param aOptions Object - * An object with the following optional properties: - * - loadFromCache: if false, will bypass the cache and - * always load fresh from the network (default: true) - * - policy: the nsIContentPolicy type to apply when fetching the URL - * - window: the window to get the loadGroup from - * - charset: the charset to use if the channel doesn't provide one - * @returns Promise that resolves with an object with the following members on - * success: - * - content: the document at that URL, as a string, - * - contentType: the content type of the document - * - * If an error occurs, the promise is rejected with that error. - * - * XXX: It may be better to use nsITraceableChannel to get to the sources - * without relying on caching when we can (not for eval, etc.): - * http://www.softwareishard.com/blog/firebug/nsitraceablechannel-intercept-http-traffic/ - */ -function mainThreadFetch(aURL, aOptions = { loadFromCache: true, - policy: Ci.nsIContentPolicy.TYPE_OTHER, - window: null, - charset: null }) { - // Create a channel. - let url = aURL.split(" -> ").pop(); - let channel; - try { - channel = newChannelForURL(url, aOptions); - } catch (ex) { - return promise.reject(ex); - } - - // Set the channel options. - channel.loadFlags = aOptions.loadFromCache - ? channel.LOAD_FROM_CACHE - : channel.LOAD_BYPASS_CACHE; - - if (aOptions.window) { - // Respect private browsing. - channel.loadGroup = aOptions.window.QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIWebNavigation) - .QueryInterface(Ci.nsIDocumentLoader) - .loadGroup; - } - - let deferred = promise.defer(); - let onResponse = (stream, status, request) => { - if (!components.isSuccessCode(status)) { - deferred.reject(new Error(`Failed to fetch ${url}. Code ${status}.`)); - return; - } - - try { - // We cannot use NetUtil to do the charset conversion as if charset - // information is not available and our default guess is wrong the method - // might fail and we lose the stream data. This means we can't fall back - // to using the locale default encoding (bug 1181345). - - // Read and decode the data according to the locale default encoding. - let available = stream.available(); - let source = NetUtil.readInputStreamToString(stream, available); - stream.close(); - - // If the channel or the caller has correct charset information, the - // content will be decoded correctly. If we have to fall back to UTF-8 and - // the guess is wrong, the conversion fails and convertToUnicode returns - // the input unmodified. Essentially we try to decode the data as UTF-8 - // and if that fails, we use the locale specific default encoding. This is - // the best we can do if the source does not provide charset info. - let charset = channel.contentCharset || aOptions.charset || "UTF-8"; - let unicodeSource = NetworkHelper.convertToUnicode(source, charset); - - deferred.resolve({ - content: unicodeSource, - contentType: request.contentType - }); - } catch (ex) { - let uri = request.originalURI; - if (ex.name === "NS_BASE_STREAM_CLOSED" && uri instanceof Ci.nsIFileURL) { - // Empty files cause NS_BASE_STREAM_CLOSED exception. Use OS.File to - // differentiate between empty files and other errors (bug 1170864). - // This can be removed when bug 982654 is fixed. - - uri.QueryInterface(Ci.nsIFileURL); - let result = OS.File.read(uri.file.path).then(bytes => { - // Convert the bytearray to a String. - let decoder = new TextDecoder(); - let content = decoder.decode(bytes); - - // We can't detect the contentType without opening a channel - // and that failed already. This is the best we can do here. - return { - content, - contentType: "text/plain" - }; - }); - - deferred.resolve(result); - } else { - deferred.reject(ex); - } - } - }; - - // Open the channel - try { - NetUtil.asyncFetch(channel, onResponse); - } catch (ex) { - return promise.reject(ex); - } - - return deferred.promise; -} - -/** - * Opens a channel for given URL. Tries a bit harder than NetUtil.newChannel. - * - * @param {String} url - The URL to open a channel for. - * @param {Object} options - The options object passed to @method fetch. - * @return {nsIChannel} - The newly created channel. Throws on failure. - */ -function newChannelForURL(url, { policy }) { - let channelOptions = { - contentPolicyType: policy, - loadUsingSystemPrincipal: true, - uri: url - }; - - try { - return NetUtil.newChannel(channelOptions); - } catch (e) { - // In the xpcshell tests, the script url is the absolute path of the test - // file, which will make a malformed URI error be thrown. Add the file - // scheme to see if it helps. - channelOptions.uri = "file://" + url; - - return NetUtil.newChannel(channelOptions); - } -} - -// Fetch is defined differently depending on whether we are on the main thread -// or a worker thread. -if (typeof WorkerGlobalScope === "undefined") { // i.e. not in a worker - exports.fetch = mainThreadFetch; -} else { - // Services is not available in worker threads, nor is there any other way - // to fetch a URL. We need to enlist the help from the main thread here, by - // issuing an rpc request, to fetch the URL on our behalf. - exports.fetch = function(url, options) { - return rpc("fetch", url, options); - }; -} - -/** - * Returns a promise that is resolved or rejected when all promises have settled - * (resolved or rejected). - * - * This differs from Promise.all, which will reject immediately after the first - * rejection, instead of waiting for the remaining promises to settle. - * - * @param values - * Iterable of promises that may be pending, resolved, or rejected. When - * when all promises have settled (resolved or rejected), the returned - * promise will be resolved or rejected as well. - * - * @return A new promise that is fulfilled when all values have settled - * (resolved or rejected). Its resolution value will be an array of all - * resolved values in the given order, or undefined if values is an - * empty array. The reject reason will be forwarded from the first - * promise in the list of given promises to be rejected. - */ -exports.settleAll = values => { - if (values === null || typeof (values[Symbol.iterator]) != "function") { - throw new Error("settleAll() expects an iterable."); - } - - let deferred = promise.defer(); - - values = Array.isArray(values) ? values : [...values]; - let countdown = values.length; - let resolutionValues = new Array(countdown); - let rejectionValue; - let rejectionOccurred = false; - - if (!countdown) { - deferred.resolve(resolutionValues); - return deferred.promise; - } - - function checkForCompletion() { - if (--countdown > 0) { - return; - } - if (!rejectionOccurred) { - deferred.resolve(resolutionValues); - } else { - deferred.reject(rejectionValue); - } - } - - for (let i = 0; i < values.length; i++) { - let index = i; - let value = values[i]; - let resolver = result => { - resolutionValues[index] = result; - checkForCompletion(); - }; - let rejecter = error => { - if (!rejectionOccurred) { - rejectionValue = error; - rejectionOccurred = true; - } - checkForCompletion(); - }; - - if (value && typeof (value.then) == "function") { - value.then(resolver, rejecter); - } else { - // Given value is not a promise, forward it as a resolution value. - resolver(value); - } - } - - return deferred.promise; -}; - -/** - * When the testing flag is set, various behaviors may be altered from - * production mode, typically to enable easier testing or enhanced debugging. - */ -var testing = false; -Object.defineProperty(exports, "testing", { - get: function() { - return testing; - }, - set: function(state) { - testing = state; - } -}); - -/** - * Open the file at the given path for reading. - * - * @param {String} filePath - * - * @returns Promise - */ -exports.openFileStream = function(filePath) { - return new Promise((resolve, reject) => { - const uri = NetUtil.newURI(new FileUtils.File(filePath)); - NetUtil.asyncFetch( - { uri, loadUsingSystemPrincipal: true }, - (stream, result) => { - if (!components.isSuccessCode(result)) { - reject(new Error(`Could not open "${filePath}": result = ${result}`)); - return; - } - - resolve(stream); - } - ); - }); -}; - -exports.isGenerator = function(fn) { - if (typeof fn !== "function") { - return false; - } - let proto = Object.getPrototypeOf(fn); - if (!proto) { - return false; - } - let ctor = proto.constructor; - if (!ctor) { - return false; - } - return ctor.name == "GeneratorFunction"; -}; - -exports.isPromise = function(p) { - return p && typeof p.then === "function"; -}; - -/** - * Return true if `thing` is a SavedFrame, false otherwise. - */ -exports.isSavedFrame = function(thing) { - return Object.prototype.toString.call(thing) === "[object SavedFrame]"; -}; diff --git a/packages/devtools-sham-modules/shared/client/main.js b/packages/devtools-sham-modules/shared/client/main.js deleted file mode 100644 index 238d213c29..0000000000 --- a/packages/devtools-sham-modules/shared/client/main.js +++ /dev/null @@ -1,3160 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -const { Ci, Cu, components } = require("../../sham/chrome"); -const { Services } = require("devtools-modules"); -const DevToolsUtils = require("../DevToolsUtils"); - -// WARNING I swapped the sync one for the async one here -// const promise = require("resource://devtools/shared/deprecated-sync-thenables.js", {}).Promise; -const promise = require("../../sham/promise"); - -const events = require("../../sdk/event/core"); -const { WebConsoleClient } = require("../webconsole/client"); -/* const { DebuggerSocket } = require("../shared/security/socket");*/ -/* const Authentication = require("../shared/security/auth");*/ - -const noop = () => {}; - -/** - * TODO: Get rid of this API in favor of EventTarget (bug 1042642) - * - * Add simple event notification to a prototype object. Any object that has - * some use for event notifications or the observer pattern in general can be - * augmented with the necessary facilities by passing its prototype to this - * function. - * - * @param aProto object - * The prototype object that will be modified. - */ -function eventSource(aProto) { - /** - * Add a listener to the event source for a given event. - * - * @param aName string - * The event to listen for. - * @param aListener function - * Called when the event is fired. If the same listener - * is added more than once, it will be called once per - * addListener call. - */ - aProto.addListener = function(aName, aListener) { - if (typeof aListener != "function") { - throw TypeError("Listeners must be functions."); - } - - if (!this._listeners) { - this._listeners = {}; - } - - this._getListeners(aName).push(aListener); - }; - - /** - * Add a listener to the event source for a given event. The - * listener will be removed after it is called for the first time. - * - * @param aName string - * The event to listen for. - * @param aListener function - * Called when the event is fired. - */ - aProto.addOneTimeListener = function(aName, aListener) { - let l = (...args) => { - this.removeListener(aName, l); - aListener.apply(null, args); - }; - this.addListener(aName, l); - }; - - /** - * Remove a listener from the event source previously added with - * addListener(). - * - * @param aName string - * The event name used during addListener to add the listener. - * @param aListener function - * The callback to remove. If addListener was called multiple - * times, all instances will be removed. - */ - aProto.removeListener = function(aName, aListener) { - if (!this._listeners || (aListener && !this._listeners[aName])) { - return; - } - - if (!aListener) { - this._listeners[aName] = []; - } - else { - this._listeners[aName] = - this._listeners[aName].filter(function(l) { return l != aListener; }); - } - }; - - /** - * Returns the listeners for the specified event name. If none are defined it - * initializes an empty list and returns that. - * - * @param aName string - * The event name. - */ - aProto._getListeners = function(aName) { - if (aName in this._listeners) { - return this._listeners[aName]; - } - this._listeners[aName] = []; - return this._listeners[aName]; - }; - - /** - * Notify listeners of an event. - * - * @param aName string - * The event to fire. - * @param arguments - * All arguments will be passed along to the listeners, - * including the name argument. - */ - aProto.emit = function() { - if (!this._listeners) { - return; - } - - let name = arguments[0]; - let listeners = this._getListeners(name).slice(0); - - for (let listener of listeners) { - try { - listener.apply(null, arguments); - } catch (e) { - // Prevent a bad listener from interfering with the others. - DevToolsUtils.reportException("notify event '" + name + "'", e); - } - } - }; -} - -/** - * Set of protocol messages that affect thread state, and the - * state the actor is in after each message. - */ -const ThreadStateTypes = { - "paused": "paused", - "resumed": "attached", - "detached": "detached" -}; - -/** - * Set of protocol messages that are sent by the server without a prior request - * by the client. - */ -const UnsolicitedNotifications = { - "consoleAPICall": "consoleAPICall", - "eventNotification": "eventNotification", - "fileActivity": "fileActivity", - "lastPrivateContextExited": "lastPrivateContextExited", - "logMessage": "logMessage", - "networkEvent": "networkEvent", - "networkEventUpdate": "networkEventUpdate", - "newGlobal": "newGlobal", - "newScript": "newScript", - "tabDetached": "tabDetached", - "tabListChanged": "tabListChanged", - "reflowActivity": "reflowActivity", - "addonListChanged": "addonListChanged", - "workerListChanged": "workerListChanged", - "serviceWorkerRegistrationListChanged": "serviceWorkerRegistrationList", - "tabNavigated": "tabNavigated", - "frameUpdate": "frameUpdate", - "pageError": "pageError", - "documentLoad": "documentLoad", - "enteredFrame": "enteredFrame", - "exitedFrame": "exitedFrame", - "appOpen": "appOpen", - "appClose": "appClose", - "appInstall": "appInstall", - "appUninstall": "appUninstall", - "evaluationResult": "evaluationResult", - "newSource": "newSource", - "updatedSource": "updatedSource", -}; - -/** - * Set of pause types that are sent by the server and not as an immediate - * response to a client request. - */ -const UnsolicitedPauses = { - "resumeLimit": "resumeLimit", - "debuggerStatement": "debuggerStatement", - "breakpoint": "breakpoint", - "DOMEvent": "DOMEvent", - "watchpoint": "watchpoint", - "exception": "exception" -}; - -/** - * Creates a client for the remote debugging protocol server. This client - * provides the means to communicate with the server and exchange the messages - * required by the protocol in a traditional JavaScript API. - */ -const DebuggerClient = exports.DebuggerClient = function(aTransport) -{ - this._transport = aTransport; - this._transport.hooks = this; - - // Map actor ID to client instance for each actor type. - this._clients = new Map(); - - this._pendingRequests = new Map(); - this._activeRequests = new Map(); - this._eventsEnabled = true; - - this.traits = {}; - - this.request = this.request.bind(this); - this.localTransport = this._transport.onOutputStreamReady === undefined; - - /* - * As the first thing on the connection, expect a greeting packet from - * the connection's root actor. - */ - this.mainRoot = null; - this.expectReply("root", (aPacket) => { - this.mainRoot = new RootClient(this, aPacket); - this.emit("connected", aPacket.applicationType, aPacket.traits); - }); -}; - -/** - * A declarative helper for defining methods that send requests to the server. - * - * @param aPacketSkeleton - * The form of the packet to send. Can specify fields to be filled from - * the parameters by using the |args| function. - * @param telemetry - * The unique suffix of the telemetry histogram id. - * @param before - * The function to call before sending the packet. Is passed the packet, - * and the return value is used as the new packet. The |this| context is - * the instance of the client object we are defining a method for. - * @param after - * The function to call after the response is received. It is passed the - * response, and the return value is considered the new response that - * will be passed to the callback. The |this| context is the instance of - * the client object we are defining a method for. - * @return Request - * The `Request` object that is a Promise object and resolves once - * we receive the response. (See request method for more details) - */ -DebuggerClient.requester = function(aPacketSkeleton, config = {}) { - let { telemetry, before, after } = config; - return DevToolsUtils.makeInfallible(function(...args) { - let histogram, startTime; - if (telemetry) { - let transportType = this._transport.onOutputStreamReady === undefined - ? "LOCAL_" - : "REMOTE_"; - let histogramId = "DEVTOOLS_DEBUGGER_RDP_" - + transportType + telemetry + "_MS"; - histogram = Services.telemetry.getHistogramById(histogramId); - startTime = +new Date(); - } - let outgoingPacket = { - to: aPacketSkeleton.to || this.actor - }; - - let maxPosition = -1; - for (let k of Object.keys(aPacketSkeleton)) { - if (aPacketSkeleton[k] instanceof DebuggerClient.Argument) { - let { position } = aPacketSkeleton[k]; - outgoingPacket[k] = aPacketSkeleton[k].getArgument(args); - maxPosition = Math.max(position, maxPosition); - } else { - outgoingPacket[k] = aPacketSkeleton[k]; - } - } - - if (before) { - outgoingPacket = before.call(this, outgoingPacket); - } - - return this.request(outgoingPacket, DevToolsUtils.makeInfallible((aResponse) => { - if (after) { - let { from } = aResponse; - aResponse = after.call(this, aResponse); - if (!aResponse.from) { - aResponse.from = from; - } - } - - // The callback is always the last parameter. - let thisCallback = args[maxPosition + 1]; - if (thisCallback) { - thisCallback(aResponse); - } - - if (histogram) { - histogram.add(+new Date() - startTime); - } - }, "DebuggerClient.requester request callback")); - }, "DebuggerClient.requester"); -}; - -function args(aPos) { - return new DebuggerClient.Argument(aPos); -} - -DebuggerClient.Argument = function(aPosition) { - this.position = aPosition; -}; - -DebuggerClient.Argument.prototype.getArgument = function(aParams) { - if (!(this.position in aParams)) { - throw new Error("Bad index into params: " + this.position); - } - return aParams[this.position]; -}; - -// Expose these to save callers the trouble of importing DebuggerSocket -DebuggerClient.socketConnect = function(options) { - // Defined here instead of just copying the function to allow lazy-load - return DebuggerSocket.connect(options); -}; -DevToolsUtils.defineLazyGetter(DebuggerClient, "Authenticators", () => { - return Authentication.Authenticators; -}); -DevToolsUtils.defineLazyGetter(DebuggerClient, "AuthenticationResult", () => { - return Authentication.AuthenticationResult; -}); - -DebuggerClient.prototype = { - /** - * Connect to the server and start exchanging protocol messages. - * - * @param aOnConnected function - * If specified, will be called when the greeting packet is - * received from the debugging server. - * - * @return Promise - * Resolves once connected with an array whose first element - * is the application type, by default "browser", and the second - * element is the traits object (help figure out the features - * and behaviors of the server we connect to. See RootActor). - */ - connect: function(aOnConnected) { - return Promise.race([ - new Promise((resolve, reject) => { - this.emit("connect"); - - // Also emit the event on the |DebuggerClient| object (not on the instance), - // so it's possible to track all instances. - events.emit(DebuggerClient, "connect", this); - - this.addOneTimeListener("connected", (aName, aApplicationType, aTraits) => { - this.traits = aTraits; - if (aOnConnected) { - aOnConnected(aApplicationType, aTraits); - } - resolve([aApplicationType, aTraits]); - }); - - this._transport.ready(); - }), - new Promise((resolve, reject) => { - setTimeout(() => reject(new Error("Connect timeout error")), 6000); - }) - ]); - }, - - /** - * Shut down communication with the debugging server. - * - * @param aOnClosed function - * If specified, will be called when the debugging connection - * has been closed. - */ - close: function(aOnClosed) { - // Disable detach event notifications, because event handlers will be in a - // cleared scope by the time they run. - this._eventsEnabled = false; - - let cleanup = () => { - this._transport.close(); - this._transport = null; - }; - - // If the connection is already closed, - // there is no need to detach client - // as we won't be able to send any message. - if (this._closed) { - cleanup(); - if (aOnClosed) { - aOnClosed(); - } - return; - } - - if (aOnClosed) { - this.addOneTimeListener("closed", function(aEvent) { - aOnClosed(); - }); - } - - // Call each client's `detach` method by calling - // lastly registered ones first to give a chance - // to detach child clients first. - let clients = [...this._clients.values()]; - this._clients.clear(); - const detachClients = () => { - let client = clients.pop(); - if (!client) { - // All clients detached. - cleanup(); - return; - } - if (client.detach) { - client.detach(detachClients); - return; - } - detachClients(); - }; - detachClients(); - }, - - /* - * This function exists only to preserve DebuggerClient's interface; - * new code should say 'client.mainRoot.listTabs()'. - */ - listTabs: function(aOnResponse) { return this.mainRoot.listTabs(aOnResponse); }, - - /* - * This function exists only to preserve DebuggerClient's interface; - * new code should say 'client.mainRoot.listAddons()'. - */ - listAddons: function(aOnResponse) { return this.mainRoot.listAddons(aOnResponse); }, - - getTab: function(aFilter) { return this.mainRoot.getTab(aFilter); }, - - /** - * Attach to a tab actor. - * - * @param string aTabActor - * The actor ID for the tab to attach. - * @param function aOnResponse - * Called with the response packet and a TabClient - * (which will be undefined on error). - */ - attachTab: function(aTabActor, aOnResponse = noop) { - if (this._clients.has(aTabActor)) { - let cachedTab = this._clients.get(aTabActor); - let cachedResponse = { - cacheDisabled: cachedTab.cacheDisabled, - javascriptEnabled: cachedTab.javascriptEnabled, - traits: cachedTab.traits, - }; - DevToolsUtils.executeSoon(() => aOnResponse(cachedResponse, cachedTab)); - return promise.resolve([cachedResponse, cachedTab]); - } - - let packet = { - to: aTabActor, - type: "attach" - }; - return this.request(packet).then(aResponse => { - let tabClient; - if (!aResponse.error) { - tabClient = new TabClient(this, aResponse); - this.registerClient(tabClient); - } - aOnResponse(aResponse, tabClient); - return [aResponse, tabClient]; - }); - }, - - attachWorker: function DC_attachWorker(aWorkerActor, aOnResponse = noop) { - let workerClient = this._clients.get(aWorkerActor); - if (workerClient !== undefined) { - let response = { - from: workerClient.actor, - type: "attached", - url: workerClient.url - }; - DevToolsUtils.executeSoon(() => aOnResponse(response, workerClient)); - return promise.resolve([response, workerClient]); - } - - return this.request({ to: aWorkerActor, type: "attach" }).then(aResponse => { - if (aResponse.error) { - aOnResponse(aResponse, null); - return [aResponse, null]; - } - - let workerClient = new WorkerClient(this, aResponse); - this.registerClient(workerClient); - aOnResponse(aResponse, workerClient); - return [aResponse, workerClient]; - }); - }, - - /** - * Attach to an addon actor. - * - * @param string aAddonActor - * The actor ID for the addon to attach. - * @param function aOnResponse - * Called with the response packet and a AddonClient - * (which will be undefined on error). - */ - attachAddon: function DC_attachAddon(aAddonActor, aOnResponse = noop) { - let packet = { - to: aAddonActor, - type: "attach" - }; - return this.request(packet).then(aResponse => { - let addonClient; - if (!aResponse.error) { - addonClient = new AddonClient(this, aAddonActor); - this.registerClient(addonClient); - this.activeAddon = addonClient; - } - aOnResponse(aResponse, addonClient); - return [aResponse, addonClient]; - }); - }, - - /** - * Attach to a Web Console actor. - * - * @param string aConsoleActor - * The ID for the console actor to attach to. - * @param array aListeners - * The console listeners you want to start. - * @param function aOnResponse - * Called with the response packet and a WebConsoleClient - * instance (which will be undefined on error). - */ - attachConsole: - function(aConsoleActor, aListeners, aOnResponse = noop) { - let packet = { - to: aConsoleActor, - type: "startListeners", - listeners: aListeners, - }; - - return this.request(packet).then(aResponse => { - let consoleClient; - if (!aResponse.error) { - if (this._clients.has(aConsoleActor)) { - consoleClient = this._clients.get(aConsoleActor); - } else { - consoleClient = new WebConsoleClient(this, aResponse); - this.registerClient(consoleClient); - } - } - aOnResponse(aResponse, consoleClient); - return [aResponse, consoleClient]; - }); - }, - - /** - * Attach to a global-scoped thread actor for chrome debugging. - * - * @param string aThreadActor - * The actor ID for the thread to attach. - * @param function aOnResponse - * Called with the response packet and a ThreadClient - * (which will be undefined on error). - * @param object aOptions - * Configuration options. - * - useSourceMaps: whether to use source maps or not. - */ - attachThread: function(aThreadActor, aOnResponse = noop, aOptions = {}) { - if (this._clients.has(aThreadActor)) { - let client = this._clients.get(aThreadActor); - DevToolsUtils.executeSoon(() => aOnResponse({}, client)); - return promise.resolve([{}, client]); - } - - let packet = { - to: aThreadActor, - type: "attach", - options: aOptions - }; - return this.request(packet).then(aResponse => { - if (!aResponse.error) { - var threadClient = new ThreadClient(this, aThreadActor); - this.registerClient(threadClient); - } - aOnResponse(aResponse, threadClient); - return [aResponse, threadClient]; - }); - }, - - /** - * Attach to a trace actor. - * - * @param string aTraceActor - * The actor ID for the tracer to attach. - * @param function aOnResponse - * Called with the response packet and a TraceClient - * (which will be undefined on error). - */ - attachTracer: function(aTraceActor, aOnResponse = noop) { - if (this._clients.has(aTraceActor)) { - let client = this._clients.get(aTraceActor); - DevToolsUtils.executeSoon(() => aOnResponse({}, client)); - return promise.resolve([{}, client]); - } - - let packet = { - to: aTraceActor, - type: "attach" - }; - return this.request(packet).then(aResponse => { - if (!aResponse.error) { - var traceClient = new TraceClient(this, aTraceActor); - this.registerClient(traceClient); - } - aOnResponse(aResponse, traceClient); - return [aResponse, traceClient]; - }); - }, - - /** - * Fetch the ChromeActor for the main process or ChildProcessActor for a - * a given child process ID. - * - * @param number aId - * The ID for the process to attach (returned by `listProcesses`). - * Connected to the main process if omitted, or is 0. - */ - getProcess: function(aId) { - let packet = { - to: "root", - type: "getProcess" - }; - if (typeof (aId) == "number") { - packet.id = aId; - } - return this.request(packet); - }, - - /** - * Release an object actor. - * - * @param string aActor - * The actor ID to send the request to. - * @param aOnResponse function - * If specified, will be called with the response packet when - * debugging server responds. - */ - release: DebuggerClient.requester({ - to: args(0), - type: "release" - }, { - telemetry: "RELEASE" - }), - - /** - * Send a request to the debugging server. - * - * @param aRequest object - * A JSON packet to send to the debugging server. - * @param aOnResponse function - * If specified, will be called with the JSON response packet when - * debugging server responds. - * @return Request - * This object emits a number of events to allow you to respond to - * different parts of the request lifecycle. - * It is also a Promise object, with a `then` method, that is resolved - * whenever a JSON or a Bulk response is received; and is rejected - * if the response is an error. - * Note: This return value can be ignored if you are using JSON alone, - * because the callback provided in |aOnResponse| will be bound to the - * "json-reply" event automatically. - * - * Events emitted: - * * json-reply: The server replied with a JSON packet, which is - * passed as event data. - * * bulk-reply: The server replied with bulk data, which you can read - * using the event data object containing: - * * actor: Name of actor that received the packet - * * type: Name of actor's method that was called on receipt - * * length: Size of the data to be read - * * stream: This input stream should only be used directly if you - * can ensure that you will read exactly |length| bytes - * and will not close the stream when reading is complete - * * done: If you use the stream directly (instead of |copyTo| - * below), you must signal completion by resolving / - * rejecting this deferred. If it's rejected, the - * transport will be closed. If an Error is supplied as a - * rejection value, it will be logged via |dumpn|. If you - * do use |copyTo|, resolving is taken care of for you - * when copying completes. - * * copyTo: A helper function for getting your data out of the - * stream that meets the stream handling requirements - * above, and has the following signature: - * @param output nsIAsyncOutputStream - * The stream to copy to. - * @return Promise - * The promise is resolved when copying completes or - * rejected if any (unexpected) errors occur. - * This object also emits "progress" events for each chunk - * that is copied. See stream-utils.js. - */ - request: function(aRequest, aOnResponse) { - if (!this.mainRoot) { - throw Error("Have not yet received a hello packet from the server."); - } - let type = aRequest.type || ""; - if (!aRequest.to) { - throw Error("'" + type + "' request packet has no destination."); - } - if (this._closed) { - let msg = "'" + type + "' request packet to " + - "'" + aRequest.to + "' " + - "can't be sent as the connection is closed."; - let resp = { error: "connectionClosed", message: msg }; - if (aOnResponse) { - aOnResponse(resp); - } - return promise.reject(resp); - } - - let request = new Request(aRequest); - request.format = "json"; - request.stack = components.stack; - if (aOnResponse) { - request.on("json-reply", aOnResponse); - } - - this._sendOrQueueRequest(request); - - // Implement a Promise like API on the returned object - // that resolves/rejects on request response - let deferred = promise.defer(); - function listenerJson(resp) { - request.off("json-reply", listenerJson); - request.off("bulk-reply", listenerBulk); - if (resp.error) { - deferred.reject(resp); - } else { - deferred.resolve(resp); - } - } - function listenerBulk(resp) { - request.off("json-reply", listenerJson); - request.off("bulk-reply", listenerBulk); - deferred.resolve(resp); - } - request.on("json-reply", listenerJson); - request.on("bulk-reply", listenerBulk); - request.then = deferred.promise.then.bind(deferred.promise); - - return request; - }, - - /** - * Transmit streaming data via a bulk request. - * - * This method initiates the bulk send process by queuing up the header data. - * The caller receives eventual access to a stream for writing. - * - * Since this opens up more options for how the server might respond (it could - * send back either JSON or bulk data), and the returned Request object emits - * events for different stages of the request process that you may want to - * react to. - * - * @param request Object - * This is modeled after the format of JSON packets above, but does not - * actually contain the data, but is instead just a routing header: - * * actor: Name of actor that will receive the packet - * * type: Name of actor's method that should be called on receipt - * * length: Size of the data to be sent - * @return Request - * This object emits a number of events to allow you to respond to - * different parts of the request lifecycle. - * - * Events emitted: - * * bulk-send-ready: Ready to send bulk data to the server, using the - * event data object containing: - * * stream: This output stream should only be used directly if - * you can ensure that you will write exactly |length| - * bytes and will not close the stream when writing is - * complete - * * done: If you use the stream directly (instead of |copyFrom| - * below), you must signal completion by resolving / - * rejecting this deferred. If it's rejected, the - * transport will be closed. If an Error is supplied as - * a rejection value, it will be logged via |dumpn|. If - * you do use |copyFrom|, resolving is taken care of for - * you when copying completes. - * * copyFrom: A helper function for getting your data onto the - * stream that meets the stream handling requirements - * above, and has the following signature: - * @param input nsIAsyncInputStream - * The stream to copy from. - * @return Promise - * The promise is resolved when copying completes or - * rejected if any (unexpected) errors occur. - * This object also emits "progress" events for each chunk - * that is copied. See stream-utils.js. - * * json-reply: The server replied with a JSON packet, which is - * passed as event data. - * * bulk-reply: The server replied with bulk data, which you can read - * using the event data object containing: - * * actor: Name of actor that received the packet - * * type: Name of actor's method that was called on receipt - * * length: Size of the data to be read - * * stream: This input stream should only be used directly if you - * can ensure that you will read exactly |length| bytes - * and will not close the stream when reading is complete - * * done: If you use the stream directly (instead of |copyTo| - * below), you must signal completion by resolving / - * rejecting this deferred. If it's rejected, the - * transport will be closed. If an Error is supplied as a - * rejection value, it will be logged via |dumpn|. If you - * do use |copyTo|, resolving is taken care of for you - * when copying completes. - * * copyTo: A helper function for getting your data out of the - * stream that meets the stream handling requirements - * above, and has the following signature: - * @param output nsIAsyncOutputStream - * The stream to copy to. - * @return Promise - * The promise is resolved when copying completes or - * rejected if any (unexpected) errors occur. - * This object also emits "progress" events for each chunk - * that is copied. See stream-utils.js. - */ - startBulkRequest: function(request) { - if (!this.traits.bulk) { - throw Error("Server doesn't support bulk transfers"); - } - if (!this.mainRoot) { - throw Error("Have not yet received a hello packet from the server."); - } - if (!request.type) { - throw Error("Bulk packet is missing the required 'type' field."); - } - if (!request.actor) { - throw Error("'" + request.type + "' bulk packet has no destination."); - } - if (!request.length) { - throw Error("'" + request.type + "' bulk packet has no length."); - } - - request = new Request(request); - request.format = "bulk"; - - this._sendOrQueueRequest(request); - - return request; - }, - - /** - * If a new request can be sent immediately, do so. Otherwise, queue it. - */ - _sendOrQueueRequest(request) { - let actor = request.actor; - if (!this._activeRequests.has(actor)) { - this._sendRequest(request); - } else { - this._queueRequest(request); - } - }, - - /** - * Send a request. - * @throws Error if there is already an active request in flight for the same - * actor. - */ - _sendRequest(request) { - let actor = request.actor; - this.expectReply(actor, request); - - if (request.format === "json") { - this._transport.send(request.request); - return false; - } - - this._transport.startBulkSend(request.request).then((...args) => { - request.emit("bulk-send-ready", ...args); - }); - }, - - /** - * Queue a request to be sent later. Queues are only drained when an in - * flight request to a given actor completes. - */ - _queueRequest(request) { - let actor = request.actor; - let queue = this._pendingRequests.get(actor) || []; - queue.push(request); - this._pendingRequests.set(actor, queue); - }, - - /** - * Attempt the next request to a given actor (if any). - */ - _attemptNextRequest(actor) { - if (this._activeRequests.has(actor)) { - return; - } - let queue = this._pendingRequests.get(actor); - if (!queue) { - return; - } - let request = queue.shift(); - if (queue.length === 0) { - this._pendingRequests.delete(actor); - } - this._sendRequest(request); - }, - - /** - * Arrange to hand the next reply from |aActor| to the handler bound to - * |aRequest|. - * - * DebuggerClient.prototype.request / startBulkRequest usually takes care of - * establishing the handler for a given request, but in rare cases (well, - * greetings from new root actors, is the only case at the moment) we must be - * prepared for a "reply" that doesn't correspond to any request we sent. - */ - expectReply: function(aActor, aRequest) { - if (this._activeRequests.has(aActor)) { - throw Error("clashing handlers for next reply from " + uneval(aActor)); - } - - // If a handler is passed directly (as it is with the handler for the root - // actor greeting), create a dummy request to bind this to. - if (typeof aRequest === "function") { - let handler = aRequest; - aRequest = new Request(); - aRequest.on("json-reply", handler); - } - - this._activeRequests.set(aActor, aRequest); - }, - - // Transport hooks. - - /** - * Called by DebuggerTransport to dispatch incoming packets as appropriate. - * - * @param aPacket object - * The incoming packet. - */ - onPacket: function(aPacket) { - if (!aPacket.from) { - DevToolsUtils.reportException( - "onPacket", - new Error("Server did not specify an actor, dropping packet: " + - JSON.stringify(aPacket))); - return; - } - - // If we have a registered Front for this actor, let it handle the packet - // and skip all the rest of this unpleasantness. - let front = this.getActor(aPacket.from); - if (front) { - front.onPacket(aPacket); - return; - } - - if (this._clients.has(aPacket.from) && aPacket.type) { - let client = this._clients.get(aPacket.from); - let type = aPacket.type; - if (client.events.indexOf(type) != -1) { - client.emit(type, aPacket); - // we ignore the rest, as the client is expected to handle this packet. - return; - } - } - - let activeRequest; - // See if we have a handler function waiting for a reply from this - // actor. (Don't count unsolicited notifications or pauses as - // replies.) - if (this._activeRequests.has(aPacket.from) && - !(aPacket.type in UnsolicitedNotifications) && - !(aPacket.type == ThreadStateTypes.paused && - aPacket.why.type in UnsolicitedPauses)) { - activeRequest = this._activeRequests.get(aPacket.from); - this._activeRequests.delete(aPacket.from); - } - - // If there is a subsequent request for the same actor, hand it off to the - // transport. Delivery of packets on the other end is always async, even - // in the local transport case. - this._attemptNextRequest(aPacket.from); - - // Packets that indicate thread state changes get special treatment. - if (aPacket.type in ThreadStateTypes && - this._clients.has(aPacket.from) && - typeof this._clients.get(aPacket.from)._onThreadState == "function") { - this._clients.get(aPacket.from)._onThreadState(aPacket); - } - - // TODO: Bug 1151156 - Remove once Gecko 40 is on b2g-stable. - if (!this.traits.noNeedToFakeResumptionOnNavigation) { - // On navigation the server resumes, so the client must resume as well. - // We achieve that by generating a fake resumption packet that triggers - // the client's thread state change listeners. - if (aPacket.type == UnsolicitedNotifications.tabNavigated && - this._clients.has(aPacket.from) && - this._clients.get(aPacket.from).thread) { - let thread = this._clients.get(aPacket.from).thread; - let resumption = { from: thread._actor, type: "resumed" }; - thread._onThreadState(resumption); - } - } - - // Only try to notify listeners on events, not responses to requests - // that lack a packet type. - if (aPacket.type) { - this.emit(aPacket.type, aPacket); - } - - if (activeRequest) { - let emitReply = () => activeRequest.emit("json-reply", aPacket); - if (activeRequest.stack) { - Cu.callFunctionWithAsyncStack(emitReply, activeRequest.stack, - "DevTools RDP"); - } else { - emitReply(); - } - } - }, - - /** - * Called by the DebuggerTransport to dispatch incoming bulk packets as - * appropriate. - * - * @param packet object - * The incoming packet, which contains: - * * actor: Name of actor that will receive the packet - * * type: Name of actor's method that should be called on receipt - * * length: Size of the data to be read - * * stream: This input stream should only be used directly if you can - * ensure that you will read exactly |length| bytes and will - * not close the stream when reading is complete - * * done: If you use the stream directly (instead of |copyTo| - * below), you must signal completion by resolving / - * rejecting this deferred. If it's rejected, the transport - * will be closed. If an Error is supplied as a rejection - * value, it will be logged via |dumpn|. If you do use - * |copyTo|, resolving is taken care of for you when copying - * completes. - * * copyTo: A helper function for getting your data out of the stream - * that meets the stream handling requirements above, and has - * the following signature: - * @param output nsIAsyncOutputStream - * The stream to copy to. - * @return Promise - * The promise is resolved when copying completes or rejected - * if any (unexpected) errors occur. - * This object also emits "progress" events for each chunk - * that is copied. See stream-utils.js. - */ - onBulkPacket: function(packet) { - let { actor, type, length } = packet; - - if (!actor) { - DevToolsUtils.reportException( - "onBulkPacket", - new Error("Server did not specify an actor, dropping bulk packet: " + - JSON.stringify(packet))); - return; - } - - // See if we have a handler function waiting for a reply from this - // actor. - if (!this._activeRequests.has(actor)) { - return; - } - - let activeRequest = this._activeRequests.get(actor); - this._activeRequests.delete(actor); - - // If there is a subsequent request for the same actor, hand it off to the - // transport. Delivery of packets on the other end is always async, even - // in the local transport case. - this._attemptNextRequest(actor); - - activeRequest.emit("bulk-reply", packet); - }, - - /** - * Called by DebuggerTransport when the underlying stream is closed. - * - * @param aStatus nsresult - * The status code that corresponds to the reason for closing - * the stream. - */ - onClosed: function(aStatus) { - this._closed = true; - this.emit("closed"); - - // Reject all pending and active requests - let reject = function(type, request, actor) { - // Server can send packets on its own and client only pass a callback - // to expectReply, so that there is no request object. - let msg; - if (request.request) { - msg = "'" + request.request.type + "' " + type + " request packet" + - " to '" + actor + "' " + - "can't be sent as the connection just closed."; - } else { - msg = "server side packet from '" + actor + "' can't be received " + - "as the connection just closed."; - } - let packet = { error: "connectionClosed", message: msg }; - request.emit("json-reply", packet); - }; - - let pendingRequests = new Map(this._pendingRequests); - this._pendingRequests.clear(); - pendingRequests.forEach((list, actor) => { - list.forEach(request => reject("pending", request, actor)); - }); - let activeRequests = new Map(this._activeRequests); - this._activeRequests.clear(); - activeRequests.forEach(reject.bind(null, "active")); - - // The |_pools| array on the client-side currently is used only by - // protocol.js to store active fronts, mirroring the actor pools found in - // the server. So, read all usages of "pool" as "protocol.js front". - // - // In the normal case where we shutdown cleanly, the toolbox tells each tool - // to close, and they each call |destroy| on any fronts they were using. - // When |destroy| or |cleanup| is called on a protocol.js front, it also - // removes itself from the |_pools| array. Once the toolbox has shutdown, - // the connection is closed, and we reach here. All fronts (should have - // been) |destroy|ed, so |_pools| should empty. - // - // If the connection instead aborts unexpectedly, we may end up here with - // all fronts used during the life of the connection. So, we call |cleanup| - // on them clear their state, reject pending requests, and remove themselves - // from |_pools|. This saves the toolbox from hanging indefinitely, in case - // it waits for some server response before shutdown that will now never - // arrive. - for (let pool of this._pools) { - pool.cleanup(); - } - }, - - registerClient: function(client) { - let actorID = client.actor; - if (!actorID) { - throw new Error("DebuggerServer.registerClient expects " + - "a client instance with an `actor` attribute."); - } - if (!Array.isArray(client.events)) { - throw new Error("DebuggerServer.registerClient expects " + - "a client instance with an `events` attribute " + - "that is an array."); - } - if (client.events.length > 0 && typeof (client.emit) != "function") { - throw new Error("DebuggerServer.registerClient expects " + - "a client instance with non-empty `events` array to" + - "have an `emit` function."); - } - if (this._clients.has(actorID)) { - throw new Error("DebuggerServer.registerClient already registered " + - "a client for this actor."); - } - this._clients.set(actorID, client); - }, - - unregisterClient: function(client) { - let actorID = client.actor; - if (!actorID) { - throw new Error("DebuggerServer.unregisterClient expects " + - "a Client instance with a `actor` attribute."); - } - this._clients.delete(actorID); - }, - - /** - * Actor lifetime management, echos the server's actor pools. - */ - __pools: null, - get _pools() { - if (this.__pools) { - return this.__pools; - } - this.__pools = new Set(); - return this.__pools; - }, - - addActorPool: function(pool) { - this._pools.add(pool); - }, - removeActorPool: function(pool) { - this._pools.delete(pool); - }, - getActor: function(actorID) { - let pool = this.poolFor(actorID); - return pool ? pool.get(actorID) : null; - }, - - poolFor: function(actorID) { - for (let pool of this._pools) { - if (pool.has(actorID)) return pool; - } - return null; - }, - - /** - * Currently attached addon. - */ - activeAddon: null -}; - -eventSource(DebuggerClient.prototype); - -function Request(request) { - this.request = request; -} - -Request.prototype = { - - on: function(type, listener) { - events.on(this, type, listener); - }, - - off: function(type, listener) { - events.off(this, type, listener); - }, - - once: function(type, listener) { - events.once(this, type, listener); - }, - - emit: function(type, ...args) { - events.emit(this, type, ...args); - }, - - get actor() { return this.request.to || this.request.actor; } - -}; - -/** - * Creates a tab client for the remote debugging protocol server. This client - * is a front to the tab actor created in the server side, hiding the protocol - * details in a traditional JavaScript API. - * - * @param aClient DebuggerClient - * The debugger client parent. - * @param aForm object - * The protocol form for this tab. - */ -function TabClient(aClient, aForm) { - this.client = aClient; - this._actor = aForm.from; - this._threadActor = aForm.threadActor; - this.javascriptEnabled = aForm.javascriptEnabled; - this.cacheDisabled = aForm.cacheDisabled; - this.thread = null; - this.request = this.client.request; - this.traits = aForm.traits || {}; - this.events = ["workerListChanged"]; -} - -TabClient.prototype = { - get actor() { return this._actor; }, - get _transport() { return this.client._transport; }, - - /** - * Attach to a thread actor. - * - * @param object aOptions - * Configuration options. - * - useSourceMaps: whether to use source maps or not. - * @param function aOnResponse - * Called with the response packet and a ThreadClient - * (which will be undefined on error). - */ - attachThread: function(aOptions = {}, aOnResponse = noop) { - if (this.thread) { - DevToolsUtils.executeSoon(() => aOnResponse({}, this.thread)); - return promise.resolve([{}, this.thread]); - } - - let packet = { - to: this._threadActor, - type: "attach", - options: aOptions - }; - return this.request(packet).then(aResponse => { - if (!aResponse.error) { - this.thread = new ThreadClient(this, this._threadActor); - this.client.registerClient(this.thread); - } - aOnResponse(aResponse, this.thread); - return [aResponse, this.thread]; - }); - }, - - /** - * Detach the client from the tab actor. - * - * @param function aOnResponse - * Called with the response packet. - */ - detach: DebuggerClient.requester({ - type: "detach" - }, { - before: function(aPacket) { - if (this.thread) { - this.thread.detach(); - } - return aPacket; - }, - after: function(aResponse) { - this.client.unregisterClient(this); - return aResponse; - }, - telemetry: "TABDETACH" - }), - - /** - * Bring the window to the front. - */ - focus: DebuggerClient.requester({ - type: "focus" - }, {}), - - /** - * Reload the page in this tab. - * - * @param [optional] object options - * An object with a `force` property indicating whether or not - * this reload should skip the cache - */ - reload: function(options = { force: false }) { - return this._reload(options); - }, - _reload: DebuggerClient.requester({ - type: "reload", - options: args(0) - }, { - telemetry: "RELOAD" - }), - - /** - * Navigate to another URL. - * - * @param string url - * The URL to navigate to. - */ - navigateTo: DebuggerClient.requester({ - type: "navigateTo", - url: args(0) - }, { - telemetry: "NAVIGATETO" - }), - - /** - * Reconfigure the tab actor. - * - * @param object aOptions - * A dictionary object of the new options to use in the tab actor. - * @param function aOnResponse - * Called with the response packet. - */ - reconfigure: DebuggerClient.requester({ - type: "reconfigure", - options: args(0) - }, { - telemetry: "RECONFIGURETAB" - }), - - listWorkers: DebuggerClient.requester({ - type: "listWorkers" - }, { - telemetry: "LISTWORKERS" - }), - - attachWorker: function(aWorkerActor, aOnResponse) { - this.client.attachWorker(aWorkerActor, aOnResponse); - }, - - /** - * Resolve a location ({ url, line, column }) to its current - * source mapping location. - * - * @param {String} arg[0].url - * @param {Number} arg[0].line - * @param {Number?} arg[0].column - */ - resolveLocation: DebuggerClient.requester({ - type: "resolveLocation", - location: args(0) - }), -}; - -eventSource(TabClient.prototype); - -function WorkerClient(aClient, aForm) { - this.client = aClient; - this._actor = aForm.from; - this._isClosed = false; - this._url = aForm.url; - - this._onClose = this._onClose.bind(this); - - this.addListener("close", this._onClose); - - this.traits = {}; -} - -WorkerClient.prototype = { - get _transport() { - return this.client._transport; - }, - - get request() { - return this.client.request; - }, - - get actor() { - return this._actor; - }, - - get url() { - return this._url; - }, - - get isClosed() { - return this._isClosed; - }, - - detach: DebuggerClient.requester({ type: "detach" }, { - after: function(aResponse) { - if (this.thread) { - this.client.unregisterClient(this.thread); - } - this.client.unregisterClient(this); - return aResponse; - }, - - telemetry: "WORKERDETACH" - }), - - attachThread: function(aOptions = {}, aOnResponse = noop) { - if (this.thread) { - let response = [{ - type: "connected", - threadActor: this.thread._actor, - consoleActor: this.consoleActor, - }, this.thread]; - DevToolsUtils.executeSoon(() => aOnResponse(response)); - return response; - } - - // The connect call on server doesn't attach the thread as of version 44. - return this.request({ - to: this._actor, - type: "connect", - options: aOptions, - }).then(connectReponse => { - if (connectReponse.error) { - aOnResponse(connectReponse, null); - return [connectResponse, null]; - } - - return this.request({ - to: connectReponse.threadActor, - type: "attach", - options: aOptions - }).then(attachResponse => { - if (attachResponse.error) { - aOnResponse(attachResponse, null); - } - - this.thread = new ThreadClient(this, connectReponse.threadActor); - this.consoleActor = connectReponse.consoleActor; - this.client.registerClient(this.thread); - - aOnResponse(connectReponse, this.thread); - return [connectResponse, this.thread]; - }); - }); - }, - - _onClose: function() { - this.removeListener("close", this._onClose); - - if (this.thread) { - this.client.unregisterClient(this.thread); - } - this.client.unregisterClient(this); - this._isClosed = true; - }, - - reconfigure: function() { - return Promise.resolve(); - }, - - events: ["close"] -}; - -eventSource(WorkerClient.prototype); - -function AddonClient(aClient, aActor) { - this._client = aClient; - this._actor = aActor; - this.request = this._client.request; - this.events = []; -} - -AddonClient.prototype = { - get actor() { return this._actor; }, - get _transport() { return this._client._transport; }, - - /** - * Detach the client from the addon actor. - * - * @param function aOnResponse - * Called with the response packet. - */ - detach: DebuggerClient.requester({ - type: "detach" - }, { - after: function(aResponse) { - if (this._client.activeAddon === this) { - this._client.activeAddon = null; - } - this._client.unregisterClient(this); - return aResponse; - }, - telemetry: "ADDONDETACH" - }) -}; - -/** - * A RootClient object represents a root actor on the server. Each - * DebuggerClient keeps a RootClient instance representing the root actor - * for the initial connection; DebuggerClient's 'listTabs' and - * 'listChildProcesses' methods forward to that root actor. - * - * @param aClient object - * The client connection to which this actor belongs. - * @param aGreeting string - * The greeting packet from the root actor we're to represent. - * - * Properties of a RootClient instance: - * - * @property actor string - * The name of this child's root actor. - * @property applicationType string - * The application type, as given in the root actor's greeting packet. - * @property traits object - * The traits object, as given in the root actor's greeting packet. - */ -function RootClient(aClient, aGreeting) { - this._client = aClient; - this.actor = aGreeting.from; - this.applicationType = aGreeting.applicationType; - this.traits = aGreeting.traits; -} -exports.RootClient = RootClient; - -RootClient.prototype = { - constructor: RootClient, - - /** - * List the open tabs. - * - * @param function aOnResponse - * Called with the response packet. - */ - listTabs: DebuggerClient.requester({ type: "listTabs" }, - { telemetry: "LISTTABS" }), - - /** - * List the installed addons. - * - * @param function aOnResponse - * Called with the response packet. - */ - listAddons: DebuggerClient.requester({ type: "listAddons" }, - { telemetry: "LISTADDONS" }), - - /** - * List the registered workers. - * - * @param function aOnResponse - * Called with the response packet. - */ - listWorkers: DebuggerClient.requester({ type: "listWorkers" }, - { telemetry: "LISTWORKERS" }), - - /** - * List the registered service workers. - * - * @param function aOnResponse - * Called with the response packet. - */ - listServiceWorkerRegistrations: DebuggerClient.requester({ type: "listServiceWorkerRegistrations" }, - { telemetry: "LISTSERVICEWORKERREGISTRATIONS" }), - - /** - * List the running processes. - * - * @param function aOnResponse - * Called with the response packet. - */ - listProcesses: DebuggerClient.requester({ type: "listProcesses" }, - { telemetry: "LISTPROCESSES" }), - - /** - * Fetch the TabActor for the currently selected tab, or for a specific - * tab given as first parameter. - * - * @param [optional] object aFilter - * A dictionary object with following optional attributes: - * - outerWindowID: used to match tabs in parent process - * - tabId: used to match tabs in child processes - * - tab: a reference to xul:tab element - * If nothing is specified, returns the actor for the currently - * selected tab. - */ - getTab: function(aFilter) { - let packet = { - to: this.actor, - type: "getTab" - }; - - if (aFilter) { - if (typeof (aFilter.outerWindowID) == "number") { - packet.outerWindowID = aFilter.outerWindowID; - } else if (typeof (aFilter.tabId) == "number") { - packet.tabId = aFilter.tabId; - } else if ("tab" in aFilter) { - let browser = aFilter.tab.linkedBrowser; - if (browser.frameLoader.tabParent) { - // Tabs in child process - packet.tabId = browser.frameLoader.tabParent.tabId; - } else { - // Tabs in parent process - let windowUtils = browser.contentWindow - .QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIDOMWindowUtils); - packet.outerWindowID = windowUtils.outerWindowID; - } - } else { - // Throw if a filter object have been passed but without - // any clearly idenfified filter. - throw new Error("Unsupported argument given to getTab request"); - } - } - - return this.request(packet); - }, - - /** - * Description of protocol's actors and methods. - * - * @param function aOnResponse - * Called with the response packet. - */ - protocolDescription: DebuggerClient.requester({ type: "protocolDescription" }, - { telemetry: "PROTOCOLDESCRIPTION" }), - - /* - * Methods constructed by DebuggerClient.requester require these forwards - * on their 'this'. - */ - get _transport() { return this._client._transport; }, - get request() { return this._client.request; } -}; - -/** - * Creates a thread client for the remote debugging protocol server. This client - * is a front to the thread actor created in the server side, hiding the - * protocol details in a traditional JavaScript API. - * - * @param aClient DebuggerClient|TabClient - * The parent of the thread (tab for tab-scoped debuggers, DebuggerClient - * for chrome debuggers). - * @param aActor string - * The actor ID for this thread. - */ -function ThreadClient(aClient, aActor) { - this._parent = aClient; - this.client = aClient instanceof DebuggerClient ? aClient : aClient.client; - this._actor = aActor; - this._frameCache = []; - this._scriptCache = {}; - this._pauseGrips = {}; - this._threadGrips = {}; - this.request = this.client.request; -} - -ThreadClient.prototype = { - _state: "paused", - get state() { return this._state; }, - get paused() { return this._state === "paused"; }, - - _pauseOnExceptions: false, - _ignoreCaughtExceptions: false, - _pauseOnDOMEvents: null, - - _actor: null, - get actor() { return this._actor; }, - - get _transport() { return this.client._transport; }, - - _assertPaused: function(aCommand) { - if (!this.paused) { - throw Error(aCommand + " command sent while not paused. Currently " + this._state); - } - }, - - /** - * Resume a paused thread. If the optional aLimit parameter is present, then - * the thread will also pause when that limit is reached. - * - * @param [optional] object aLimit - * An object with a type property set to the appropriate limit (next, - * step, or finish) per the remote debugging protocol specification. - * Use null to specify no limit. - * @param function aOnResponse - * Called with the response packet. - */ - _doResume: DebuggerClient.requester({ - type: "resume", - resumeLimit: args(0) - }, { - before: function(aPacket) { - this._assertPaused("resume"); - - // Put the client in a tentative "resuming" state so we can prevent - // further requests that should only be sent in the paused state. - this._state = "resuming"; - - if (this._pauseOnExceptions) { - aPacket.pauseOnExceptions = this._pauseOnExceptions; - } - if (this._ignoreCaughtExceptions) { - aPacket.ignoreCaughtExceptions = this._ignoreCaughtExceptions; - } - if (this._pauseOnDOMEvents) { - aPacket.pauseOnDOMEvents = this._pauseOnDOMEvents; - } - return aPacket; - }, - after: function(aResponse) { - if (aResponse.error) { - // There was an error resuming, back to paused state. - this._state = "paused"; - } - return aResponse; - }, - telemetry: "RESUME" - }), - - /** - * Reconfigure the thread actor. - * - * @param object aOptions - * A dictionary object of the new options to use in the thread actor. - * @param function aOnResponse - * Called with the response packet. - */ - reconfigure: DebuggerClient.requester({ - type: "reconfigure", - options: args(0) - }, { - telemetry: "RECONFIGURETHREAD" - }), - - /** - * Resume a paused thread. - */ - resume: function(aOnResponse) { - return this._doResume(null, aOnResponse); - }, - - /** - * Resume then pause without stepping. - * - * @param function aOnResponse - * Called with the response packet. - */ - resumeThenPause: function(aOnResponse) { - return this._doResume({ type: "break" }, aOnResponse); - }, - - /** - * Step over a function call. - * - * @param function aOnResponse - * Called with the response packet. - */ - stepOver: function(aOnResponse) { - return this._doResume({ type: "next" }, aOnResponse); - }, - - /** - * Step into a function call. - * - * @param function aOnResponse - * Called with the response packet. - */ - stepIn: function(aOnResponse) { - return this._doResume({ type: "step" }, aOnResponse); - }, - - /** - * Step out of a function call. - * - * @param function aOnResponse - * Called with the response packet. - */ - stepOut: function(aOnResponse) { - return this._doResume({ type: "finish" }, aOnResponse); - }, - - /** - * Immediately interrupt a running thread. - * - * @param function aOnResponse - * Called with the response packet. - */ - interrupt: function(aOnResponse) { - return this._doInterrupt(null, aOnResponse); - }, - - /** - * Pause execution right before the next JavaScript bytecode is executed. - * - * @param function aOnResponse - * Called with the response packet. - */ - breakOnNext: function(aOnResponse) { - return this._doInterrupt("onNext", aOnResponse); - }, - - /** - * Interrupt a running thread. - * - * @param function aOnResponse - * Called with the response packet. - */ - _doInterrupt: DebuggerClient.requester({ - type: "interrupt", - when: args(0) - }, { - telemetry: "INTERRUPT" - }), - - /** - * Enable or disable pausing when an exception is thrown. - * - * @param boolean aFlag - * Enables pausing if true, disables otherwise. - * @param function aOnResponse - * Called with the response packet. - */ - pauseOnExceptions: function(aPauseOnExceptions, - aIgnoreCaughtExceptions, - aOnResponse = noop) { - this._pauseOnExceptions = aPauseOnExceptions; - this._ignoreCaughtExceptions = aIgnoreCaughtExceptions; - - // Otherwise send the flag using a standard resume request. - if (!this.paused) { - return this.interrupt(aResponse => { - if (aResponse.error) { - // Can't continue if pausing failed. - aOnResponse(aResponse); - return aResponse; - } - return this.resume(aOnResponse); - }); - } - - aOnResponse(); - return promise.resolve(); - }, - - /** - * Enable pausing when the specified DOM events are triggered. Disabling - * pausing on an event can be realized by calling this method with the updated - * array of events that doesn't contain it. - * - * @param array|string events - * An array of strings, representing the DOM event types to pause on, - * or "*" to pause on all DOM events. Pass an empty array to - * completely disable pausing on DOM events. - * @param function onResponse - * Called with the response packet in a future turn of the event loop. - */ - pauseOnDOMEvents: function(events, onResponse = noop) { - this._pauseOnDOMEvents = events; - // If the debuggee is paused, the value of the array will be communicated in - // the next resumption. Otherwise we have to force a pause in order to send - // the array. - if (this.paused) { - DevToolsUtils.executeSoon(() => onResponse({})); - return {}; - } - return this.interrupt(response => { - // Can't continue if pausing failed. - if (response.error) { - onResponse(response); - return response; - } - return this.resume(onResponse); - }); - }, - - /** - * Send a clientEvaluate packet to the debuggee. Response - * will be a resume packet. - * - * @param string aFrame - * The actor ID of the frame where the evaluation should take place. - * @param string aExpression - * The expression that will be evaluated in the scope of the frame - * above. - * @param function aOnResponse - * Called with the response packet. - */ - eval: DebuggerClient.requester({ - type: "clientEvaluate", - frame: args(0), - expression: args(1) - }, { - before: function(aPacket) { - this._assertPaused("eval"); - // Put the client in a tentative "resuming" state so we can prevent - // further requests that should only be sent in the paused state. - this._state = "resuming"; - return aPacket; - }, - after: function(aResponse) { - if (aResponse.error) { - // There was an error resuming, back to paused state. - this._state = "paused"; - } - return aResponse; - }, - telemetry: "CLIENTEVALUATE" - }), - - /** - * Detach from the thread actor. - * - * @param function aOnResponse - * Called with the response packet. - */ - detach: DebuggerClient.requester({ - type: "detach" - }, { - after: function(aResponse) { - this.client.unregisterClient(this); - this._parent.thread = null; - return aResponse; - }, - telemetry: "THREADDETACH" - }), - - /** - * Release multiple thread-lifetime object actors. If any pause-lifetime - * actors are included in the request, a |notReleasable| error will return, - * but all the thread-lifetime ones will have been released. - * - * @param array actors - * An array with actor IDs to release. - */ - releaseMany: DebuggerClient.requester({ - type: "releaseMany", - actors: args(0), - }, { - telemetry: "RELEASEMANY" - }), - - /** - * Promote multiple pause-lifetime object actors to thread-lifetime ones. - * - * @param array actors - * An array with actor IDs to promote. - */ - threadGrips: DebuggerClient.requester({ - type: "threadGrips", - actors: args(0) - }, { - telemetry: "THREADGRIPS" - }), - - /** - * Return the event listeners defined on the page. - * - * @param aOnResponse Function - * Called with the thread's response. - */ - eventListeners: DebuggerClient.requester({ - type: "eventListeners" - }, { - telemetry: "EVENTLISTENERS" - }), - - /** - * Request the loaded sources for the current thread. - * - * @param aOnResponse Function - * Called with the thread's response. - */ - getSources: DebuggerClient.requester({ - type: "sources" - }, { - telemetry: "SOURCES" - }), - - /** - * Clear the thread's source script cache. A scriptscleared event - * will be sent. - */ - _clearScripts: function() { - if (Object.keys(this._scriptCache).length > 0) { - this._scriptCache = {}; - this.emit("scriptscleared"); - } - }, - - /** - * Request frames from the callstack for the current thread. - * - * @param aStart integer - * The number of the youngest stack frame to return (the youngest - * frame is 0). - * @param aCount integer - * The maximum number of frames to return, or null to return all - * frames. - * @param aOnResponse function - * Called with the thread's response. - */ - getFrames: DebuggerClient.requester({ - type: "frames", - start: args(0), - count: args(1) - }, { - telemetry: "FRAMES" - }), - - /** - * An array of cached frames. Clients can observe the framesadded and - * framescleared event to keep up to date on changes to this cache, - * and can fill it using the fillFrames method. - */ - get cachedFrames() { return this._frameCache; }, - - /** - * true if there are more stack frames available on the server. - */ - get moreFrames() { - return this.paused && (!this._frameCache || this._frameCache.length == 0 - || !this._frameCache[this._frameCache.length - 1].oldest); - }, - - /** - * Ensure that at least aTotal stack frames have been loaded in the - * ThreadClient's stack frame cache. A framesadded event will be - * sent when the stack frame cache is updated. - * - * @param aTotal number - * The minimum number of stack frames to be included. - * @param aCallback function - * Optional callback function called when frames have been loaded - * @returns true if a framesadded notification should be expected. - */ - fillFrames: function(aTotal, aCallback = noop) { - this._assertPaused("fillFrames"); - if (this._frameCache.length >= aTotal) { - return false; - } - - let numFrames = this._frameCache.length; - - this.getFrames(numFrames, aTotal - numFrames, (aResponse) => { - if (aResponse.error) { - aCallback(aResponse); - return; - } - - let threadGrips = DevToolsUtils.values(this._threadGrips); - - for (let i in aResponse.frames) { - let frame = aResponse.frames[i]; - if (!frame.where.source) { - // Older servers use urls instead, so we need to resolve - // them to source actors - for (let grip of threadGrips) { - if (grip instanceof SourceClient && grip.url === frame.url) { - frame.where.source = grip._form; - } - } - } - - this._frameCache[frame.depth] = frame; - } - - // If we got as many frames as we asked for, there might be more - // frames available. - this.emit("framesadded"); - - aCallback(aResponse); - }); - - return true; - }, - - /** - * Clear the thread's stack frame cache. A framescleared event - * will be sent. - */ - _clearFrames: function() { - if (this._frameCache.length > 0) { - this._frameCache = []; - this.emit("framescleared"); - } - }, - - /** - * Return a ObjectClient object for the given object grip. - * - * @param aGrip object - * A pause-lifetime object grip returned by the protocol. - */ - pauseGrip: function(aGrip) { - if (aGrip.actor in this._pauseGrips) { - return this._pauseGrips[aGrip.actor]; - } - - let client = new ObjectClient(this.client, aGrip); - this._pauseGrips[aGrip.actor] = client; - return client; - }, - - /** - * Get or create a long string client, checking the grip client cache if it - * already exists. - * - * @param aGrip Object - * The long string grip returned by the protocol. - * @param aGripCacheName String - * The property name of the grip client cache to check for existing - * clients in. - */ - _longString: function(aGrip, aGripCacheName) { - if (aGrip.actor in this[aGripCacheName]) { - return this[aGripCacheName][aGrip.actor]; - } - - let client = new LongStringClient(this.client, aGrip); - this[aGripCacheName][aGrip.actor] = client; - return client; - }, - - /** - * Return an instance of LongStringClient for the given long string grip that - * is scoped to the current pause. - * - * @param aGrip Object - * The long string grip returned by the protocol. - */ - pauseLongString: function(aGrip) { - return this._longString(aGrip, "_pauseGrips"); - }, - - /** - * Return an instance of LongStringClient for the given long string grip that - * is scoped to the thread lifetime. - * - * @param aGrip Object - * The long string grip returned by the protocol. - */ - threadLongString: function(aGrip) { - return this._longString(aGrip, "_threadGrips"); - }, - - /** - * Clear and invalidate all the grip clients from the given cache. - * - * @param aGripCacheName - * The property name of the grip cache we want to clear. - */ - _clearObjectClients: function(aGripCacheName) { - for (let id in this[aGripCacheName]) { - this[aGripCacheName][id].valid = false; - } - this[aGripCacheName] = {}; - }, - - /** - * Invalidate pause-lifetime grip clients and clear the list of current grip - * clients. - */ - _clearPauseGrips: function() { - this._clearObjectClients("_pauseGrips"); - }, - - /** - * Invalidate thread-lifetime grip clients and clear the list of current grip - * clients. - */ - _clearThreadGrips: function() { - this._clearObjectClients("_threadGrips"); - }, - - /** - * Handle thread state change by doing necessary cleanup and notifying all - * registered listeners. - */ - _onThreadState: function(aPacket) { - this._state = ThreadStateTypes[aPacket.type]; - // The debugger UI may not be initialized yet so we want to keep - // the packet around so it knows what to pause state to display - // when it's initialized - this._lastPausePacket = aPacket.type === "resumed" ? null : aPacket; - this._clearFrames(); - this._clearPauseGrips(); - aPacket.type === ThreadStateTypes.detached && this._clearThreadGrips(); - this.client._eventsEnabled && this.emit(aPacket.type, aPacket); - }, - - getLastPausePacket: function() { - return this._lastPausePacket; - }, - - /** - * Return an EnvironmentClient instance for the given environment actor form. - */ - environment: function(aForm) { - return new EnvironmentClient(this.client, aForm); - }, - - /** - * Return an instance of SourceClient for the given source actor form. - */ - source: function(aForm) { - if (aForm.actor in this._threadGrips) { - return this._threadGrips[aForm.actor]; - } - - return this._threadGrips[aForm.actor] = new SourceClient(this, aForm); - }, - - /** - * Request the prototype and own properties of mutlipleObjects. - * - * @param aOnResponse function - * Called with the request's response. - * @param actors [string] - * List of actor ID of the queried objects. - */ - getPrototypesAndProperties: DebuggerClient.requester({ - type: "prototypesAndProperties", - actors: args(0) - }, { - telemetry: "PROTOTYPESANDPROPERTIES" - }), - - events: ["newSource"] -}; - -eventSource(ThreadClient.prototype); - -/** - * Creates a tracing profiler client for the remote debugging protocol - * server. This client is a front to the trace actor created on the - * server side, hiding the protocol details in a traditional - * JavaScript API. - * - * @param aClient DebuggerClient - * The debugger client parent. - * @param aActor string - * The actor ID for this thread. - */ -function TraceClient(aClient, aActor) { - this._client = aClient; - this._actor = aActor; - this._activeTraces = new Set(); - this._waitingPackets = new Map(); - this._expectedPacket = 0; - this.request = this._client.request; - this.events = []; -} - -TraceClient.prototype = { - get actor() { return this._actor; }, - get tracing() { return this._activeTraces.size > 0; }, - - get _transport() { return this._client._transport; }, - - /** - * Detach from the trace actor. - */ - detach: DebuggerClient.requester({ - type: "detach" - }, { - after: function(aResponse) { - this._client.unregisterClient(this); - return aResponse; - }, - telemetry: "TRACERDETACH" - }), - - /** - * Start a new trace. - * - * @param aTrace [string] - * An array of trace types to be recorded by the new trace. - * - * @param aName string - * The name of the new trace. - * - * @param aOnResponse function - * Called with the request's response. - */ - startTrace: DebuggerClient.requester({ - type: "startTrace", - name: args(1), - trace: args(0) - }, { - after: function(aResponse) { - if (aResponse.error) { - return aResponse; - } - - if (!this.tracing) { - this._waitingPackets.clear(); - this._expectedPacket = 0; - } - this._activeTraces.add(aResponse.name); - - return aResponse; - }, - telemetry: "STARTTRACE" - }), - - /** - * End a trace. If a name is provided, stop the named - * trace. Otherwise, stop the most recently started trace. - * - * @param aName string - * The name of the trace to stop. - * - * @param aOnResponse function - * Called with the request's response. - */ - stopTrace: DebuggerClient.requester({ - type: "stopTrace", - name: args(0) - }, { - after: function(aResponse) { - if (aResponse.error) { - return aResponse; - } - - this._activeTraces.delete(aResponse.name); - - return aResponse; - }, - telemetry: "STOPTRACE" - }) -}; - -/** - * Grip clients are used to retrieve information about the relevant object. - * - * @param aClient DebuggerClient - * The debugger client parent. - * @param aGrip object - * A pause-lifetime object grip returned by the protocol. - */ -function ObjectClient(aClient, aGrip) -{ - this._grip = aGrip; - this._client = aClient; - this.request = this._client.request; -} -exports.ObjectClient = ObjectClient; - -ObjectClient.prototype = { - get actor() { return this._grip.actor; }, - get _transport() { return this._client._transport; }, - - valid: true, - - get isFrozen() { - return this._grip.frozen; - }, - get isSealed() { - return this._grip.sealed; - }, - get isExtensible() { - return this._grip.extensible; - }, - - getDefinitionSite: DebuggerClient.requester({ - type: "definitionSite" - }, { - before: function(aPacket) { - if (this._grip.class != "Function") { - throw new Error("getDefinitionSite is only valid for function grips."); - } - return aPacket; - } - }), - - /** - * Request the names of a function's formal parameters. - * - * @param aOnResponse function - * Called with an object of the form: - * { parameterNames:[, ...] } - * where each is the name of a parameter. - */ - getParameterNames: DebuggerClient.requester({ - type: "parameterNames" - }, { - before: function(aPacket) { - if (this._grip.class !== "Function") { - throw new Error("getParameterNames is only valid for function grips."); - } - return aPacket; - }, - telemetry: "PARAMETERNAMES" - }), - - /** - * Request the names of the properties defined on the object and not its - * prototype. - * - * @param aOnResponse function Called with the request's response. - */ - getOwnPropertyNames: DebuggerClient.requester({ - type: "ownPropertyNames" - }, { - telemetry: "OWNPROPERTYNAMES" - }), - - /** - * Request the prototype and own properties of the object. - * - * @param aOnResponse function Called with the request's response. - */ - getPrototypeAndProperties: DebuggerClient.requester({ - type: "prototypeAndProperties" - }, { - telemetry: "PROTOTYPEANDPROPERTIES" - }), - - /** - * Request a PropertyIteratorClient instance to ease listing - * properties for this object. - * - * @param options Object - * A dictionary object with various boolean attributes: - * - ignoreSafeGetters Boolean - * If true, do not iterate over safe getters. - * - ignoreIndexedProperties Boolean - * If true, filters out Array items. - * e.g. properties names between `0` and `object.length`. - * - ignoreNonIndexedProperties Boolean - * If true, filters out items that aren't array items - * e.g. properties names that are not a number between `0` - * and `object.length`. - * - sort Boolean - * If true, the iterator will sort the properties by name - * before dispatching them. - * @param aOnResponse function Called with the client instance. - */ - enumProperties: DebuggerClient.requester({ - type: "enumProperties", - options: args(0) - }, { - after: function(aResponse) { - if (aResponse.iterator) { - return { iterator: new PropertyIteratorClient(this._client, aResponse.iterator) }; - } - return aResponse; - }, - telemetry: "ENUMPROPERTIES" - }), - - /** - * Request a PropertyIteratorClient instance to enumerate entries in a - * Map/Set-like object. - * - * @param aOnResponse function Called with the request's response. - */ - enumEntries: DebuggerClient.requester({ - type: "enumEntries" - }, { - before: function(packet) { - if (!["Map", "WeakMap", "Set", "WeakSet"].includes(this._grip.class)) { - throw new Error("enumEntries is only valid for Map/Set-like grips."); - } - return packet; - }, - after: function(response) { - if (response.iterator) { - return { - iterator: new PropertyIteratorClient(this._client, response.iterator) - }; - } - return response; - } - }), - - /** - * Request the property descriptor of the object's specified property. - * - * @param aName string The name of the requested property. - * @param aOnResponse function Called with the request's response. - */ - getProperty: DebuggerClient.requester({ - type: "property", - name: args(0) - }, { - telemetry: "PROPERTY" - }), - - /** - * Request the prototype of the object. - * - * @param aOnResponse function Called with the request's response. - */ - getPrototype: DebuggerClient.requester({ - type: "prototype" - }, { - telemetry: "PROTOTYPE" - }), - - /** - * Request the display string of the object. - * - * @param aOnResponse function Called with the request's response. - */ - getDisplayString: DebuggerClient.requester({ - type: "displayString" - }, { - telemetry: "DISPLAYSTRING" - }), - - /** - * Request the scope of the object. - * - * @param aOnResponse function Called with the request's response. - */ - getScope: DebuggerClient.requester({ - type: "scope" - }, { - before: function(aPacket) { - if (this._grip.class !== "Function") { - throw new Error("scope is only valid for function grips."); - } - return aPacket; - }, - telemetry: "SCOPE" - }), - - /** - * Request the promises directly depending on the current promise. - */ - getDependentPromises: DebuggerClient.requester({ - type: "dependentPromises" - }, { - before: function(aPacket) { - if (this._grip.class !== "Promise") { - throw new Error("getDependentPromises is only valid for promise " + - "grips."); - } - return aPacket; - } - }), - - /** - * Request the stack to the promise's allocation point. - */ - getPromiseAllocationStack: DebuggerClient.requester({ - type: "allocationStack" - }, { - before: function(aPacket) { - if (this._grip.class !== "Promise") { - throw new Error("getAllocationStack is only valid for promise grips."); - } - return aPacket; - } - }), - - /** - * Request the stack to the promise's fulfillment point. - */ - getPromiseFulfillmentStack: DebuggerClient.requester({ - type: "fulfillmentStack" - }, { - before: function(packet) { - if (this._grip.class !== "Promise") { - throw new Error("getPromiseFulfillmentStack is only valid for " + - "promise grips."); - } - return packet; - } - }), - - /** - * Request the stack to the promise's rejection point. - */ - getPromiseRejectionStack: DebuggerClient.requester({ - type: "rejectionStack" - }, { - before: function(packet) { - if (this._grip.class !== "Promise") { - throw new Error("getPromiseRejectionStack is only valid for " + - "promise grips."); - } - return packet; - } - }) -}; - -/** - * A PropertyIteratorClient provides a way to access to property names and - * values of an object efficiently, slice by slice. - * Note that the properties can be sorted in the backend, - * this is controled while creating the PropertyIteratorClient - * from ObjectClient.enumProperties. - * - * @param aClient DebuggerClient - * The debugger client parent. - * @param aGrip Object - * A PropertyIteratorActor grip returned by the protocol via - * TabActor.enumProperties request. - */ -function PropertyIteratorClient(aClient, aGrip) { - this._grip = aGrip; - this._client = aClient; - this.request = this._client.request; -} - -PropertyIteratorClient.prototype = { - get actor() { return this._grip.actor; }, - - /** - * Get the total number of properties available in the iterator. - */ - get count() { return this._grip.count; }, - - /** - * Get one or more property names that correspond to the positions in the - * indexes parameter. - * - * @param indexes Array - * An array of property indexes. - * @param aCallback Function - * The function called when we receive the property names. - */ - names: DebuggerClient.requester({ - type: "names", - indexes: args(0) - }, {}), - - /** - * Get a set of following property value(s). - * - * @param start Number - * The index of the first property to fetch. - * @param count Number - * The number of properties to fetch. - * @param aCallback Function - * The function called when we receive the property values. - */ - slice: DebuggerClient.requester({ - type: "slice", - start: args(0), - count: args(1) - }, {}), - - /** - * Get all the property values. - * - * @param aCallback Function - * The function called when we receive the property values. - */ - all: DebuggerClient.requester({ - type: "all" - }, {}), -}; - -/** - * A LongStringClient provides a way to access "very long" strings from the - * debugger server. - * - * @param aClient DebuggerClient - * The debugger client parent. - * @param aGrip Object - * A pause-lifetime long string grip returned by the protocol. - */ -function LongStringClient(aClient, aGrip) { - this._grip = aGrip; - this._client = aClient; - this.request = this._client.request; -} -exports.LongStringClient = LongStringClient; - -LongStringClient.prototype = { - get actor() { return this._grip.actor; }, - get length() { return this._grip.length; }, - get initial() { return this._grip.initial; }, - get _transport() { return this._client._transport; }, - - valid: true, - - /** - * Get the substring of this LongString from aStart to aEnd. - * - * @param aStart Number - * The starting index. - * @param aEnd Number - * The ending index. - * @param aCallback Function - * The function called when we receive the substring. - */ - substring: DebuggerClient.requester({ - type: "substring", - start: args(0), - end: args(1) - }, { - telemetry: "SUBSTRING" - }), -}; - -/** - * A SourceClient provides a way to access the source text of a script. - * - * @param aClient ThreadClient - * The thread client parent. - * @param aForm Object - * The form sent across the remote debugging protocol. - */ -function SourceClient(aClient, aForm) { - this._form = aForm; - this._isBlackBoxed = aForm.isBlackBoxed; - this._isPrettyPrinted = aForm.isPrettyPrinted; - this._activeThread = aClient; - this._client = aClient.client; -} - -SourceClient.prototype = { - get _transport() { - return this._client._transport; - }, - get isBlackBoxed() { - return this._isBlackBoxed; - }, - get isPrettyPrinted() { - return this._isPrettyPrinted; - }, - get actor() { - return this._form.actor; - }, - get request() { - return this._client.request; - }, - get url() { - return this._form.url; - }, - - /** - * Black box this SourceClient's source. - * - * @param aCallback Function - * The callback function called when we receive the response from the server. - */ - blackBox: DebuggerClient.requester({ - type: "blackbox" - }, { - telemetry: "BLACKBOX", - after: function(aResponse) { - if (!aResponse.error) { - this._isBlackBoxed = true; - if (this._activeThread) { - this._activeThread.emit("blackboxchange", this); - } - } - return aResponse; - } - }), - - /** - * Un-black box this SourceClient's source. - * - * @param aCallback Function - * The callback function called when we receive the response from the server. - */ - unblackBox: DebuggerClient.requester({ - type: "unblackbox" - }, { - telemetry: "UNBLACKBOX", - after: function(aResponse) { - if (!aResponse.error) { - this._isBlackBoxed = false; - if (this._activeThread) { - this._activeThread.emit("blackboxchange", this); - } - } - return aResponse; - } - }), - - /** - * Get Executable Lines from a source - * - * @param aCallback Function - * The callback function called when we receive the response from the server. - */ - getExecutableLines: function(cb = noop) { - let packet = { - to: this._form.actor, - type: "getExecutableLines" - }; - - return this._client.request(packet).then(res => { - cb(res.lines); - return res.lines; - }); - }, - - /** - * Get a long string grip for this SourceClient's source. - */ - source: function(aCallback = noop) { - let packet = { - to: this._form.actor, - type: "source" - }; - return this._client.request(packet).then(aResponse => { - return this._onSourceResponse(aResponse, aCallback); - }); - }, - - /** - * Pretty print this source's text. - */ - prettyPrint: function(aIndent, aCallback = noop) { - const packet = { - to: this._form.actor, - type: "prettyPrint", - indent: aIndent - }; - return this._client.request(packet).then(aResponse => { - if (!aResponse.error) { - this._isPrettyPrinted = true; - this._activeThread._clearFrames(); - this._activeThread.emit("prettyprintchange", this); - } - return this._onSourceResponse(aResponse, aCallback); - }); - }, - - /** - * Stop pretty printing this source's text. - */ - disablePrettyPrint: function(aCallback = noop) { - const packet = { - to: this._form.actor, - type: "disablePrettyPrint" - }; - return this._client.request(packet).then(aResponse => { - if (!aResponse.error) { - this._isPrettyPrinted = false; - this._activeThread._clearFrames(); - this._activeThread.emit("prettyprintchange", this); - } - return this._onSourceResponse(aResponse, aCallback); - }); - }, - - _onSourceResponse: function(aResponse, aCallback) { - if (aResponse.error) { - aCallback(aResponse); - return aResponse; - } - - if (typeof aResponse.source === "string") { - aCallback(aResponse); - return aResponse; - } - - let { contentType, source } = aResponse; - let longString = this._activeThread.threadLongString(source); - return longString.substring(0, longString.length).then(function(aResponse) { - if (aResponse.error) { - aCallback(aResponse); - return aReponse; - } - - let response = { - source: aResponse.substring, - contentType: contentType - }; - aCallback(response); - return response; - }); - }, - - /** - * Request to set a breakpoint in the specified location. - * - * @param object aLocation - * The location and condition of the breakpoint in - * the form of { line[, column, condition] }. - * @param function aOnResponse - * Called with the thread's response. - */ - setBreakpoint: function({ line, column, condition, noSliding }, aOnResponse = noop) { - // A helper function that sets the breakpoint. - let doSetBreakpoint = aCallback => { - let root = this._client.mainRoot; - let location = { - line: line, - column: column - }; - - let packet = { - to: this.actor, - type: "setBreakpoint", - location: location, - condition: condition, - noSliding: noSliding - }; - - // Backwards compatibility: send the breakpoint request to the - // thread if the server doesn't support Debugger.Source actors. - if (!root.traits.debuggerSourceActors) { - packet.to = this._activeThread.actor; - packet.location.url = this.url; - } - - return this._client.request(packet).then(aResponse => { - // Ignoring errors, since the user may be setting a breakpoint in a - // dead script that will reappear on a page reload. - let bpClient; - if (aResponse.actor) { - bpClient = new BreakpointClient( - this._client, - this, - aResponse.actor, - location, - root.traits.conditionalBreakpoints ? condition : undefined - ); - } - aOnResponse(aResponse, bpClient); - if (aCallback) { - aCallback(); - } - return [aResponse, bpClient]; - }); - }; - - // If the debuggee is paused, just set the breakpoint. - if (this._activeThread.paused) { - return doSetBreakpoint(); - } - // Otherwise, force a pause in order to set the breakpoint. - return this._activeThread.interrupt().then(aResponse => { - if (aResponse.error) { - // Can't set the breakpoint if pausing failed. - aOnResponse(aResponse); - return aResponse; - } - - const { type, why } = aResponse; - const cleanUp = type == "paused" && why.type == "interrupted" - ? () => this._activeThread.resume() - : noop; - - return doSetBreakpoint(cleanUp); - }); - } -}; - -/** - * Breakpoint clients are used to remove breakpoints that are no longer used. - * - * @param aClient DebuggerClient - * The debugger client parent. - * @param aSourceClient SourceClient - * The source where this breakpoint exists - * @param aActor string - * The actor ID for this breakpoint. - * @param aLocation object - * The location of the breakpoint. This is an object with two properties: - * url and line. - * @param aCondition string - * The conditional expression of the breakpoint - */ -function BreakpointClient(aClient, aSourceClient, aActor, aLocation, aCondition) { - this._client = aClient; - this._actor = aActor; - this.location = aLocation; - this.location.actor = aSourceClient.actor; - this.location.url = aSourceClient.url; - this.source = aSourceClient; - this.request = this._client.request; - - // The condition property should only exist if it's a truthy value - if (aCondition) { - this.condition = aCondition; - } -} - -BreakpointClient.prototype = { - - _actor: null, - get actor() { return this._actor; }, - get _transport() { return this._client._transport; }, - - /** - * Remove the breakpoint from the server. - */ - remove: DebuggerClient.requester({ - type: "delete" - }, { - telemetry: "DELETE" - }), - - /** - * Determines if this breakpoint has a condition - */ - hasCondition: function() { - let root = this._client.mainRoot; - // XXX bug 990137: We will remove support for client-side handling of - // conditional breakpoints - if (root.traits.conditionalBreakpoints) { - return "condition" in this; - } else { - return "conditionalExpression" in this; - } - }, - - /** - * Get the condition of this breakpoint. Currently we have to - * support locally emulated conditional breakpoints until the - * debugger servers are updated (see bug 990137). We used a - * different property when moving it server-side to ensure that we - * are testing the right code. - */ - getCondition: function() { - let root = this._client.mainRoot; - if (root.traits.conditionalBreakpoints) { - return this.condition; - } else { - return this.conditionalExpression; - } - }, - - /** - * Set the condition of this breakpoint - */ - setCondition: function(gThreadClient, aCondition, noSliding) { - let root = this._client.mainRoot; - let deferred = promise.defer(); - - if (root.traits.conditionalBreakpoints) { - let info = { - line: this.location.line, - column: this.location.column, - condition: aCondition, - noSliding - }; - - // Remove the current breakpoint and add a new one with the - // condition. - this.remove(aResponse => { - if (aResponse && aResponse.error) { - deferred.reject(aResponse); - return; - } - - this.source.setBreakpoint(info, (aResponse, aNewBreakpoint) => { - if (aResponse && aResponse.error) { - deferred.reject(aResponse); - } else { - deferred.resolve(aNewBreakpoint); - } - }); - }); - } else { - // The property shouldn't even exist if the condition is blank - if (aCondition === "") { - delete this.conditionalExpression; - } - else { - this.conditionalExpression = aCondition; - } - deferred.resolve(this); - } - - return deferred.promise; - } -}; - -eventSource(BreakpointClient.prototype); - -/** - * Environment clients are used to manipulate the lexical environment actors. - * - * @param aClient DebuggerClient - * The debugger client parent. - * @param aForm Object - * The form sent across the remote debugging protocol. - */ -function EnvironmentClient(aClient, aForm) { - this._client = aClient; - this._form = aForm; - this.request = this._client.request; -} -exports.EnvironmentClient = EnvironmentClient; - -EnvironmentClient.prototype = { - - get actor() { - return this._form.actor; - }, - get _transport() { return this._client._transport; }, - - /** - * Fetches the bindings introduced by this lexical environment. - */ - getBindings: DebuggerClient.requester({ - type: "bindings" - }, { - telemetry: "BINDINGS" - }), - - /** - * Changes the value of the identifier whose name is name (a string) to that - * represented by value (a grip). - */ - assign: DebuggerClient.requester({ - type: "assign", - name: args(0), - value: args(1) - }, { - telemetry: "ASSIGN" - }) -}; - -eventSource(EnvironmentClient.prototype); diff --git a/packages/devtools-sham-modules/shared/event-emitter.js b/packages/devtools-sham-modules/shared/event-emitter.js deleted file mode 100644 index 24d5664d45..0000000000 --- a/packages/devtools-sham-modules/shared/event-emitter.js +++ /dev/null @@ -1,132 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/** - * EventEmitter. - */ - -var EventEmitter = function EventEmitter() {}; -module.exports = EventEmitter; - -const { Cu } = require("../sham/chrome"); -const promise = require("../sham/promise"); - -/** - * Decorate an object with event emitter functionality. - * - * @param Object aObjectToDecorate - * Bind all public methods of EventEmitter to - * the aObjectToDecorate object. - */ -EventEmitter.decorate = function EventEmitter_decorate (aObjectToDecorate) { - let emitter = new EventEmitter(); - aObjectToDecorate.on = emitter.on.bind(emitter); - aObjectToDecorate.off = emitter.off.bind(emitter); - aObjectToDecorate.once = emitter.once.bind(emitter); - aObjectToDecorate.emit = emitter.emit.bind(emitter); -}; - -EventEmitter.prototype = { - /** - * Connect a listener. - * - * @param string aEvent - * The event name to which we're connecting. - * @param function aListener - * Called when the event is fired. - */ - on: function EventEmitter_on(aEvent, aListener) { - if (!this._eventEmitterListeners) - this._eventEmitterListeners = new Map(); - if (!this._eventEmitterListeners.has(aEvent)) { - this._eventEmitterListeners.set(aEvent, []); - } - this._eventEmitterListeners.get(aEvent).push(aListener); - }, - - /** - * Listen for the next time an event is fired. - * - * @param string aEvent - * The event name to which we're connecting. - * @param function aListener - * (Optional) Called when the event is fired. Will be called at most - * one time. - * @return promise - * A promise which is resolved when the event next happens. The - * resolution value of the promise is the first event argument. If - * you need access to second or subsequent event arguments (it's rare - * that this is needed) then use aListener - */ - once: function EventEmitter_once(aEvent, aListener) { - let deferred = promise.defer(); - - let handler = (aEvent, aFirstArg, ...aRest) => { - this.off(aEvent, handler); - if (aListener) { - aListener.apply(null, [aEvent, aFirstArg, ...aRest]); - } - deferred.resolve(aFirstArg); - }; - - handler._originalListener = aListener; - this.on(aEvent, handler); - - return deferred.promise; - }, - - /** - * Remove a previously-registered event listener. Works for events - * registered with either on or once. - * - * @param string aEvent - * The event name whose listener we're disconnecting. - * @param function aListener - * The listener to remove. - */ - off: function EventEmitter_off(aEvent, aListener) { - if (!this._eventEmitterListeners) - return; - let listeners = this._eventEmitterListeners.get(aEvent); - if (listeners) { - this._eventEmitterListeners.set(aEvent, listeners.filter(l => { - return l !== aListener && l._originalListener !== aListener; - })); - } - }, - - /** - * Emit an event. All arguments to this method will - * be sent to listener functions. - */ - emit: function EventEmitter_emit(aEvent) { - if (!this._eventEmitterListeners || !this._eventEmitterListeners.has(aEvent)) { - return; - } - - let originalListeners = this._eventEmitterListeners.get(aEvent); - for (let listener of this._eventEmitterListeners.get(aEvent)) { - // If the object was destroyed during event emission, stop - // emitting. - if (!this._eventEmitterListeners) { - break; - } - - // If listeners were removed during emission, make sure the - // event handler we're going to fire wasn't removed. - if (originalListeners === this._eventEmitterListeners.get(aEvent) || - this._eventEmitterListeners.get(aEvent).some(l => l === listener)) { - try { - listener.apply(null, arguments); - } - catch (ex) { - // Prevent a bad listener from interfering with the others. - let msg = ex + ": " + ex.stack; - //console.error(msg); - console.log(msg); - } - } - } - }, -}; diff --git a/packages/devtools-sham-modules/shared/transport/packets.js b/packages/devtools-sham-modules/shared/transport/packets.js deleted file mode 100644 index 0130b3d8b2..0000000000 --- a/packages/devtools-sham-modules/shared/transport/packets.js +++ /dev/null @@ -1,418 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -/** - * Packets contain read / write functionality for the different packet types - * supported by the debugging protocol, so that a transport can focus on - * delivery and queue management without worrying too much about the specific - * packet types. - * - * They are intended to be "one use only", so a new packet should be - * instantiated for each incoming or outgoing packet. - * - * A complete Packet type should expose at least the following: - * * read(stream, scriptableStream) - * Called when the input stream has data to read - * * write(stream) - * Called when the output stream is ready to write - * * get done() - * Returns true once the packet is done being read / written - * * destroy() - * Called to clean up at the end of use - */ - -const { Cc, Ci, Cu } = require("../../sham/chrome"); -const DevToolsUtils = require("../DevToolsUtils"); -const { dumpn, dumpv } = DevToolsUtils; -const StreamUtils = require("../transport/stream-utils"); -const promise = require("../../sham/promise"); - -/*DevToolsUtils.defineLazyGetter(this, "unicodeConverter", () => { - const unicodeConverter = Cc("@mozilla.org/intl/scriptableunicodeconverter") - .createInstance(Ci.nsIScriptableUnicodeConverter); - unicodeConverter.charset = "UTF-8"; - return unicodeConverter; -});*/ -const utf8 = require("./utf8"); - -// The transport's previous check ensured the header length did not exceed 20 -// characters. Here, we opt for the somewhat smaller, but still large limit of -// 1 TiB. -const PACKET_LENGTH_MAX = Math.pow(2, 40); - -/** - * A generic Packet processing object (extended by two subtypes below). - */ -function Packet(transport) { - this._transport = transport; - this._length = 0; -} - -/** - * Attempt to initialize a new Packet based on the incoming packet header we've - * received so far. We try each of the types in succession, trying JSON packets - * first since they are much more common. - * @param header string - * The packet header string to attempt parsing. - * @param transport DebuggerTransport - * The transport instance that will own the packet. - * @return Packet - * The parsed packet of the matching type, or null if no types matched. - */ -Packet.fromHeader = function(header, transport) { - return JSONPacket.fromHeader(header, transport) || - BulkPacket.fromHeader(header, transport); -}; - -Packet.prototype = { - - get length() { - return this._length; - }, - - set length(length) { - if (length > PACKET_LENGTH_MAX) { - throw Error("Packet length " + length + " exceeds the max length of " + - PACKET_LENGTH_MAX); - } - this._length = length; - }, - - destroy: function() { - this._transport = null; - } - -}; - -exports.Packet = Packet; - -/** - * With a JSON packet (the typical packet type sent via the transport), data is - * transferred as a JSON packet serialized into a string, with the string length - * prepended to the packet, followed by a colon ([length]:[packet]). The - * contents of the JSON packet are specified in the Remote Debugging Protocol - * specification. - * @param transport DebuggerTransport - * The transport instance that will own the packet. - */ -function JSONPacket(transport) { - Packet.call(this, transport); - this._data = ""; - this._done = false; -} - -/** - * Attempt to initialize a new JSONPacket based on the incoming packet header - * we've received so far. - * @param header string - * The packet header string to attempt parsing. - * @param transport DebuggerTransport - * The transport instance that will own the packet. - * @return JSONPacket - * The parsed packet, or null if it's not a match. - */ -JSONPacket.fromHeader = function(header, transport) { - let match = this.HEADER_PATTERN.exec(header); - - if (!match) { - return null; - } - - dumpv("Header matches JSON packet"); - let packet = new JSONPacket(transport); - packet.length = +match[1]; - return packet; -}; - -JSONPacket.HEADER_PATTERN = /^(\d+):$/; - -JSONPacket.prototype = Object.create(Packet.prototype); - -Object.defineProperty(JSONPacket.prototype, "object", { - /** - * Gets the object (not the serialized string) being read or written. - */ - get: function() { return this._object; }, - - /** - * Sets the object to be sent when write() is called. - */ - set: function(object) { - this._object = object; - let data = JSON.stringify(object); - this._data = data; - this.length = this._data.length; - } -}); - -JSONPacket.prototype.read = function(stream, scriptableStream) { - dumpv("Reading JSON packet"); - - // Read in more packet data. - this._readData(stream, scriptableStream); - - if (!this.done) { - // Don't have a complete packet yet. - return; - } - - let json = this._data; - try { - json = utf8.decode(json); - this._object = JSON.parse(json); - } catch(e) { - let msg = "Error parsing incoming packet: " + json + " (" + e + - " - " + e.stack + ")"; - if (console.error) { - console.error(msg); - } - dumpn(msg); - return; - } - - this._transport._onJSONObjectReady(this._object); -} - -JSONPacket.prototype._readData = function(stream, scriptableStream) { - if (!scriptableStream) { - scriptableStream = stream; - } - if (dumpv.wantVerbose) { - dumpv("Reading JSON data: _l: " + this.length + " dL: " + - this._data.length + " sA: " + stream.available()); - } - let bytesToRead = Math.min(this.length - this._data.length, - stream.available()); - this._data += scriptableStream.readBytes(bytesToRead); - this._done = this._data.length === this.length; -} - -JSONPacket.prototype.write = function(stream) { - dumpv("Writing JSON packet"); - - if (this._outgoing === undefined) { - // Format the serialized packet to a buffer - this._outgoing = this.length + ":" + this._data; - } - - let written = stream.write(this._outgoing, this._outgoing.length); - this._outgoing = this._outgoing.slice(written); - this._done = !this._outgoing.length; -} - -Object.defineProperty(JSONPacket.prototype, "done", { - get: function() { return this._done; } -}); - -JSONPacket.prototype.toString = function() { - return JSON.stringify(this._object, null, 2); -} - -exports.JSONPacket = JSONPacket; - -/** - * With a bulk packet, data is transferred by temporarily handing over the - * transport's input or output stream to the application layer for writing data - * directly. This can be much faster for large data sets, and avoids various - * stages of copies and data duplication inherent in the JSON packet type. The - * bulk packet looks like: - * - * bulk [actor] [type] [length]:[data] - * - * The interpretation of the data portion depends on the kind of actor and the - * packet's type. See the Remote Debugging Protocol Stream Transport spec for - * more details. - * @param transport DebuggerTransport - * The transport instance that will own the packet. - */ -function BulkPacket(transport) { - Packet.call(this, transport); - this._done = false; - this._readyForWriting = promise.defer(); -} - -/** - * Attempt to initialize a new BulkPacket based on the incoming packet header - * we've received so far. - * @param header string - * The packet header string to attempt parsing. - * @param transport DebuggerTransport - * The transport instance that will own the packet. - * @return BulkPacket - * The parsed packet, or null if it's not a match. - */ -BulkPacket.fromHeader = function(header, transport) { - let match = this.HEADER_PATTERN.exec(header); - - if (!match) { - return null; - } - - dumpv("Header matches bulk packet"); - let packet = new BulkPacket(transport); - packet.header = { - actor: match[1], - type: match[2], - length: +match[3] - }; - return packet; -}; - -BulkPacket.HEADER_PATTERN = /^bulk ([^: ]+) ([^: ]+) (\d+):$/; - -BulkPacket.prototype = Object.create(Packet.prototype); - -BulkPacket.prototype.read = function(stream) { - dumpv("Reading bulk packet, handing off input stream"); - - // Temporarily pause monitoring of the input stream - this._transport.pauseIncoming(); - - let deferred = promise.defer(); - - this._transport._onBulkReadReady({ - actor: this.actor, - type: this.type, - length: this.length, - copyTo: (output) => { - dumpv("CT length: " + this.length); - let copying = StreamUtils.copyStream(stream, output, this.length); - deferred.resolve(copying); - return copying; - }, - stream: stream, - done: deferred - }); - - // Await the result of reading from the stream - deferred.promise.then(() => { - dumpv("onReadDone called, ending bulk mode"); - this._done = true; - this._transport.resumeIncoming(); - }, this._transport.close); - - // Ensure this is only done once - this.read = () => { - throw new Error("Tried to read() a BulkPacket's stream multiple times."); - }; -} - -BulkPacket.prototype.write = function(stream) { - dumpv("Writing bulk packet"); - - if (this._outgoingHeader === undefined) { - dumpv("Serializing bulk packet header"); - // Format the serialized packet header to a buffer - this._outgoingHeader = "bulk " + this.actor + " " + this.type + " " + - this.length + ":"; - } - - // Write the header, or whatever's left of it to write. - if (this._outgoingHeader.length) { - dumpv("Writing bulk packet header"); - let written = stream.write(this._outgoingHeader, - this._outgoingHeader.length); - this._outgoingHeader = this._outgoingHeader.slice(written); - return; - } - - dumpv("Handing off output stream"); - - // Temporarily pause the monitoring of the output stream - this._transport.pauseOutgoing(); - - let deferred = promise.defer(); - - this._readyForWriting.resolve({ - copyFrom: (input) => { - dumpv("CF length: " + this.length); - let copying = StreamUtils.copyStream(input, stream, this.length); - deferred.resolve(copying); - return copying; - }, - stream: stream, - done: deferred - }); - - // Await the result of writing to the stream - deferred.promise.then(() => { - dumpv("onWriteDone called, ending bulk mode"); - this._done = true; - this._transport.resumeOutgoing(); - }, this._transport.close); - - // Ensure this is only done once - this.write = () => { - throw new Error("Tried to write() a BulkPacket's stream multiple times."); - }; -} - -Object.defineProperty(BulkPacket.prototype, "streamReadyForWriting", { - get: function() { - return this._readyForWriting.promise; - } -}); - -Object.defineProperty(BulkPacket.prototype, "header", { - get: function() { - return { - actor: this.actor, - type: this.type, - length: this.length - }; - }, - - set: function(header) { - this.actor = header.actor; - this.type = header.type; - this.length = header.length; - }, -}); - -Object.defineProperty(BulkPacket.prototype, "done", { - get: function() { return this._done; }, -}); - - -BulkPacket.prototype.toString = function() { - return "Bulk: " + JSON.stringify(this.header, null, 2); -} - -exports.BulkPacket = BulkPacket; - -/** - * RawPacket is used to test the transport's error handling of malformed - * packets, by writing data directly onto the stream. - * @param transport DebuggerTransport - * The transport instance that will own the packet. - * @param data string - * The raw string to send out onto the stream. - */ -function RawPacket(transport, data) { - Packet.call(this, transport); - this._data = data; - this.length = data.length; - this._done = false; -} - -RawPacket.prototype = Object.create(Packet.prototype); - -RawPacket.prototype.read = function(stream) { - // This hasn't yet been needed for testing. - throw Error("Not implmented."); -} - -RawPacket.prototype.write = function(stream) { - let written = stream.write(this._data, this._data.length); - this._data = this._data.slice(written); - this._done = !this._data.length; -} - -Object.defineProperty(RawPacket.prototype, "done", { - get: function() { return this._done; } -}); - -exports.RawPacket = RawPacket; diff --git a/packages/devtools-sham-modules/shared/transport/stream-utils.js b/packages/devtools-sham-modules/shared/transport/stream-utils.js deleted file mode 100644 index 8de9035cfa..0000000000 --- a/packages/devtools-sham-modules/shared/transport/stream-utils.js +++ /dev/null @@ -1,241 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -const { Ci, Cc, Cr, CC } = require("../../sham/chrome"); -const { Services } = require("devtools-modules"); -const { dumpv } = require("../DevToolsUtils"); -const EventEmitter = require("../event-emitter"); -const promise = require("../../sham/promise"); - -const IOUtil = Cc("@mozilla.org/io-util;1").getService(Ci.nsIIOUtil); - -const ScriptableInputStream = CC("@mozilla.org/scriptableinputstream;1", - "nsIScriptableInputStream", "init"); - -const BUFFER_SIZE = 0x8000; - -/** - * This helper function (and its companion object) are used by bulk senders and - * receivers to read and write data in and out of other streams. Functions that - * make use of this tool are passed to callers when it is time to read or write - * bulk data. It is highly recommended to use these copier functions instead of - * the stream directly because the copier enforces the agreed upon length. - * Since bulk mode reuses an existing stream, the sender and receiver must write - * and read exactly the agreed upon amount of data, or else the entire transport - * will be left in a invalid state. Additionally, other methods of stream - * copying (such as NetUtil.asyncCopy) close the streams involved, which would - * terminate the debugging transport, and so it is avoided here. - * - * Overall, this *works*, but clearly the optimal solution would be able to just - * use the streams directly. If it were possible to fully implement - * nsIInputStream / nsIOutputStream in JS, wrapper streams could be created to - * enforce the length and avoid closing, and consumers could use familiar stream - * utilities like NetUtil.asyncCopy. - * - * The function takes two async streams and copies a precise number of bytes - * from one to the other. Copying begins immediately, but may complete at some - * future time depending on data size. Use the returned promise to know when - * it's complete. - * - * @param input nsIAsyncInputStream - * The stream to copy from. - * @param output nsIAsyncOutputStream - * The stream to copy to. - * @param length Integer - * The amount of data that needs to be copied. - * @return Promise - * The promise is resolved when copying completes or rejected if any - * (unexpected) errors occur. - */ -function copyStream(input, output, length) { - let copier = new StreamCopier(input, output, length); - return copier.copy(); -} - -function StreamCopier(input, output, length) { - EventEmitter.decorate(this); - this._id = StreamCopier._nextId++; - this.input = input; - // Save off the base output stream, since we know it's async as we've required - this.baseAsyncOutput = output; - if (IOUtil.outputStreamIsBuffered(output)) { - this.output = output; - } else { - this.output = Cc("@mozilla.org/network/buffered-output-stream;1") - .createInstance(Ci.nsIBufferedOutputStream); - this.output.init(output, BUFFER_SIZE); - } - this._length = length; - this._amountLeft = length; - this._deferred = promise.defer(); - - this._copy = this._copy.bind(this); - this._flush = this._flush.bind(this); - this._destroy = this._destroy.bind(this); - - // Copy promise's then method up to this object. - // Allows the copier to offer a promise interface for the simple succeed or - // fail scenarios, but also emit events (due to the EventEmitter) for other - // states, like progress. - this.then = this._deferred.promise.then.bind(this._deferred.promise); - this.then(this._destroy, this._destroy); - - // Stream ready callback starts as |_copy|, but may switch to |_flush| at end - // if flushing would block the output stream. - this._streamReadyCallback = this._copy; -} -StreamCopier._nextId = 0; - -StreamCopier.prototype = { - - copy: function() { - // Dispatch to the next tick so that it's possible to attach a progress - // event listener, even for extremely fast copies (like when testing). - Services.tm.currentThread.dispatch(() => { - try { - this._copy(); - } catch (e) { - this._deferred.reject(e); - } - }, 0); - return this; - }, - - _copy: function() { - let bytesAvailable = this.input.available(); - let amountToCopy = Math.min(bytesAvailable, this._amountLeft); - this._debug("Trying to copy: " + amountToCopy); - - let bytesCopied; - try { - bytesCopied = this.output.writeFrom(this.input, amountToCopy); - } catch (e) { - if (e.result == Cr.NS_BASE_STREAM_WOULD_BLOCK) { - this._debug("Base stream would block, will retry"); - this._debug("Waiting for output stream"); - this.baseAsyncOutput.asyncWait(this, 0, 0, Services.tm.currentThread); - return; - } else { - throw e; - } - } - - this._amountLeft -= bytesCopied; - this._debug("Copied: " + bytesCopied + - ", Left: " + this._amountLeft); - this._emitProgress(); - - if (this._amountLeft === 0) { - this._debug("Copy done!"); - this._flush(); - return; - } - - this._debug("Waiting for input stream"); - this.input.asyncWait(this, 0, 0, Services.tm.currentThread); - }, - - _emitProgress: function() { - this.emit("progress", { - bytesSent: this._length - this._amountLeft, - totalBytes: this._length - }); - }, - - _flush: function() { - try { - this.output.flush(); - } catch (e) { - if (e.result == Cr.NS_BASE_STREAM_WOULD_BLOCK || - e.result == Cr.NS_ERROR_FAILURE) { - this._debug("Flush would block, will retry"); - this._streamReadyCallback = this._flush; - this._debug("Waiting for output stream"); - this.baseAsyncOutput.asyncWait(this, 0, 0, Services.tm.currentThread); - return; - } else { - throw e; - } - } - this._deferred.resolve(); - }, - - _destroy: function() { - this._destroy = null; - this._copy = null; - this._flush = null; - this.input = null; - this.output = null; - }, - - // nsIInputStreamCallback - onInputStreamReady: function() { - this._streamReadyCallback(); - }, - - // nsIOutputStreamCallback - onOutputStreamReady: function() { - this._streamReadyCallback(); - }, - - _debug: function(msg) { - // Prefix logs with the copier ID, which makes logs much easier to - // understand when several copiers are running simultaneously - dumpv("Copier: " + this._id + " " + msg); - } - -}; - -/** - * Read from a stream, one byte at a time, up to the next |delimiter| - * character, but stopping if we've read |count| without finding it. Reading - * also terminates early if there are less than |count| bytes available on the - * stream. In that case, we only read as many bytes as the stream currently has - * to offer. - * TODO: This implementation could be removed if bug 984651 is fixed, which - * provides a native version of the same idea. - * @param stream nsIInputStream - * The input stream to read from. - * @param delimiter string - * The character we're trying to find. - * @param count integer - * The max number of characters to read while searching. - * @return string - * The data collected. If the delimiter was found, this string will - * end with it. - */ -function delimitedRead(stream, delimiter, count) { - dumpv("Starting delimited read for " + delimiter + " up to " + - count + " bytes"); - - let scriptableStream; - if (stream.readBytes) { - scriptableStream = stream; - } else { - scriptableStream = new ScriptableInputStream(stream); - } - - let data = ""; - - // Don't exceed what's available on the stream - count = Math.min(count, stream.available()); - - if (count <= 0) { - return data; - } - - let char; - while (char !== delimiter && count > 0) { - char = scriptableStream.readBytes(1); - count--; - data += char; - } - - return data; -} - -module.exports = { - copyStream: copyStream, - delimitedRead: delimitedRead -}; diff --git a/packages/devtools-sham-modules/shared/transport/utf8.js b/packages/devtools-sham-modules/shared/transport/utf8.js deleted file mode 100644 index c138a38ef5..0000000000 --- a/packages/devtools-sham-modules/shared/transport/utf8.js +++ /dev/null @@ -1,244 +0,0 @@ -/*! https://mths.be/utf8js v2.0.0 by @mathias */ -;(function(root) { - - // Detect free variables `exports` - var freeExports = typeof exports == 'object' && exports; - - // Detect free variable `module` - var freeModule = typeof module == 'object' && module && - module.exports == freeExports && module; - - // Detect free variable `global`, from Node.js or Browserified code, - // and use it as `root` - var freeGlobal = typeof global == 'object' && global; - if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) { - root = freeGlobal; - } - - /*--------------------------------------------------------------------------*/ - - var stringFromCharCode = String.fromCharCode; - - // Taken from https://mths.be/punycode - function ucs2decode(string) { - var output = []; - var counter = 0; - var length = string.length; - var value; - var extra; - while (counter < length) { - value = string.charCodeAt(counter++); - if (value >= 0xD800 && value <= 0xDBFF && counter < length) { - // high surrogate, and there is a next character - extra = string.charCodeAt(counter++); - if ((extra & 0xFC00) == 0xDC00) { // low surrogate - output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000); - } else { - // unmatched surrogate; only append this code unit, in case the next - // code unit is the high surrogate of a surrogate pair - output.push(value); - counter--; - } - } else { - output.push(value); - } - } - return output; - } - - // Taken from https://mths.be/punycode - function ucs2encode(array) { - var length = array.length; - var index = -1; - var value; - var output = ''; - while (++index < length) { - value = array[index]; - if (value > 0xFFFF) { - value -= 0x10000; - output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800); - value = 0xDC00 | value & 0x3FF; - } - output += stringFromCharCode(value); - } - return output; - } - - function checkScalarValue(codePoint) { - if (codePoint >= 0xD800 && codePoint <= 0xDFFF) { - throw Error( - 'Lone surrogate U+' + codePoint.toString(16).toUpperCase() + - ' is not a scalar value' - ); - } - } - /*--------------------------------------------------------------------------*/ - - function createByte(codePoint, shift) { - return stringFromCharCode(((codePoint >> shift) & 0x3F) | 0x80); - } - - function encodeCodePoint(codePoint) { - if ((codePoint & 0xFFFFFF80) == 0) { // 1-byte sequence - return stringFromCharCode(codePoint); - } - var symbol = ''; - if ((codePoint & 0xFFFFF800) == 0) { // 2-byte sequence - symbol = stringFromCharCode(((codePoint >> 6) & 0x1F) | 0xC0); - } - else if ((codePoint & 0xFFFF0000) == 0) { // 3-byte sequence - checkScalarValue(codePoint); - symbol = stringFromCharCode(((codePoint >> 12) & 0x0F) | 0xE0); - symbol += createByte(codePoint, 6); - } - else if ((codePoint & 0xFFE00000) == 0) { // 4-byte sequence - symbol = stringFromCharCode(((codePoint >> 18) & 0x07) | 0xF0); - symbol += createByte(codePoint, 12); - symbol += createByte(codePoint, 6); - } - symbol += stringFromCharCode((codePoint & 0x3F) | 0x80); - return symbol; - } - - function utf8encode(string) { - var codePoints = ucs2decode(string); - var length = codePoints.length; - var index = -1; - var codePoint; - var byteString = ''; - while (++index < length) { - codePoint = codePoints[index]; - byteString += encodeCodePoint(codePoint); - } - return byteString; - } - - /*--------------------------------------------------------------------------*/ - - function readContinuationByte() { - if (byteIndex >= byteCount) { - throw Error('Invalid byte index'); - } - - var continuationByte = byteArray[byteIndex] & 0xFF; - byteIndex++; - - if ((continuationByte & 0xC0) == 0x80) { - return continuationByte & 0x3F; - } - - // If we end up here, it’s not a continuation byte - throw Error('Invalid continuation byte'); - } - - function decodeSymbol() { - var byte1; - var byte2; - var byte3; - var byte4; - var codePoint; - - if (byteIndex > byteCount) { - throw Error('Invalid byte index'); - } - - if (byteIndex == byteCount) { - return false; - } - - // Read first byte - byte1 = byteArray[byteIndex] & 0xFF; - byteIndex++; - - // 1-byte sequence (no continuation bytes) - if ((byte1 & 0x80) == 0) { - return byte1; - } - - // 2-byte sequence - if ((byte1 & 0xE0) == 0xC0) { - var byte2 = readContinuationByte(); - codePoint = ((byte1 & 0x1F) << 6) | byte2; - if (codePoint >= 0x80) { - return codePoint; - } else { - throw Error('Invalid continuation byte'); - } - } - - // 3-byte sequence (may include unpaired surrogates) - if ((byte1 & 0xF0) == 0xE0) { - byte2 = readContinuationByte(); - byte3 = readContinuationByte(); - codePoint = ((byte1 & 0x0F) << 12) | (byte2 << 6) | byte3; - if (codePoint >= 0x0800) { - checkScalarValue(codePoint); - return codePoint; - } else { - throw Error('Invalid continuation byte'); - } - } - - // 4-byte sequence - if ((byte1 & 0xF8) == 0xF0) { - byte2 = readContinuationByte(); - byte3 = readContinuationByte(); - byte4 = readContinuationByte(); - codePoint = ((byte1 & 0x0F) << 0x12) | (byte2 << 0x0C) | - (byte3 << 0x06) | byte4; - if (codePoint >= 0x010000 && codePoint <= 0x10FFFF) { - return codePoint; - } - } - - throw Error('Invalid UTF-8 detected'); - } - - var byteArray; - var byteCount; - var byteIndex; - function utf8decode(byteString) { - byteArray = ucs2decode(byteString); - byteCount = byteArray.length; - byteIndex = 0; - var codePoints = []; - var tmp; - while ((tmp = decodeSymbol()) !== false) { - codePoints.push(tmp); - } - return ucs2encode(codePoints); - } - - /*--------------------------------------------------------------------------*/ - - var utf8 = { - 'version': '2.0.0', - 'encode': utf8encode, - 'decode': utf8decode - }; - - // Some AMD build optimizers, like r.js, check for specific condition patterns - // like the following: - if ( - typeof define == 'function' && - typeof define.amd == 'object' && - define.amd - ) { - define(function() { - return utf8; - }); - } else if (freeExports && !freeExports.nodeType) { - if (freeModule) { // in Node.js or RingoJS v0.8.0+ - freeModule.exports = utf8; - } else { // in Narwhal or RingoJS v0.7.0- - var object = {}; - var hasOwnProperty = object.hasOwnProperty; - for (var key in utf8) { - hasOwnProperty.call(utf8, key) && (freeExports[key] = utf8[key]); - } - } - } else { // in Rhino or a web browser - root.utf8 = utf8; - } - -}(this)); diff --git a/packages/devtools-sham-modules/shared/transport/websocket-transport.js b/packages/devtools-sham-modules/shared/transport/websocket-transport.js deleted file mode 100644 index 02b46d07aa..0000000000 --- a/packages/devtools-sham-modules/shared/transport/websocket-transport.js +++ /dev/null @@ -1,79 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -const EventEmitter = require("../event-emitter"); - -function WebSocketDebuggerTransport(socket) { - EventEmitter.decorate(this); - - this.active = false; - this.hooks = null; - this.socket = socket; -} - -WebSocketDebuggerTransport.prototype = { - ready() { - if (this.active) { - return; - } - - this.socket.addEventListener("message", this); - this.socket.addEventListener("close", this); - - this.active = true; - }, - - send(object) { - this.emit("send", object); - if (this.socket) { - this.socket.send(JSON.stringify(object)); - } - }, - - startBulkSend() { - throw new Error("Bulk send is not supported by WebSocket transport"); - }, - - close() { - this.emit("close"); - this.active = false; - - this.socket.removeEventListener("message", this); - this.socket.removeEventListener("close", this); - this.socket.close(); - this.socket = null; - - if (this.hooks) { - this.hooks.onClosed(); - this.hooks = null; - } - }, - - handleEvent(event) { - switch (event.type) { - case "message": - this.onMessage(event); - break; - case "close": - this.close(); - break; - } - }, - - onMessage({ data }) { - if (typeof data !== "string") { - throw new Error("Binary messages are not supported by WebSocket transport"); - } - - let object = JSON.parse(data); - this.emit("packet", object); - if (this.hooks) { - this.hooks.onPacket(object); - } - }, -}; - -module.exports = WebSocketDebuggerTransport; diff --git a/packages/devtools-sham-modules/shared/webconsole/client.js b/packages/devtools-sham-modules/shared/webconsole/client.js deleted file mode 100644 index cf173aee0d..0000000000 --- a/packages/devtools-sham-modules/shared/webconsole/client.js +++ /dev/null @@ -1,667 +0,0 @@ -/* -*- js-indent-level: 2; indent-tabs-mode: nil -*- */ -/* vim: set ts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -const {Cc, Ci, Cu} = require("../../sham/chrome"); -const DevToolsUtils = require("../DevToolsUtils"); -const EventEmitter = require("../event-emitter"); -const promise = require("../../sham/promise"); -const {LongStringClient} = require("../client/main"); - -/** - * A WebConsoleClient is used as a front end for the WebConsoleActor that is - * created on the server, hiding implementation details. - * - * @param object aDebuggerClient - * The DebuggerClient instance we live for. - * @param object aResponse - * The response packet received from the "startListeners" request sent to - * the WebConsoleActor. - */ -function WebConsoleClient(aDebuggerClient, aResponse) -{ - this._actor = aResponse.from; - this._client = aDebuggerClient; - this._longStrings = {}; - this.traits = aResponse.traits || {}; - this.events = []; - this._networkRequests = new Map(); - - this.pendingEvaluationResults = new Map(); - this.onEvaluationResult = this.onEvaluationResult.bind(this); - this.onNetworkEvent = this._onNetworkEvent.bind(this); - this.onNetworkEventUpdate = this._onNetworkEventUpdate.bind(this); - - this._client.addListener("evaluationResult", this.onEvaluationResult); - this._client.addListener("networkEvent", this.onNetworkEvent); - this._client.addListener("networkEventUpdate", this.onNetworkEventUpdate); - EventEmitter.decorate(this); -} - -exports.WebConsoleClient = WebConsoleClient; - -WebConsoleClient.prototype = { - _longStrings: null, - traits: null, - - /** - * Holds the network requests currently displayed by the Web Console. Each key - * represents the connection ID and the value is network request information. - * @private - * @type object - */ - _networkRequests: null, - - getNetworkRequest(actorId) { - return this._networkRequests.get(actorId); - }, - - hasNetworkRequest(actorId) { - return this._networkRequests.has(actorId); - }, - - removeNetworkRequest(actorId) { - this._networkRequests.delete(actorId); - }, - - getNetworkEvents() { - return this._networkRequests.values(); - }, - - get actor() { return this._actor; }, - - /** - * The "networkEvent" message type handler. We redirect any message to - * the UI for displaying. - * - * @private - * @param string type - * Message type. - * @param object packet - * The message received from the server. - */ - _onNetworkEvent: function (type, packet) - { - if (packet.from == this._actor) { - let actor = packet.eventActor; - let networkInfo = { - _type: "NetworkEvent", - timeStamp: actor.timeStamp, - node: null, - actor: actor.actor, - discardRequestBody: true, - discardResponseBody: true, - startedDateTime: actor.startedDateTime, - request: { - url: actor.url, - method: actor.method, - }, - isXHR: actor.isXHR, - response: {}, - timings: {}, - updates: [], // track the list of network event updates - private: actor.private, - fromCache: actor.fromCache - }; - this._networkRequests.set(actor.actor, networkInfo); - - this.emit("networkEvent", networkInfo); - } - }, - - /** - * The "networkEventUpdate" message type handler. We redirect any message to - * the UI for displaying. - * - * @private - * @param string type - * Message type. - * @param object packet - * The message received from the server. - */ - _onNetworkEventUpdate: function (type, packet) - { - let networkInfo = this.getNetworkRequest(packet.from); - if (!networkInfo) { - return; - } - - networkInfo.updates.push(packet.updateType); - - switch (packet.updateType) { - case "requestHeaders": - networkInfo.request.headersSize = packet.headersSize; - break; - case "requestPostData": - networkInfo.discardRequestBody = packet.discardRequestBody; - networkInfo.request.bodySize = packet.dataSize; - break; - case "responseStart": - networkInfo.response.httpVersion = packet.response.httpVersion; - networkInfo.response.status = packet.response.status; - networkInfo.response.statusText = packet.response.statusText; - networkInfo.response.headersSize = packet.response.headersSize; - networkInfo.response.remoteAddress = packet.response.remoteAddress; - networkInfo.response.remotePort = packet.response.remotePort; - networkInfo.discardResponseBody = packet.response.discardResponseBody; - break; - case "responseContent": - networkInfo.response.content = { - mimeType: packet.mimeType, - }; - networkInfo.response.bodySize = packet.contentSize; - networkInfo.response.transferredSize = packet.transferredSize; - networkInfo.discardResponseBody = packet.discardResponseBody; - break; - case "eventTimings": - networkInfo.totalTime = packet.totalTime; - break; - case "securityInfo": - networkInfo.securityInfo = packet.state; - break; - } - - this.emit("networkEventUpdate", { - packet: packet, - networkInfo - }); - }, - - /** - * Retrieve the cached messages from the server. - * - * @see this.CACHED_MESSAGES - * @param array types - * The array of message types you want from the server. See - * this.CACHED_MESSAGES for known types. - * @param function aOnResponse - * The function invoked when the response is received. - */ - getCachedMessages: function WCC_getCachedMessages(types, aOnResponse) - { - let packet = { - to: this._actor, - type: "getCachedMessages", - messageTypes: types, - }; - this._client.request(packet, aOnResponse); - }, - - /** - * Inspect the properties of an object. - * - * @param string aActor - * The WebConsoleObjectActor ID to send the request to. - * @param function aOnResponse - * The function invoked when the response is received. - */ - inspectObjectProperties: - function WCC_inspectObjectProperties(aActor, aOnResponse) - { - let packet = { - to: aActor, - type: "inspectProperties", - }; - this._client.request(packet, aOnResponse); - }, - - /** - * Evaluate a JavaScript expression. - * - * @param string aString - * The code you want to evaluate. - * @param function aOnResponse - * The function invoked when the response is received. - * @param object [aOptions={}] - * Options for evaluation: - * - * - bindObjectActor: an ObjectActor ID. The OA holds a reference to - * a Debugger.Object that wraps a content object. This option allows - * you to bind |_self| to the D.O of the given OA, during string - * evaluation. - * - * See: Debugger.Object.executeInGlobalWithBindings() for information - * about bindings. - * - * Use case: the variable view needs to update objects and it does so - * by knowing the ObjectActor it inspects and binding |_self| to the - * D.O of the OA. As such, variable view sends strings like these for - * eval: - * _self["prop"] = value; - * - * - frameActor: a FrameActor ID. The FA holds a reference to - * a Debugger.Frame. This option allows you to evaluate the string in - * the frame of the given FA. - * - * - url: the url to evaluate the script as. Defaults to - * "debugger eval code". - * - * - selectedNodeActor: the NodeActor ID of the current selection in the - * Inspector, if such a selection exists. This is used by helper functions - * that can reference the currently selected node in the Inspector, like - * $0. - */ - evaluateJS: function WCC_evaluateJS(aString, aOnResponse, aOptions = {}) - { - let packet = { - to: this._actor, - type: "evaluateJS", - text: aString, - bindObjectActor: aOptions.bindObjectActor, - frameActor: aOptions.frameActor, - url: aOptions.url, - selectedNodeActor: aOptions.selectedNodeActor, - selectedObjectActor: aOptions.selectedObjectActor, - }; - this._client.request(packet, aOnResponse); - }, - - /** - * Evaluate a JavaScript expression asynchronously. - * See evaluateJS for parameter and response information. - */ - evaluateJSAsync: function(aString, aOnResponse, aOptions = {}) - { - // Pre-37 servers don't support async evaluation. - if (!this.traits.evaluateJSAsync) { - this.evaluateJS(aString, aOnResponse, aOptions); - return; - } - - let packet = { - to: this._actor, - type: "evaluateJSAsync", - text: aString, - bindObjectActor: aOptions.bindObjectActor, - frameActor: aOptions.frameActor, - url: aOptions.url, - selectedNodeActor: aOptions.selectedNodeActor, - selectedObjectActor: aOptions.selectedObjectActor, - }; - - this._client.request(packet, response => { - // Null check this in case the client has been detached while waiting - // for a response. - if (this.pendingEvaluationResults) { - this.pendingEvaluationResults.set(response.resultID, aOnResponse); - } - }); - }, - - /** - * Handler for the actors's unsolicited evaluationResult packet. - */ - onEvaluationResult: function(aNotification, aPacket) { - // The client on the main thread can receive notification packets from - // multiple webconsole actors: the one on the main thread and the ones - // on worker threads. So make sure we should be handling this request. - if (aPacket.from !== this._actor) { - return; - } - - // Find the associated callback based on this ID, and fire it. - // In a sync evaluation, this would have already been called in - // direct response to the client.request function. - let onResponse = this.pendingEvaluationResults.get(aPacket.resultID); - if (onResponse) { - onResponse(aPacket); - this.pendingEvaluationResults.delete(aPacket.resultID); - } else { - DevToolsUtils.reportException("onEvaluationResult", - "No response handler for an evaluateJSAsync result (resultID: " + aPacket.resultID + ")"); - } - }, - - /** - * Autocomplete a JavaScript expression. - * - * @param string aString - * The code you want to autocomplete. - * @param number aCursor - * Cursor location inside the string. Index starts from 0. - * @param function aOnResponse - * The function invoked when the response is received. - * @param string aFrameActor - * The id of the frame actor that made the call. - */ - autocomplete: function WCC_autocomplete(aString, aCursor, aOnResponse, aFrameActor) - { - let packet = { - to: this._actor, - type: "autocomplete", - text: aString, - cursor: aCursor, - frameActor: aFrameActor, - }; - this._client.request(packet, aOnResponse); - }, - - /** - * Clear the cache of messages (page errors and console API calls). - */ - clearMessagesCache: function WCC_clearMessagesCache() - { - let packet = { - to: this._actor, - type: "clearMessagesCache", - }; - this._client.request(packet); - }, - - /** - * Get Web Console-related preferences on the server. - * - * @param array aPreferences - * An array with the preferences you want to retrieve. - * @param function [aOnResponse] - * Optional function to invoke when the response is received. - */ - getPreferences: function WCC_getPreferences(aPreferences, aOnResponse) - { - let packet = { - to: this._actor, - type: "getPreferences", - preferences: aPreferences, - }; - this._client.request(packet, aOnResponse); - }, - - /** - * Set Web Console-related preferences on the server. - * - * @param object aPreferences - * An object with the preferences you want to change. - * @param function [aOnResponse] - * Optional function to invoke when the response is received. - */ - setPreferences: function WCC_setPreferences(aPreferences, aOnResponse) - { - let packet = { - to: this._actor, - type: "setPreferences", - preferences: aPreferences, - }; - this._client.request(packet, aOnResponse); - }, - - /** - * Retrieve the request headers from the given NetworkEventActor. - * - * @param string aActor - * The NetworkEventActor ID. - * @param function aOnResponse - * The function invoked when the response is received. - */ - getRequestHeaders: function WCC_getRequestHeaders(aActor, aOnResponse) - { - let packet = { - to: aActor, - type: "getRequestHeaders", - }; - this._client.request(packet, aOnResponse); - }, - - /** - * Retrieve the request cookies from the given NetworkEventActor. - * - * @param string aActor - * The NetworkEventActor ID. - * @param function aOnResponse - * The function invoked when the response is received. - */ - getRequestCookies: function WCC_getRequestCookies(aActor, aOnResponse) - { - let packet = { - to: aActor, - type: "getRequestCookies", - }; - this._client.request(packet, aOnResponse); - }, - - /** - * Retrieve the request post data from the given NetworkEventActor. - * - * @param string aActor - * The NetworkEventActor ID. - * @param function aOnResponse - * The function invoked when the response is received. - */ - getRequestPostData: function WCC_getRequestPostData(aActor, aOnResponse) - { - let packet = { - to: aActor, - type: "getRequestPostData", - }; - this._client.request(packet, aOnResponse); - }, - - /** - * Retrieve the response headers from the given NetworkEventActor. - * - * @param string aActor - * The NetworkEventActor ID. - * @param function aOnResponse - * The function invoked when the response is received. - */ - getResponseHeaders: function WCC_getResponseHeaders(aActor, aOnResponse) - { - let packet = { - to: aActor, - type: "getResponseHeaders", - }; - this._client.request(packet, aOnResponse); - }, - - /** - * Retrieve the response cookies from the given NetworkEventActor. - * - * @param string aActor - * The NetworkEventActor ID. - * @param function aOnResponse - * The function invoked when the response is received. - */ - getResponseCookies: function WCC_getResponseCookies(aActor, aOnResponse) - { - let packet = { - to: aActor, - type: "getResponseCookies", - }; - this._client.request(packet, aOnResponse); - }, - - /** - * Retrieve the response content from the given NetworkEventActor. - * - * @param string aActor - * The NetworkEventActor ID. - * @param function aOnResponse - * The function invoked when the response is received. - */ - getResponseContent: function WCC_getResponseContent(aActor, aOnResponse) - { - let packet = { - to: aActor, - type: "getResponseContent", - }; - this._client.request(packet, aOnResponse); - }, - - /** - * Retrieve the timing information for the given NetworkEventActor. - * - * @param string aActor - * The NetworkEventActor ID. - * @param function aOnResponse - * The function invoked when the response is received. - */ - getEventTimings: function WCC_getEventTimings(aActor, aOnResponse) - { - let packet = { - to: aActor, - type: "getEventTimings", - }; - this._client.request(packet, aOnResponse); - }, - - /** - * Retrieve the security information for the given NetworkEventActor. - * - * @param string aActor - * The NetworkEventActor ID. - * @param function aOnResponse - * The function invoked when the response is received. - */ - getSecurityInfo: function WCC_getSecurityInfo(aActor, aOnResponse) - { - let packet = { - to: aActor, - type: "getSecurityInfo", - }; - this._client.request(packet, aOnResponse); - }, - - /** - * Send a HTTP request with the given data. - * - * @param string aData - * The details of the HTTP request. - * @param function aOnResponse - * The function invoked when the response is received. - */ - sendHTTPRequest: function WCC_sendHTTPRequest(aData, aOnResponse) { - let packet = { - to: this._actor, - type: "sendHTTPRequest", - request: aData - }; - this._client.request(packet, aOnResponse); - }, - - /** - * Start the given Web Console listeners. - * - * @see this.LISTENERS - * @param array aListeners - * Array of listeners you want to start. See this.LISTENERS for - * known listeners. - * @param function aOnResponse - * Function to invoke when the server response is received. - */ - startListeners: function WCC_startListeners(aListeners, aOnResponse) - { - let packet = { - to: this._actor, - type: "startListeners", - listeners: aListeners, - }; - this._client.request(packet, aOnResponse); - }, - - /** - * Stop the given Web Console listeners. - * - * @see this.LISTENERS - * @param array aListeners - * Array of listeners you want to stop. See this.LISTENERS for - * known listeners. - * @param function aOnResponse - * Function to invoke when the server response is received. - */ - stopListeners: function WCC_stopListeners(aListeners, aOnResponse) - { - let packet = { - to: this._actor, - type: "stopListeners", - listeners: aListeners, - }; - this._client.request(packet, aOnResponse); - }, - - /** - * Return an instance of LongStringClient for the given long string grip. - * - * @param object aGrip - * The long string grip returned by the protocol. - * @return object - * The LongStringClient for the given long string grip. - */ - longString: function WCC_longString(aGrip) - { - if (aGrip.actor in this._longStrings) { - return this._longStrings[aGrip.actor]; - } - - let client = new LongStringClient(this._client, aGrip); - this._longStrings[aGrip.actor] = client; - return client; - }, - - /** - * Close the WebConsoleClient. This stops all the listeners on the server and - * detaches from the console actor. - * - * @param function aOnResponse - * Function to invoke when the server response is received. - */ - detach: function WCC_detach(aOnResponse) - { - this._client.removeListener("evaluationResult", this.onEvaluationResult); - this._client.removeListener("networkEvent", this.onNetworkEvent); - this._client.removeListener("networkEventUpdate", this.onNetworkEventUpdate); - this.stopListeners(null, aOnResponse); - this._longStrings = null; - this._client = null; - this.pendingEvaluationResults.clear(); - this.pendingEvaluationResults = null; - this.clearNetworkRequests(); - this._networkRequests = null; - }, - - clearNetworkRequests: function () { - this._networkRequests.clear(); - }, - - /** - * Fetches the full text of a LongString. - * - * @param object | string stringGrip - * The long string grip containing the corresponding actor. - * If you pass in a plain string (by accident or because you're lazy), - * then a promise of the same string is simply returned. - * @return object Promise - * A promise that is resolved when the full string contents - * are available, or rejected if something goes wrong. - */ - getString: function(stringGrip) { - // Make sure this is a long string. - if (typeof stringGrip != "object" || stringGrip.type != "longString") { - return promise.resolve(stringGrip); // Go home string, you're drunk. - } - - // Fetch the long string only once. - if (stringGrip._fullText) { - return stringGrip._fullText.promise; - } - - let deferred = stringGrip._fullText = promise.defer(); - let { actor, initial, length } = stringGrip; - let longStringClient = this.longString(stringGrip); - - longStringClient.substring(initial.length, length, aResponse => { - if (aResponse.error) { - DevToolsUtils.reportException("getString", - aResponse.error + ": " + aResponse.message); - - deferred.reject(aResponse); - return; - } - deferred.resolve(initial + aResponse.substring); - }); - - return deferred.promise; - } -}; diff --git a/packages/devtools-sham-modules/shared/webconsole/network-helper.js b/packages/devtools-sham-modules/shared/webconsole/network-helper.js deleted file mode 100644 index 8746ec259c..0000000000 --- a/packages/devtools-sham-modules/shared/webconsole/network-helper.js +++ /dev/null @@ -1,811 +0,0 @@ -/* vim:set ts=2 sw=2 sts=2 et: */ -/* - * Software License Agreement (BSD License) - * - * Copyright (c) 2007, Parakey Inc. - * All rights reserved. - * - * Redistribution and use of this software 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 of Parakey Inc. nor the names of its - * contributors may be used to endorse or promote products - * derived from this software without specific prior - * written permission of Parakey Inc. - * - * 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 OWNER 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. - */ - -/* - * Creator: - * Joe Hewitt - * Contributors - * John J. Barton (IBM Almaden) - * Jan Odvarko (Mozilla Corp.) - * Max Stepanov (Aptana Inc.) - * Rob Campbell (Mozilla Corp.) - * Hans Hillen (Paciello Group, Mozilla) - * Curtis Bartley (Mozilla Corp.) - * Mike Collins (IBM Almaden) - * Kevin Decker - * Mike Ratcliffe (Comartis AG) - * Hernan Rodríguez Colmeiro - * Austin Andrews - * Christoph Dorn - * Steven Roussey (AppCenter Inc, Network54) - * Mihai Sucan (Mozilla Corp.) - */ - -"use strict"; - -const {components, Cc, Ci, Cu} = require("../../sham/chrome"); -const { NetUtil } = require("../../sham/netutil"); -const DevToolsUtils = require("../DevToolsUtils"); - -// The cache used in the `nsIURL` function. -const gNSURLStore = new Map(); - -/** - * Helper object for networking stuff. - * - * Most of the following functions have been taken from the Firebug source. They - * have been modified to match the Firefox coding rules. - */ -var NetworkHelper = { - /** - * Converts aText with a given aCharset to unicode. - * - * @param string aText - * Text to convert. - * @param string aCharset - * Charset to convert the text to. - * @returns string - * Converted text. - */ - convertToUnicode: function NH_convertToUnicode(aText, aCharset) - { - let conv = Cc("@mozilla.org/intl/scriptableunicodeconverter"). - createInstance(Ci.nsIScriptableUnicodeConverter); - try { - conv.charset = aCharset || "UTF-8"; - return conv.ConvertToUnicode(aText); - } - catch (ex) { - return aText; - } - }, - - /** - * Reads all available bytes from aStream and converts them to aCharset. - * - * @param nsIInputStream aStream - * @param string aCharset - * @returns string - * UTF-16 encoded string based on the content of aStream and aCharset. - */ - readAndConvertFromStream: function NH_readAndConvertFromStream(aStream, aCharset) - { - let text = null; - try { - text = NetUtil.readInputStreamToString(aStream, aStream.available()) - return this.convertToUnicode(text, aCharset); - } - catch (err) { - return text; - } - }, - - /** - * Reads the posted text from aRequest. - * - * @param nsIHttpChannel aRequest - * @param string aCharset - * The content document charset, used when reading the POSTed data. - * @returns string or null - * Returns the posted string if it was possible to read from aRequest - * otherwise null. - */ - readPostTextFromRequest: function NH_readPostTextFromRequest(aRequest, aCharset) - { - if (aRequest instanceof Ci.nsIUploadChannel) { - let iStream = aRequest.uploadStream; - - let isSeekableStream = false; - if (iStream instanceof Ci.nsISeekableStream) { - isSeekableStream = true; - } - - let prevOffset; - if (isSeekableStream) { - prevOffset = iStream.tell(); - iStream.seek(Ci.nsISeekableStream.NS_SEEK_SET, 0); - } - - // Read data from the stream. - let text = this.readAndConvertFromStream(iStream, aCharset); - - // Seek locks the file, so seek to the beginning only if necko hasn't - // read it yet, since necko doesn't seek to 0 before reading (at lest - // not till 459384 is fixed). - if (isSeekableStream && prevOffset == 0) { - iStream.seek(Ci.nsISeekableStream.NS_SEEK_SET, 0); - } - return text; - } - return null; - }, - - /** - * Reads the posted text from the page's cache. - * - * @param nsIDocShell aDocShell - * @param string aCharset - * @returns string or null - * Returns the posted string if it was possible to read from - * aDocShell otherwise null. - */ - readPostTextFromPage: function NH_readPostTextFromPage(aDocShell, aCharset) - { - let webNav = aDocShell.QueryInterface(Ci.nsIWebNavigation); - return this.readPostTextFromPageViaWebNav(webNav, aCharset); - }, - - /** - * Reads the posted text from the page's cache, given an nsIWebNavigation - * object. - * - * @param nsIWebNavigation aWebNav - * @param string aCharset - * @returns string or null - * Returns the posted string if it was possible to read from - * aWebNav, otherwise null. - */ - readPostTextFromPageViaWebNav: - function NH_readPostTextFromPageViaWebNav(aWebNav, aCharset) - { - if (aWebNav instanceof Ci.nsIWebPageDescriptor) { - let descriptor = aWebNav.currentDescriptor; - - if (descriptor instanceof Ci.nsISHEntry && descriptor.postData && - descriptor instanceof Ci.nsISeekableStream) { - descriptor.seek(NS_SEEK_SET, 0); - - return this.readAndConvertFromStream(descriptor, aCharset); - } - } - return null; - }, - - /** - * Gets the web appId that is associated with aRequest. - * - * @param nsIHttpChannel aRequest - * @returns number|null - * The appId for the given request, if available. - */ - getAppIdForRequest: function NH_getAppIdForRequest(aRequest) - { - try { - return this.getRequestLoadContext(aRequest).appId; - } catch (ex) { - // request loadContent is not always available. - } - return null; - }, - - /** - * Gets the topFrameElement that is associated with aRequest. This - * works in single-process and multiprocess contexts. It may cross - * the content/chrome boundary. - * - * @param nsIHttpChannel aRequest - * @returns nsIDOMElement|null - * The top frame element for the given request. - */ - getTopFrameForRequest: function NH_getTopFrameForRequest(aRequest) - { - try { - return this.getRequestLoadContext(aRequest).topFrameElement; - } catch (ex) { - // request loadContent is not always available. - } - return null; - }, - - /** - * Gets the nsIDOMWindow that is associated with aRequest. - * - * @param nsIHttpChannel aRequest - * @returns nsIDOMWindow or null - */ - getWindowForRequest: function NH_getWindowForRequest(aRequest) - { - try { - return this.getRequestLoadContext(aRequest).associatedWindow; - } catch (ex) { - // TODO: bug 802246 - getWindowForRequest() throws on b2g: there is no - // associatedWindow property. - } - return null; - }, - - /** - * Gets the nsILoadContext that is associated with aRequest. - * - * @param nsIHttpChannel aRequest - * @returns nsILoadContext or null - */ - getRequestLoadContext: function NH_getRequestLoadContext(aRequest) - { - try { - return aRequest.notificationCallbacks.getInterface(Ci.nsILoadContext); - } catch (ex) { } - - try { - return aRequest.loadGroup.notificationCallbacks.getInterface(Ci.nsILoadContext); - } catch (ex) { } - - return null; - }, - - /** - * Determines whether the request has been made for the top level document. - * - * @param nsIHttpChannel aRequest - * @returns Boolean True if the request represents the top level document. - */ - isTopLevelLoad: function(aRequest) - { - if (aRequest instanceof Ci.nsIChannel) { - let loadInfo = aRequest.loadInfo; - if (loadInfo && loadInfo.parentOuterWindowID == loadInfo.outerWindowID) { - return (aRequest.loadFlags & Ci.nsIChannel.LOAD_DOCUMENT_URI); - } - } - - return false; - }, - - /** - * Loads the content of aUrl from the cache. - * - * @param string aUrl - * URL to load the cached content for. - * @param string aCharset - * Assumed charset of the cached content. Used if there is no charset - * on the channel directly. - * @param function aCallback - * Callback that is called with the loaded cached content if available - * or null if something failed while getting the cached content. - */ - loadFromCache: function NH_loadFromCache(aUrl, aCharset, aCallback) - { - let channel = NetUtil.newChannel({uri: aUrl, loadUsingSystemPrincipal: true}); - - // Ensure that we only read from the cache and not the server. - channel.loadFlags = Ci.nsIRequest.LOAD_FROM_CACHE | - Ci.nsICachingChannel.LOAD_ONLY_FROM_CACHE | - Ci.nsICachingChannel.LOAD_BYPASS_LOCAL_CACHE_IF_BUSY; - - NetUtil.asyncFetch( - channel, - (aInputStream, aStatusCode, aRequest) => { - if (!components.isSuccessCode(aStatusCode)) { - aCallback(null); - return; - } - - // Try to get the encoding from the channel. If there is none, then use - // the passed assumed aCharset. - let aChannel = aRequest.QueryInterface(Ci.nsIChannel); - let contentCharset = aChannel.contentCharset || aCharset; - - // Read the content of the stream using contentCharset as encoding. - aCallback(this.readAndConvertFromStream(aInputStream, contentCharset)); - }); - }, - - /** - * Parse a raw Cookie header value. - * - * @param string aHeader - * The raw Cookie header value. - * @return array - * Array holding an object for each cookie. Each object holds the - * following properties: name and value. - */ - parseCookieHeader: function NH_parseCookieHeader(aHeader) - { - let cookies = aHeader.split(";"); - let result = []; - - cookies.forEach(function(aCookie) { - let equal = aCookie.indexOf("="); - let name = aCookie.substr(0, equal); - let value = aCookie.substr(equal + 1); - result.push({name: unescape(name.trim()), - value: unescape(value.trim())}); - }); - - return result; - }, - - /** - * Parse a raw Set-Cookie header value. - * - * @param string aHeader - * The raw Set-Cookie header value. - * @return array - * Array holding an object for each cookie. Each object holds the - * following properties: name, value, secure (boolean), httpOnly - * (boolean), path, domain and expires (ISO date string). - */ - parseSetCookieHeader: function NH_parseSetCookieHeader(aHeader) - { - let rawCookies = aHeader.split(/\r\n|\n|\r/); - let cookies = []; - - rawCookies.forEach(function(aCookie) { - let equal = aCookie.indexOf("="); - let name = unescape(aCookie.substr(0, equal).trim()); - let parts = aCookie.substr(equal + 1).split(";"); - let value = unescape(parts.shift().trim()); - - let cookie = {name: name, value: value}; - - parts.forEach(function(aPart) { - let part = aPart.trim(); - if (part.toLowerCase() == "secure") { - cookie.secure = true; - } - else if (part.toLowerCase() == "httponly") { - cookie.httpOnly = true; - } - else if (part.indexOf("=") > -1) { - let pair = part.split("="); - pair[0] = pair[0].toLowerCase(); - if (pair[0] == "path" || pair[0] == "domain") { - cookie[pair[0]] = pair[1]; - } - else if (pair[0] == "expires") { - try { - pair[1] = pair[1].replace(/-/g, ' '); - cookie.expires = new Date(pair[1]).toISOString(); - } - catch (ex) { } - } - } - }); - - cookies.push(cookie); - }); - - return cookies; - }, - - // This is a list of all the mime category maps jviereck could find in the - // firebug code base. - mimeCategoryMap: { - "text/plain": "txt", - "text/html": "html", - "text/xml": "xml", - "text/xsl": "txt", - "text/xul": "txt", - "text/css": "css", - "text/sgml": "txt", - "text/rtf": "txt", - "text/x-setext": "txt", - "text/richtext": "txt", - "text/javascript": "js", - "text/jscript": "txt", - "text/tab-separated-values": "txt", - "text/rdf": "txt", - "text/xif": "txt", - "text/ecmascript": "js", - "text/vnd.curl": "txt", - "text/x-json": "json", - "text/x-js": "txt", - "text/js": "txt", - "text/vbscript": "txt", - "view-source": "txt", - "view-fragment": "txt", - "application/xml": "xml", - "application/xhtml+xml": "xml", - "application/atom+xml": "xml", - "application/rss+xml": "xml", - "application/vnd.mozilla.maybe.feed": "xml", - "application/vnd.mozilla.xul+xml": "xml", - "application/javascript": "js", - "application/x-javascript": "js", - "application/x-httpd-php": "txt", - "application/rdf+xml": "xml", - "application/ecmascript": "js", - "application/http-index-format": "txt", - "application/json": "json", - "application/x-js": "txt", - "multipart/mixed": "txt", - "multipart/x-mixed-replace": "txt", - "image/svg+xml": "svg", - "application/octet-stream": "bin", - "image/jpeg": "image", - "image/jpg": "image", - "image/gif": "image", - "image/png": "image", - "image/bmp": "image", - "application/x-shockwave-flash": "flash", - "video/x-flv": "flash", - "audio/mpeg3": "media", - "audio/x-mpeg-3": "media", - "video/mpeg": "media", - "video/x-mpeg": "media", - "audio/ogg": "media", - "application/ogg": "media", - "application/x-ogg": "media", - "application/x-midi": "media", - "audio/midi": "media", - "audio/x-mid": "media", - "audio/x-midi": "media", - "music/crescendo": "media", - "audio/wav": "media", - "audio/x-wav": "media", - "text/json": "json", - "application/x-json": "json", - "application/json-rpc": "json", - "application/x-web-app-manifest+json": "json", - "application/manifest+json": "json" - }, - - /** - * Check if the given MIME type is a text-only MIME type. - * - * @param string aMimeType - * @return boolean - */ - isTextMimeType: function NH_isTextMimeType(aMimeType) - { - if (aMimeType.indexOf("text/") == 0) { - return true; - } - - // XML and JSON often come with custom MIME types, so in addition to the - // standard "application/xml" and "application/json", we also look for - // variants like "application/x-bigcorp+xml". For JSON we allow "+json" and - // "-json" as suffixes. - if (/^application\/\w+(?:[\.-]\w+)*(?:\+xml|[-+]json)$/.test(aMimeType)) { - return true; - } - - let category = this.mimeCategoryMap[aMimeType] || null; - switch (category) { - case "txt": - case "js": - case "json": - case "css": - case "html": - case "svg": - case "xml": - return true; - - default: - return false; - } - }, - - /** - * Takes a securityInfo object of nsIRequest, the nsIRequest itself and - * extracts security information from them. - * - * @param object securityInfo - * The securityInfo object of a request. If null channel is assumed - * to be insecure. - * @param object httpActivity - * The httpActivity object for the request with at least members - * { private, hostname }. - * - * @return object - * Returns an object containing following members: - * - state: The security of the connection used to fetch this - * request. Has one of following string values: - * * "insecure": the connection was not secure (only http) - * * "weak": the connection has minor security issues - * * "broken": secure connection failed (e.g. expired cert) - * * "secure": the connection was properly secured. - * If state == broken: - * - errorMessage: full error message from nsITransportSecurityInfo. - * If state == secure: - * - protocolVersion: one of TLSv1, TLSv1.1, TLSv1.2. - * - cipherSuite: the cipher suite used in this connection. - * - cert: information about certificate used in this connection. - * See parseCertificateInfo for the contents. - * - hsts: true if host uses Strict Transport Security, false otherwise - * - hpkp: true if host uses Public Key Pinning, false otherwise - * If state == weak: Same as state == secure and - * - weaknessReasons: list of reasons that cause the request to be - * considered weak. See getReasonsForWeakness. - */ - parseSecurityInfo: function NH_parseSecurityInfo(securityInfo, httpActivity) { - const info = { - state: "insecure", - }; - - // The request did not contain any security info. - if (!securityInfo) { - return info; - } - - /** - * Different scenarios to consider here and how they are handled: - * - request is HTTP, the connection is not secure - * => securityInfo is null - * => state === "insecure" - * - * - request is HTTPS, the connection is secure - * => .securityState has STATE_IS_SECURE flag - * => state === "secure" - * - * - request is HTTPS, the connection has security issues - * => .securityState has STATE_IS_INSECURE flag - * => .errorCode is an NSS error code. - * => state === "broken" - * - * - request is HTTPS, the connection was terminated before the security - * could be validated - * => .securityState has STATE_IS_INSECURE flag - * => .errorCode is NOT an NSS error code. - * => .errorMessage is not available. - * => state === "insecure" - * - * - request is HTTPS but it uses a weak cipher or old protocol, see - * http://hg.mozilla.org/mozilla-central/annotate/def6ed9d1c1a/ - * security/manager/ssl/nsNSSCallbacks.cpp#l1233 - * - request is mixed content (which makes no sense whatsoever) - * => .securityState has STATE_IS_BROKEN flag - * => .errorCode is NOT an NSS error code - * => .errorMessage is not available - * => state === "weak" - */ - - securityInfo.QueryInterface(Ci.nsITransportSecurityInfo); - securityInfo.QueryInterface(Ci.nsISSLStatusProvider); - - const wpl = Ci.nsIWebProgressListener; - const NSSErrorsService = Cc['@mozilla.org/nss_errors_service;1'] - .getService(Ci.nsINSSErrorsService); - const SSLStatus = securityInfo.SSLStatus; - if (!NSSErrorsService.isNSSErrorCode(securityInfo.errorCode)) { - const state = securityInfo.securityState; - - let uri = null; - if (httpActivity.channel && httpActivity.channel.URI) { - uri = httpActivity.channel.URI; - } - if (uri && !uri.schemeIs("https") && !uri.schemeIs("wss")) { - // it is not enough to look at the transport security info - schemes other than - // https and wss are subject to downgrade/etc at the scheme level and should - // always be considered insecure - info.state = "insecure"; - } else if (state & wpl.STATE_IS_SECURE) { - // The connection is secure if the scheme is sufficient - info.state = "secure"; - } else if (state & wpl.STATE_IS_BROKEN) { - // The connection is not secure, there was no error but there's some - // minor security issues. - info.state = "weak"; - info.weaknessReasons = this.getReasonsForWeakness(state); - } else if (state & wpl.STATE_IS_INSECURE) { - // This was most likely an https request that was aborted before - // validation. Return info as info.state = insecure. - return info; - } else { - DevToolsUtils.reportException("NetworkHelper.parseSecurityInfo", - "Security state " + state + " has no known STATE_IS_* flags."); - return info; - } - - // Cipher suite. - info.cipherSuite = SSLStatus.cipherName; - - // Protocol version. - info.protocolVersion = this.formatSecurityProtocol(SSLStatus.protocolVersion); - - // Certificate. - info.cert = this.parseCertificateInfo(SSLStatus.serverCert); - - // HSTS and HPKP if available. - if (httpActivity.hostname) { - const sss = Cc("@mozilla.org/ssservice;1") - .getService(Ci.nsISiteSecurityService); - - - // SiteSecurityService uses different storage if the channel is - // private. Thus we must give isSecureHost correct flags or we - // might get incorrect results. - let flags = (httpActivity.private) ? - Ci.nsISocketProvider.NO_PERMANENT_STORAGE : 0; - - let host = httpActivity.hostname; - - info.hsts = sss.isSecureHost(sss.HEADER_HSTS, host, flags); - info.hpkp = sss.isSecureHost(sss.HEADER_HPKP, host, flags); - } else { - DevToolsUtils.reportException("NetworkHelper.parseSecurityInfo", - "Could not get HSTS/HPKP status as hostname is not available."); - info.hsts = false; - info.hpkp = false; - } - - } else { - // The connection failed. - info.state = "broken"; - info.errorMessage = securityInfo.errorMessage; - } - - return info; - }, - - /** - * Takes an nsIX509Cert and returns an object with certificate information. - * - * @param nsIX509Cert cert - * The certificate to extract the information from. - * @return object - * An object with following format: - * { - * subject: { commonName, organization, organizationalUnit }, - * issuer: { commonName, organization, organizationUnit }, - * validity: { start, end }, - * fingerprint: { sha1, sha256 } - * } - */ - parseCertificateInfo: function NH_parseCertifificateInfo(cert) { - let info = {}; - if (cert) { - info.subject = { - commonName: cert.commonName, - organization: cert.organization, - organizationalUnit: cert.organizationalUnit, - }; - - info.issuer = { - commonName: cert.issuerCommonName, - organization: cert.issuerOrganization, - organizationUnit: cert.issuerOrganizationUnit, - }; - - info.validity = { - start: cert.validity.notBeforeLocalDay, - end: cert.validity.notAfterLocalDay, - }; - - info.fingerprint = { - sha1: cert.sha1Fingerprint, - sha256: cert.sha256Fingerprint, - }; - } else { - DevToolsUtils.reportException("NetworkHelper.parseCertificateInfo", - "Secure connection established without certificate."); - } - - return info; - }, - - /** - * Takes protocolVersion of SSLStatus object and returns human readable - * description. - * - * @param Number version - * One of nsISSLStatus version constants. - * @return string - * One of TLSv1, TLSv1.1, TLSv1.2 if @param version is valid, - * Unknown otherwise. - */ - formatSecurityProtocol: function NH_formatSecurityProtocol(version) { - switch (version) { - case Ci.nsISSLStatus.TLS_VERSION_1: - return "TLSv1"; - case Ci.nsISSLStatus.TLS_VERSION_1_1: - return "TLSv1.1"; - case Ci.nsISSLStatus.TLS_VERSION_1_2: - return "TLSv1.2"; - default: - DevToolsUtils.reportException("NetworkHelper.formatSecurityProtocol", - "protocolVersion " + version + " is unknown."); - return "Unknown"; - } - }, - - /** - * Takes the securityState bitfield and returns reasons for weak connection - * as an array of strings. - * - * @param Number state - * nsITransportSecurityInfo.securityState. - * - * @return Array[String] - * List of weakness reasons. A subset of { cipher } where - * * cipher: The cipher suite is consireded to be weak (RC4). - */ - getReasonsForWeakness: function NH_getReasonsForWeakness(state) { - const wpl = Ci.nsIWebProgressListener; - - // If there's non-fatal security issues the request has STATE_IS_BROKEN - // flag set. See http://hg.mozilla.org/mozilla-central/file/44344099d119 - // /security/manager/ssl/nsNSSCallbacks.cpp#l1233 - let reasons = []; - - if (state & wpl.STATE_IS_BROKEN) { - let isCipher = state & wpl.STATE_USES_WEAK_CRYPTO; - - if (isCipher) { - reasons.push("cipher"); - } - - if (!isCipher) { - DevToolsUtils.reportException("NetworkHelper.getReasonsForWeakness", - "STATE_IS_BROKEN without a known reason. Full state was: " + state); - } - } - - return reasons; - }, - - /** - * Parse a url's query string into its components - * - * @param string aQueryString - * The query part of a url - * @return array - * Array of query params {name, value} - */ - parseQueryString: function(aQueryString) { - // Make sure there's at least one param available. - // Be careful here, params don't necessarily need to have values, so - // no need to verify the existence of a "=". - if (!aQueryString) { - return; - } - - // Turn the params string into an array containing { name: value } tuples. - let paramsArray = aQueryString.replace(/^[?&]/, "").split("&").map(e => { - let param = e.split("="); - return { - name: param[0] ? NetworkHelper.convertToUnicode(unescape(param[0])) : "", - value: param[1] ? NetworkHelper.convertToUnicode(unescape(param[1])) : "" - }}); - - return paramsArray; - }, - - /** - * Helper for getting an nsIURL instance out of a string. - */ - nsIURL: function(aUrl, aStore = gNSURLStore) { - if (aStore.has(aUrl)) { - return aStore.get(aUrl); - } - - let uri = Services.io.newURI(aUrl, null, null).QueryInterface(Ci.nsIURL); - aStore.set(aUrl, uri); - return uri; - } -}; - -for (let prop of Object.getOwnPropertyNames(NetworkHelper)) { - exports[prop] = NetworkHelper[prop]; -} diff --git a/packages/devtools-sham-modules/transport/transport.js b/packages/devtools-sham-modules/transport/transport.js deleted file mode 100644 index 29351b3c6c..0000000000 --- a/packages/devtools-sham-modules/transport/transport.js +++ /dev/null @@ -1,866 +0,0 @@ -/* eslint-env browser */ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -// TODO: Get rid of this code once the marionette server loads transport.js as -// an SDK module (see bug 1000814) - -"use strict"; - -const DevToolsUtils = require("../shared/DevToolsUtils"); -const { dumpn, dumpv } = DevToolsUtils; -const StreamUtils = require("../shared/transport/stream-utils"); -const { Packet, JSONPacket, BulkPacket } = - require("../shared/transport/packets"); -const promise = require("../sham/promise"); -const EventEmitter = require("../shared/event-emitter"); -const utf8 = require("./utf8"); - -const PACKET_HEADER_MAX = 200; - -/** - * An adapter that handles data transfers between the debugger client and - * server. It can work with both nsIPipe and nsIServerSocket transports so - * long as the properly created input and output streams are specified. - * (However, for intra-process connections, LocalDebuggerTransport, below, - * is more efficient than using an nsIPipe pair with DebuggerTransport.) - * - * @param input nsIAsyncInputStream - * The input stream. - * @param output nsIAsyncOutputStream - * The output stream. - * - * Given a DebuggerTransport instance dt: - * 1) Set dt.hooks to a packet handler object (described below). - * 2) Call dt.ready() to begin watching for input packets. - * 3) Call dt.send() / dt.startBulkSend() to send packets. - * 4) Call dt.close() to close the connection, and disengage from the event - * loop. - * - * A packet handler is an object with the following methods: - * - * - onPacket(packet) - called when we have received a complete packet. - * |packet| is the parsed form of the packet --- a JavaScript value, not - * a JSON-syntax string. - * - * - onBulkPacket(packet) - called when we have switched to bulk packet - * receiving mode. |packet| is an object containing: - * * actor: Name of actor that will receive the packet - * * type: Name of actor's method that should be called on receipt - * * length: Size of the data to be read - * * stream: This input stream should only be used directly if you can ensure - * that you will read exactly |length| bytes and will not close the - * stream when reading is complete - * * done: If you use the stream directly (instead of |copyTo| below), you - * must signal completion by resolving / rejecting this deferred. - * If it's rejected, the transport will be closed. If an Error is - * supplied as a rejection value, it will be logged via |dumpn|. - * If you do use |copyTo|, resolving is taken care of for you when - * copying completes. - * * copyTo: A helper function for getting your data out of the stream that - * meets the stream handling requirements above, and has the - * following signature: - * @param output nsIAsyncOutputStream - * The stream to copy to. - * @return Promise - * The promise is resolved when copying completes or rejected if any - * (unexpected) errors occur. - * This object also emits "progress" events for each chunk that is - * copied. See stream-utils.js. - * - * - onClosed(reason) - called when the connection is closed. |reason| is - * an optional nsresult or object, typically passed when the transport is - * closed due to some error in a underlying stream. - * - * See ./packets.js and the Remote Debugging Protocol specification for more - * details on the format of these packets. - */ -function DebuggerTransport(socket) { - EventEmitter.decorate(this); - - this._socket = socket; - - // The current incoming (possibly partial) header, which will determine which - // type of Packet |_incoming| below will become. - this._incomingHeader = ""; - // The current incoming Packet object - this._incoming = null; - // A queue of outgoing Packet objects - this._outgoing = []; - - this.hooks = null; - this.active = false; - - this._incomingEnabled = true; - this._outgoingEnabled = true; - - this.close = this.close.bind(this); -} - -DebuggerTransport.prototype = { - /** - * Transmit an object as a JSON packet. - * - * This method returns immediately, without waiting for the entire - * packet to be transmitted, registering event handlers as needed to - * transmit the entire packet. Packets are transmitted in the order - * they are passed to this method. - */ - send: function(object) { - this.emit("send", object); - - let packet = new JSONPacket(this); - packet.object = object; - this._outgoing.push(packet); - this._flushOutgoing(); - }, - - /** - * Transmit streaming data via a bulk packet. - * - * This method initiates the bulk send process by queuing up the header data. - * The caller receives eventual access to a stream for writing. - * - * N.B.: Do *not* attempt to close the stream handed to you, as it will - * continue to be used by this transport afterwards. Most users should - * instead use the provided |copyFrom| function instead. - * - * @param header Object - * This is modeled after the format of JSON packets above, but does not - * actually contain the data, but is instead just a routing header: - * * actor: Name of actor that will receive the packet - * * type: Name of actor's method that should be called on receipt - * * length: Size of the data to be sent - * @return Promise - * The promise will be resolved when you are allowed to write to the - * stream with an object containing: - * * stream: This output stream should only be used directly if - * you can ensure that you will write exactly |length| - * bytes and will not close the stream when writing is - * complete - * * done: If you use the stream directly (instead of |copyFrom| - * below), you must signal completion by resolving / - * rejecting this deferred. If it's rejected, the - * transport will be closed. If an Error is supplied as - * a rejection value, it will be logged via |dumpn|. If - * you do use |copyFrom|, resolving is taken care of for - * you when copying completes. - * * copyFrom: A helper function for getting your data onto the - * stream that meets the stream handling requirements - * above, and has the following signature: - * @param input nsIAsyncInputStream - * The stream to copy from. - * @return Promise - * The promise is resolved when copying completes or - * rejected if any (unexpected) errors occur. - * This object also emits "progress" events for each chunk - * that is copied. See stream-utils.js. - */ - startBulkSend: function(header) { - this.emit("startBulkSend", header); - - let packet = new BulkPacket(this); - packet.header = header; - this._outgoing.push(packet); - this._flushOutgoing(); - return packet.streamReadyForWriting; - }, - - /** - * Close the transport. - * @param reason nsresult / object (optional) - * The status code or error message that corresponds to the reason for - * closing the transport (likely because a stream closed or failed). - */ - close: function(reason) { - this.emit("onClosed", reason); - - this.active = false; - this._socket.close(); - this._destroyIncoming(); - this._destroyAllOutgoing(); - if (this.hooks) { - this.hooks.onClosed(reason); - this.hooks = null; - } - if (reason) { - dumpn("Transport closed: " + DevToolsUtils.safeErrorString(reason)); - } else { - dumpn("Transport closed."); - } - }, - - /** - * The currently outgoing packet (at the top of the queue). - */ - get _currentOutgoing() { - return this._outgoing[0]; - }, - - /** - * Flush data to the outgoing stream. Waits until the output stream notifies - * us that it is ready to be written to (via onOutputStreamReady). - */ - _flushOutgoing: function() { - if (!this._outgoingEnabled || this._outgoing.length === 0) { - return; - } - - // If the top of the packet queue has nothing more to send, remove it. - if (this._currentOutgoing.done) { - this._finishCurrentOutgoing(); - } - - if (this._outgoing.length > 0) { - setTimeout(this.onOutputStreamReady.bind(this), 0); - } - }, - - /** - * Pause this transport's attempts to write to the output stream. This is - * used when we've temporarily handed off our output stream for writing bulk - * data. - */ - pauseOutgoing: function() { - this._outgoingEnabled = false; - }, - - /** - * Resume this transport's attempts to write to the output stream. - */ - resumeOutgoing: function() { - this._outgoingEnabled = true; - this._flushOutgoing(); - }, - - // nsIOutputStreamCallback - /** - * This is called when the output stream is ready for more data to be written. - * The current outgoing packet will attempt to write some amount of data, but - * may not complete. - */ - onOutputStreamReady: DevToolsUtils.makeInfallible(function() { - if (!this._outgoingEnabled || this._outgoing.length === 0) { - return; - } - - try { - this._currentOutgoing.write({ - write: data => { - let count = data.length; - this._socket.send(data); - return count; - } - }); - } catch(e) { - if (e.result != Cr.NS_BASE_STREAM_WOULD_BLOCK) { - this.close(e.result); - return; - } else { - throw e; - } - } - - this._flushOutgoing(); - }, "DebuggerTransport.prototype.onOutputStreamReady"), - - /** - * Remove the current outgoing packet from the queue upon completion. - */ - _finishCurrentOutgoing: function() { - if (this._currentOutgoing) { - this._currentOutgoing.destroy(); - this._outgoing.shift(); - } - }, - - /** - * Clear the entire outgoing queue. - */ - _destroyAllOutgoing: function() { - for (let packet of this._outgoing) { - packet.destroy(); - } - this._outgoing = []; - }, - - /** - * Initialize the input stream for reading. Once this method has been called, - * we watch for packets on the input stream, and pass them to the appropriate - * handlers via this.hooks. - */ - ready: function() { - this.active = true; - this._waitForIncoming(); - }, - - /** - * Asks the input stream to notify us (via onInputStreamReady) when it is - * ready for reading. - */ - _waitForIncoming: function() { - if (this._incomingEnabled && !this._socket.onmessage) { - this._socket.onmessage = this.onInputStreamReady.bind(this); - } - }, - - /** - * Pause this transport's attempts to read from the input stream. This is - * used when we've temporarily handed off our input stream for reading bulk - * data. - */ - pauseIncoming: function() { - this._incomingEnabled = false; - }, - - /** - * Resume this transport's attempts to read from the input stream. - */ - resumeIncoming: function() { - this._incomingEnabled = true; - this._flushIncoming(); - this._waitForIncoming(); - }, - - // nsIInputStreamCallback - /** - * Called when the stream is either readable or closed. - */ - onInputStreamReady: - DevToolsUtils.makeInfallible(function(event) { - let data = event.data; - // TODO: ws-tcp-proxy decodes utf-8, but the transport expects to see the - // encoded bytes. Simplest step is to re-encode for now. - data = utf8.encode(data); - let stream = { - available() { - return data.length; - }, - readBytes(count) { - let result = data.slice(0, count); - data = data.slice(count); - return result; - }, - }; - - try { - while (data && this._incomingEnabled && - this._processIncoming(stream, stream.available())) {} - this._waitForIncoming(); - } catch(e) { - if (e.result != Cr.NS_BASE_STREAM_WOULD_BLOCK) { - this.close(e.result); - } else { - throw e; - } - } - }, "DebuggerTransport.prototype.onInputStreamReady"), - - /** - * Process the incoming data. Will create a new currently incoming Packet if - * needed. Tells the incoming Packet to read as much data as it can, but - * reading may not complete. The Packet signals that its data is ready for - * delivery by calling one of this transport's _on*Ready methods (see - * ./packets.js and the _on*Ready methods below). - * @return boolean - * Whether incoming stream processing should continue for any - * remaining data. - */ - _processIncoming: function(stream, count) { - dumpv("Data available: " + count); - - if (!count) { - dumpv("Nothing to read, skipping"); - return false; - } - - try { - if (!this._incoming) { - dumpv("Creating a new packet from incoming"); - - if (!this._readHeader(stream)) { - return false; // Not enough data to read packet type - } - - // Attempt to create a new Packet by trying to parse each possible - // header pattern. - this._incoming = Packet.fromHeader(this._incomingHeader, this); - if (!this._incoming) { - throw new Error("No packet types for header: " + - this._incomingHeader); - } - } - - if (!this._incoming.done) { - // We have an incomplete packet, keep reading it. - dumpv("Existing packet incomplete, keep reading"); - this._incoming.read(stream); - } - } catch(e) { - let msg = "Error reading incoming packet: (" + e + " - " + e.stack + ")"; - dumpn(msg); - - // Now in an invalid state, shut down the transport. - this.close(); - return false; - } - - if (!this._incoming.done) { - // Still not complete, we'll wait for more data. - dumpv("Packet not done, wait for more"); - return true; - } - - // Ready for next packet - this._flushIncoming(); - return true; - }, - - /** - * Read as far as we can into the incoming data, attempting to build up a - * complete packet header (which terminates with ":"). We'll only read up to - * PACKET_HEADER_MAX characters. - * @return boolean - * True if we now have a complete header. - */ - _readHeader: function(stream) { - let amountToRead = PACKET_HEADER_MAX - this._incomingHeader.length; - this._incomingHeader += - StreamUtils.delimitedRead(stream, ":", amountToRead); - if (dumpv.wantVerbose) { - dumpv("Header read: " + this._incomingHeader); - } - - if (this._incomingHeader.endsWith(":")) { - if (dumpv.wantVerbose) { - dumpv("Found packet header successfully: " + this._incomingHeader); - } - return true; - } - - if (this._incomingHeader.length >= PACKET_HEADER_MAX) { - throw new Error("Failed to parse packet header!"); - } - - // Not enough data yet. - return false; - }, - - /** - * If the incoming packet is done, log it as needed and clear the buffer. - */ - _flushIncoming: function() { - if (!this._incoming.done) { - return; - } - if (dumpn.wantLogging) { - dumpn("Got: " + this._incoming); - } - this._destroyIncoming(); - }, - - /** - * Handler triggered by an incoming JSONPacket completing it's |read| method. - * Delivers the packet to this.hooks.onPacket. - */ - _onJSONObjectReady: function(object) { - DevToolsUtils.executeSoon(DevToolsUtils.makeInfallible(() => { - // Ensure the transport is still alive by the time this runs. - if (this.active) { - this.emit("onPacket", object); - this.hooks.onPacket(object); - } - }, "DebuggerTransport instance's this.hooks.onPacket")); - }, - - /** - * Handler triggered by an incoming BulkPacket entering the |read| phase for - * the stream portion of the packet. Delivers info about the incoming - * streaming data to this.hooks.onBulkPacket. See the main comment on the - * transport at the top of this file for more details. - */ - _onBulkReadReady: function(...args) { - DevToolsUtils.executeSoon(DevToolsUtils.makeInfallible(() => { - // Ensure the transport is still alive by the time this runs. - if (this.active) { - this.emit("onBulkPacket", ...args); - this.hooks.onBulkPacket(...args); - } - }, "DebuggerTransport instance's this.hooks.onBulkPacket")); - }, - - /** - * Remove all handlers and references related to the current incoming packet, - * either because it is now complete or because the transport is closing. - */ - _destroyIncoming: function() { - if (this._incoming) { - this._incoming.destroy(); - } - this._incomingHeader = ""; - this._incoming = null; - } - -}; - -exports.DebuggerTransport = DebuggerTransport; - -/** - * An adapter that handles data transfers between the debugger client and - * server when they both run in the same process. It presents the same API as - * DebuggerTransport, but instead of transmitting serialized messages across a - * connection it merely calls the packet dispatcher of the other side. - * - * @param other LocalDebuggerTransport - * The other endpoint for this debugger connection. - * - * @see DebuggerTransport - */ -function LocalDebuggerTransport(other) { - EventEmitter.decorate(this); - - this.other = other; - this.hooks = null; - - /* - * A packet number, shared between this and this.other. This isn't used - * by the protocol at all, but it makes the packet traces a lot easier to - * follow. - */ - this._serial = this.other ? this.other._serial : { count: 0 }; - this.close = this.close.bind(this); -} - -LocalDebuggerTransport.prototype = { - /** - * Transmit a message by directly calling the onPacket handler of the other - * endpoint. - */ - send: function(packet) { - this.emit("send", packet); - - let serial = this._serial.count++; - if (dumpn.wantLogging) { - /* Check 'from' first, as 'echo' packets have both. */ - if (packet.from) { - dumpn("Packet " + serial + " sent from " + uneval(packet.from)); - } else if (packet.to) { - dumpn("Packet " + serial + " sent to " + uneval(packet.to)); - } - } - this._deepFreeze(packet); - let other = this.other; - if (other) { - DevToolsUtils.executeSoon(DevToolsUtils.makeInfallible(() => { - // Avoid the cost of JSON.stringify() when logging is disabled. - if (dumpn.wantLogging) { - dumpn("Received packet " + serial + ": " + JSON.stringify(packet, null, 2)); - } - if (other.hooks) { - other.emit("onPacket", packet); - other.hooks.onPacket(packet); - } - }, "LocalDebuggerTransport instance's this.other.hooks.onPacket")); - } - }, - - /** - * Send a streaming bulk packet directly to the onBulkPacket handler of the - * other endpoint. - * - * This case is much simpler than the full DebuggerTransport, since there is - * no primary stream we have to worry about managing while we hand it off to - * others temporarily. Instead, we can just make a single use pipe and be - * done with it. - */ - startBulkSend: function({actor, type, length}) { - this.emit("startBulkSend", {actor, type, length}); - - let serial = this._serial.count++; - - dumpn("Sent bulk packet " + serial + " for actor " + actor); - if (!this.other) { - return; - } - - let pipe = new Pipe(true, true, 0, 0, null); - - DevToolsUtils.executeSoon(DevToolsUtils.makeInfallible(() => { - dumpn("Received bulk packet " + serial); - if (!this.other.hooks) { - return; - } - - // Receiver - let deferred = promise.defer(); - let packet = { - actor: actor, - type: type, - length: length, - copyTo: (output) => { - let copying = - StreamUtils.copyStream(pipe.inputStream, output, length); - deferred.resolve(copying); - return copying; - }, - stream: pipe.inputStream, - done: deferred - }; - - this.other.emit("onBulkPacket", packet); - this.other.hooks.onBulkPacket(packet); - - // Await the result of reading from the stream - deferred.promise.then(() => pipe.inputStream.close(), this.close); - }, "LocalDebuggerTransport instance's this.other.hooks.onBulkPacket")); - - // Sender - let sendDeferred = promise.defer(); - - // The remote transport is not capable of resolving immediately here, so we - // shouldn't be able to either. - DevToolsUtils.executeSoon(() => { - let copyDeferred = promise.defer(); - - sendDeferred.resolve({ - copyFrom: (input) => { - let copying = - StreamUtils.copyStream(input, pipe.outputStream, length); - copyDeferred.resolve(copying); - return copying; - }, - stream: pipe.outputStream, - done: copyDeferred - }); - - // Await the result of writing to the stream - copyDeferred.promise.then(() => pipe.outputStream.close(), this.close); - }); - - return sendDeferred.promise; - }, - - /** - * Close the transport. - */ - close: function() { - this.emit("close"); - - if (this.other) { - // Remove the reference to the other endpoint before calling close(), to - // avoid infinite recursion. - let other = this.other; - this.other = null; - other.close(); - } - if (this.hooks) { - try { - this.hooks.onClosed(); - } catch(ex) { - console.error(ex); - } - this.hooks = null; - } - }, - - /** - * An empty method for emulating the DebuggerTransport API. - */ - ready: function() {}, - - /** - * Helper function that makes an object fully immutable. - */ - _deepFreeze: function(object) { - Object.freeze(object); - for (let prop in object) { - // Freeze the properties that are objects, not on the prototype, and not - // already frozen. Note that this might leave an unfrozen reference - // somewhere in the object if there is an already frozen object containing - // an unfrozen object. - if (object.hasOwnProperty(prop) && typeof object === "object" && - !Object.isFrozen(object)) { - this._deepFreeze(o[prop]); - } - } - } -}; - -exports.LocalDebuggerTransport = LocalDebuggerTransport; - -/** - * A transport for the debugging protocol that uses nsIMessageSenders to - * exchange packets with servers running in child processes. - * - * In the parent process, |sender| should be the nsIMessageSender for the - * child process. In a child process, |sender| should be the child process - * message manager, which sends packets to the parent. - * - * |prefix| is a string included in the message names, to distinguish - * multiple servers running in the same child process. - * - * This transport exchanges messages named 'debug::packet', where - * is |prefix|, whose data is the protocol packet. - */ -function ChildDebuggerTransport(sender, prefix) { - EventEmitter.decorate(this); - - this._sender = sender.QueryInterface(Ci.nsIMessageSender); - this._messageName = "debug:" + prefix + ":packet"; -} - -/* - * To avoid confusion, we use 'message' to mean something that - * nsIMessageSender conveys, and 'packet' to mean a remote debugging - * protocol packet. - */ -ChildDebuggerTransport.prototype = { - constructor: ChildDebuggerTransport, - - hooks: null, - - ready: function () { - this._sender.addMessageListener(this._messageName, this); - }, - - close: function () { - this._sender.removeMessageListener(this._messageName, this); - this.emit("onClosed"); - this.hooks.onClosed(); - }, - - receiveMessage: function ({data}) { - this.emit("onPacket", data); - this.hooks.onPacket(data); - }, - - send: function (packet) { - this.emit("send", packet); - this._sender.sendAsyncMessage(this._messageName, packet); - }, - - startBulkSend: function() { - throw new Error("Can't send bulk data to child processes."); - } -}; - -exports.ChildDebuggerTransport = ChildDebuggerTransport; - -// WorkerDebuggerTransport is defined differently depending on whether we are -// on the main thread or a worker thread. In the former case, we are required -// by the devtools loader, and isWorker will be false. Otherwise, we are -// required by the worker loader, and isWorker will be true. -// -// Each worker debugger supports only a single connection to the main thread. -// However, its theoretically possible for multiple servers to connect to the -// same worker. Consequently, each transport has a connection id, to allow -// messages from multiple connections to be multiplexed on a single channel. - -if (typeof WorkerGlobalScope === 'undefined') { // i.e. not in a worker - (function () { // Main thread - /** - * A transport that uses a WorkerDebugger to send packets from the main - * thread to a worker thread. - */ - function WorkerDebuggerTransport(dbg, id) { - this._dbg = dbg; - this._id = id; - this.onMessage = this._onMessage.bind(this); - } - - WorkerDebuggerTransport.prototype = { - constructor: WorkerDebuggerTransport, - - ready: function () { - this._dbg.addListener(this); - }, - - close: function () { - this._dbg.removeListener(this); - if (this.hooks) { - this.hooks.onClosed(); - } - }, - - send: function (packet) { - this._dbg.postMessage(JSON.stringify({ - type: "message", - id: this._id, - message: packet - })); - }, - - startBulkSend: function () { - throw new Error("Can't send bulk data from worker threads!"); - }, - - _onMessage: function (message) { - let packet = JSON.parse(message); - if (packet.type !== "message" || packet.id !== this._id) { - return; - } - - if (this.hooks) { - this.hooks.onPacket(packet.message); - } - } - }; - - exports.WorkerDebuggerTransport = WorkerDebuggerTransport; - }).call(this); -} else { - (function () { // Worker thread - /* - * A transport that uses a WorkerDebuggerGlobalScope to send packets from a - * worker thread to the main thread. - */ - function WorkerDebuggerTransport(scope, id) { - this._scope = scope; - this._id = id; - this._onMessage = this._onMessage.bind(this); - } - - WorkerDebuggerTransport.prototype = { - constructor: WorkerDebuggerTransport, - - ready: function () { - this._scope.addEventListener("message", this._onMessage); - }, - - close: function () { - this._scope.removeEventListener("message", this._onMessage); - if (this.hooks) { - this.hooks.onClosed(); - } - }, - - send: function (packet) { - this._scope.postMessage(JSON.stringify({ - type: "message", - id: this._id, - message: packet - })); - }, - - startBulkSend: function () { - throw new Error("Can't send bulk data from worker threads!"); - }, - - _onMessage: function (event) { - let packet = JSON.parse(event.data); - if (packet.type !== "message" || packet.id !== this._id) { - return; - } - - if (this.hooks) { - this.hooks.onPacket(packet.message); - } - } - }; - - exports.WorkerDebuggerTransport = WorkerDebuggerTransport; - }).call(this); -} diff --git a/packages/devtools-sham-modules/transport/utf8.js b/packages/devtools-sham-modules/transport/utf8.js deleted file mode 100644 index c138a38ef5..0000000000 --- a/packages/devtools-sham-modules/transport/utf8.js +++ /dev/null @@ -1,244 +0,0 @@ -/*! https://mths.be/utf8js v2.0.0 by @mathias */ -;(function(root) { - - // Detect free variables `exports` - var freeExports = typeof exports == 'object' && exports; - - // Detect free variable `module` - var freeModule = typeof module == 'object' && module && - module.exports == freeExports && module; - - // Detect free variable `global`, from Node.js or Browserified code, - // and use it as `root` - var freeGlobal = typeof global == 'object' && global; - if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) { - root = freeGlobal; - } - - /*--------------------------------------------------------------------------*/ - - var stringFromCharCode = String.fromCharCode; - - // Taken from https://mths.be/punycode - function ucs2decode(string) { - var output = []; - var counter = 0; - var length = string.length; - var value; - var extra; - while (counter < length) { - value = string.charCodeAt(counter++); - if (value >= 0xD800 && value <= 0xDBFF && counter < length) { - // high surrogate, and there is a next character - extra = string.charCodeAt(counter++); - if ((extra & 0xFC00) == 0xDC00) { // low surrogate - output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000); - } else { - // unmatched surrogate; only append this code unit, in case the next - // code unit is the high surrogate of a surrogate pair - output.push(value); - counter--; - } - } else { - output.push(value); - } - } - return output; - } - - // Taken from https://mths.be/punycode - function ucs2encode(array) { - var length = array.length; - var index = -1; - var value; - var output = ''; - while (++index < length) { - value = array[index]; - if (value > 0xFFFF) { - value -= 0x10000; - output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800); - value = 0xDC00 | value & 0x3FF; - } - output += stringFromCharCode(value); - } - return output; - } - - function checkScalarValue(codePoint) { - if (codePoint >= 0xD800 && codePoint <= 0xDFFF) { - throw Error( - 'Lone surrogate U+' + codePoint.toString(16).toUpperCase() + - ' is not a scalar value' - ); - } - } - /*--------------------------------------------------------------------------*/ - - function createByte(codePoint, shift) { - return stringFromCharCode(((codePoint >> shift) & 0x3F) | 0x80); - } - - function encodeCodePoint(codePoint) { - if ((codePoint & 0xFFFFFF80) == 0) { // 1-byte sequence - return stringFromCharCode(codePoint); - } - var symbol = ''; - if ((codePoint & 0xFFFFF800) == 0) { // 2-byte sequence - symbol = stringFromCharCode(((codePoint >> 6) & 0x1F) | 0xC0); - } - else if ((codePoint & 0xFFFF0000) == 0) { // 3-byte sequence - checkScalarValue(codePoint); - symbol = stringFromCharCode(((codePoint >> 12) & 0x0F) | 0xE0); - symbol += createByte(codePoint, 6); - } - else if ((codePoint & 0xFFE00000) == 0) { // 4-byte sequence - symbol = stringFromCharCode(((codePoint >> 18) & 0x07) | 0xF0); - symbol += createByte(codePoint, 12); - symbol += createByte(codePoint, 6); - } - symbol += stringFromCharCode((codePoint & 0x3F) | 0x80); - return symbol; - } - - function utf8encode(string) { - var codePoints = ucs2decode(string); - var length = codePoints.length; - var index = -1; - var codePoint; - var byteString = ''; - while (++index < length) { - codePoint = codePoints[index]; - byteString += encodeCodePoint(codePoint); - } - return byteString; - } - - /*--------------------------------------------------------------------------*/ - - function readContinuationByte() { - if (byteIndex >= byteCount) { - throw Error('Invalid byte index'); - } - - var continuationByte = byteArray[byteIndex] & 0xFF; - byteIndex++; - - if ((continuationByte & 0xC0) == 0x80) { - return continuationByte & 0x3F; - } - - // If we end up here, it’s not a continuation byte - throw Error('Invalid continuation byte'); - } - - function decodeSymbol() { - var byte1; - var byte2; - var byte3; - var byte4; - var codePoint; - - if (byteIndex > byteCount) { - throw Error('Invalid byte index'); - } - - if (byteIndex == byteCount) { - return false; - } - - // Read first byte - byte1 = byteArray[byteIndex] & 0xFF; - byteIndex++; - - // 1-byte sequence (no continuation bytes) - if ((byte1 & 0x80) == 0) { - return byte1; - } - - // 2-byte sequence - if ((byte1 & 0xE0) == 0xC0) { - var byte2 = readContinuationByte(); - codePoint = ((byte1 & 0x1F) << 6) | byte2; - if (codePoint >= 0x80) { - return codePoint; - } else { - throw Error('Invalid continuation byte'); - } - } - - // 3-byte sequence (may include unpaired surrogates) - if ((byte1 & 0xF0) == 0xE0) { - byte2 = readContinuationByte(); - byte3 = readContinuationByte(); - codePoint = ((byte1 & 0x0F) << 12) | (byte2 << 6) | byte3; - if (codePoint >= 0x0800) { - checkScalarValue(codePoint); - return codePoint; - } else { - throw Error('Invalid continuation byte'); - } - } - - // 4-byte sequence - if ((byte1 & 0xF8) == 0xF0) { - byte2 = readContinuationByte(); - byte3 = readContinuationByte(); - byte4 = readContinuationByte(); - codePoint = ((byte1 & 0x0F) << 0x12) | (byte2 << 0x0C) | - (byte3 << 0x06) | byte4; - if (codePoint >= 0x010000 && codePoint <= 0x10FFFF) { - return codePoint; - } - } - - throw Error('Invalid UTF-8 detected'); - } - - var byteArray; - var byteCount; - var byteIndex; - function utf8decode(byteString) { - byteArray = ucs2decode(byteString); - byteCount = byteArray.length; - byteIndex = 0; - var codePoints = []; - var tmp; - while ((tmp = decodeSymbol()) !== false) { - codePoints.push(tmp); - } - return ucs2encode(codePoints); - } - - /*--------------------------------------------------------------------------*/ - - var utf8 = { - 'version': '2.0.0', - 'encode': utf8encode, - 'decode': utf8decode - }; - - // Some AMD build optimizers, like r.js, check for specific condition patterns - // like the following: - if ( - typeof define == 'function' && - typeof define.amd == 'object' && - define.amd - ) { - define(function() { - return utf8; - }); - } else if (freeExports && !freeExports.nodeType) { - if (freeModule) { // in Node.js or RingoJS v0.8.0+ - freeModule.exports = utf8; - } else { // in Narwhal or RingoJS v0.7.0- - var object = {}; - var hasOwnProperty = object.hasOwnProperty; - for (var key in utf8) { - hasOwnProperty.call(utf8, key) && (freeExports[key] = utf8[key]); - } - } - } else { // in Rhino or a web browser - root.utf8 = utf8; - } - -}(this)); diff --git a/src/actions/breakpoints.js b/src/actions/breakpoints.js deleted file mode 100644 index a099faa5bc..0000000000 --- a/src/actions/breakpoints.js +++ /dev/null @@ -1,220 +0,0 @@ -// @flow -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/** - * Redux actions for breakpoints - * @module actions/breakpoints - */ - -const constants = require("../constants"); -const { PROMISE } = require("../utils/redux/middleware/promise"); -const { getBreakpoint, getBreakpoints, getSource } = require("../selectors"); - -const { - getOriginalLocation, getGeneratedLocation, isOriginalId -} = require("../utils/source-map"); - -import type { ThunkArgs } from "./types"; -import type { Location } from "../types"; - -type addBreakpointOptions = { - condition: string, - getTextForLine: () => any, -}; - -function _breakpointExists(state, location: Location) { - const currentBp = getBreakpoint(state, location); - return currentBp && !currentBp.disabled; -} - -function _getOrCreateBreakpoint(state, location, condition) { - return getBreakpoint(state, location) || { location, condition, text: "" }; -} - -/** - * Enabling a breakpoint calls {@link addBreakpoint} - * which will reuse the existing breakpoint information that is stored. - * - * @memberof actions/breakpoints - * @static - */ -function enableBreakpoint(location: Location) { - return addBreakpoint(location); -} - -/** - * Add a new or enable an existing breakpoint - * - * @memberof actions/breakpoints - * @static - * @param {String} $1.condition Conditional breakpoint condition value - * @param {Function} $1.getTextForLine Get the text to represent the line - */ -function addBreakpoint( - location: Location, - { condition, getTextForLine } : addBreakpointOptions = {}) { - return ({ dispatch, getState, client }: ThunkArgs) => { - if (_breakpointExists(getState(), location)) { - return Promise.resolve(); - } - - const bp = _getOrCreateBreakpoint(getState(), location, condition); - - return dispatch({ - type: constants.ADD_BREAKPOINT, - breakpoint: bp, - condition: condition, - [PROMISE]: (async function() { - if (isOriginalId(bp.location.sourceId)) { - const source = getSource(getState(), bp.location.sourceId); - location = await getGeneratedLocation(bp.location, source.toJS()); - } - - let { id, actualLocation } = await client.setBreakpoint( - location, - bp.condition, - isOriginalId(bp.location.sourceId) - ); - - actualLocation = await getOriginalLocation(actualLocation); - - // If this breakpoint is being re-enabled, it already has a - // text snippet. - let text = bp.text; - if (!text) { - text = getTextForLine ? getTextForLine(actualLocation.line) : ""; - } - - return { id, actualLocation, text }; - })() - }); - }; -} - -/** - * Disable a single breakpoint - * - * @memberof actions/breakpoints - * @static - */ -function disableBreakpoint(location: Location) { - return _removeOrDisableBreakpoint(location, true); -} - -/** - * Remove a single breakpoint - * - * @memberof actions/breakpoints - * @static - */ -function removeBreakpoint(location: Location) { - return _removeOrDisableBreakpoint(location); -} - -function _removeOrDisableBreakpoint(location, isDisabled) { - return ({ dispatch, getState, client }: ThunkArgs) => { - let bp = getBreakpoint(getState(), location); - if (!bp) { - throw new Error("attempt to remove breakpoint that does not exist"); - } - if (bp.loading) { - // TODO(jwl): make this wait until the breakpoint is saved if it - // is still loading - throw new Error("attempt to remove unsaved breakpoint"); - } - - const action = { - type: constants.REMOVE_BREAKPOINT, - breakpoint: bp, - disabled: isDisabled - }; - - // If the breakpoint is already disabled, we don't need to remove - // it from the server. We just need to dispatch an action - // simulating a successful server request to remove it, and it - // will be removed completely from the state. - if (!bp.disabled) { - return dispatch(Object.assign({}, action, { - [PROMISE]: client.removeBreakpoint(bp.id) - })); - } - return dispatch(Object.assign({}, action, { status: "done" })); - }; -} - -/** - * Toggle All Breakpoints - * - * @memberof actions/breakpoints - * @static - */ -function toggleAllBreakpoints(shouldDisableBreakpoints: boolean) { - return ({ dispatch, getState }: ThunkArgs) => { - const breakpoints = getBreakpoints(getState()); - return dispatch({ - type: constants.TOGGLE_BREAKPOINTS, - shouldDisableBreakpoints, - [PROMISE]: (async function() { - for (let [, breakpoint] of breakpoints) { - if (shouldDisableBreakpoints) { - await dispatch(disableBreakpoint(breakpoint.location)); - } else { - await dispatch(enableBreakpoint(breakpoint.location)); - } - } - })() - }); - }; -} - -/** - * Update the condition of a breakpoint. - * - * @throws {Error} "not implemented" - * @memberof actions/breakpoints - * @static - * @param {Location} location - * @see DebuggerController.Breakpoints.addBreakpoint - * @param {string} condition - * The condition to set on the breakpoint - */ -function setBreakpointCondition( - location: Location, - { condition, getTextForLine } : addBreakpointOptions = {}) { - // location: Location, condition: string, { getTextForLine }) { - return ({ dispatch, getState, client }: ThunkArgs) => { - const bp = getBreakpoint(getState(), location); - if (!bp) { - return dispatch(addBreakpoint(location, { condition, getTextForLine })); - } - - if (bp.loading) { - // TODO(jwl): when this function is called, make sure the action - // creator waits for the breakpoint to exist - throw new Error("breakpoint must be saved"); - } - - return dispatch({ - type: constants.SET_BREAKPOINT_CONDITION, - breakpoint: bp, - condition: condition, - [PROMISE]: client.setBreakpointCondition( - bp.id, - location, - condition, - isOriginalId(bp.location.sourceId) - ) - }); - }; -} - -module.exports = { - enableBreakpoint, - addBreakpoint, - disableBreakpoint, - removeBreakpoint, - toggleAllBreakpoints, - setBreakpointCondition -}; diff --git a/src/actions/event-listeners.js b/src/actions/event-listeners.js deleted file mode 100644 index 618da85272..0000000000 --- a/src/actions/event-listeners.js +++ /dev/null @@ -1,135 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -/* global window gThreadClient setNamedTimeout services EVENTS */ -/* eslint no-shadow: 0 */ - -/** - * Redux actions for the event listeners state - * @module actions/event-listeners - */ - -const constants = require("../constants"); -const { asPaused } = require("../utils/utils"); -const { reportException } = require("../utils/DevToolsUtils"); -const { Task } = require("../utils/task"); - -// delay is in ms -const FETCH_EVENT_LISTENERS_DELAY = 200; - -/** - * @memberof actions/event-listeners - * @static - */ -function fetchEventListeners() { - return (dispatch, getState) => { - // Make sure we"re not sending a batch of closely repeated requests. - // This can easily happen whenever new sources are fetched. - setNamedTimeout( - "event-listeners-fetch", - FETCH_EVENT_LISTENERS_DELAY, - () => { - // In case there is still a request of listeners going on (it - // takes several RDP round trips right now), make sure we wait - // on a currently running request - if (getState().eventListeners.fetchingListeners) { - dispatch({ - type: services.WAIT_UNTIL, - predicate: action => ( - action.type === constants.FETCH_EVENT_LISTENERS && - action.status === "done" - ), - run: dispatch => dispatch(fetchEventListeners()) - }); - return; - } - - dispatch({ - type: constants.FETCH_EVENT_LISTENERS, - status: "begin" - }); - - asPaused(gThreadClient, _getListeners).then(listeners => { - // Notify that event listeners were fetched and shown in the view, - // and callback to resume the active thread if necessary. - window.emit(EVENTS.EVENT_LISTENERS_FETCHED); - - dispatch({ - type: constants.FETCH_EVENT_LISTENERS, - status: "done", - listeners: listeners - }); - }); - }); - }; -} - -const _getListeners = Task.async(function* () { - const response = yield gThreadClient.eventListeners(); - - // Make sure all the listeners are sorted by the event type, since - // they"re not guaranteed to be clustered together. - response.listeners.sort((a, b) => a.type > b.type ? 1 : -1); - - // Add all the listeners in the debugger view event linsteners container. - let fetchedDefinitions = new Map(); - let listeners = []; - for (let listener of response.listeners) { - let definitionSite; - if (fetchedDefinitions.has(listener.function.actor)) { - definitionSite = fetchedDefinitions.get(listener.function.actor); - } else if (listener.function.class == "Function") { - definitionSite = yield _getDefinitionSite(listener.function); - if (!definitionSite) { - // We don"t know where this listener comes from so don"t show it in - // the UI as breaking on it doesn"t work (bug 942899). - continue; - } - - fetchedDefinitions.set(listener.function.actor, definitionSite); - } - listener.function.url = definitionSite; - listeners.push(listener); - } - fetchedDefinitions.clear(); - - return listeners; -}); - -const _getDefinitionSite = Task.async(function* (func) { - const grip = gThreadClient.pauseGrip(func); - let response; - - try { - response = yield grip.getDefinitionSite(); - } catch (e) { - // Don't make this error fatal, it would break the entire events pane. - reportException("_getDefinitionSite", e); - return null; - } - - return response.source.url; -}); - -/** - * @memberof actions/event-listeners - * @static - * @param {string} eventNames - */ -function updateEventBreakpoints(eventNames) { - return dispatch => { - setNamedTimeout("event-breakpoints-update", 0, () => { - gThreadClient.pauseOnDOMEvents(eventNames, function() { - // Notify that event breakpoints were added/removed on the server. - window.emit(EVENTS.EVENT_BREAKPOINTS_UPDATED); - - dispatch({ - type: constants.UPDATE_EVENT_BREAKPOINTS, - eventNames: eventNames - }); - }); - }); - }; -} - -module.exports = { updateEventBreakpoints, fetchEventListeners }; diff --git a/src/actions/index.js b/src/actions/index.js deleted file mode 100644 index b2229e694e..0000000000 --- a/src/actions/index.js +++ /dev/null @@ -1,17 +0,0 @@ -// @flow - -const breakpoints = require("./breakpoints"); -const eventListeners = require("./event-listeners"); -const sources = require("./sources"); -const pause = require("./pause"); -const navigation = require("./navigation"); -const ui = require("./ui"); - -module.exports = (Object.assign( - navigation, - breakpoints, - eventListeners, - sources, - pause, - ui -) : typeof breakpoints); diff --git a/src/actions/navigation.js b/src/actions/navigation.js deleted file mode 100644 index 2e1195cbff..0000000000 --- a/src/actions/navigation.js +++ /dev/null @@ -1,41 +0,0 @@ -const constants = require("../constants"); -const { clearSourceMaps } = require("../utils/source-map"); -const { clearDocuments } = require("../utils/source-documents"); - -/** - * Redux actions for the navigation state - * @module actions/navigation - */ - -/** - * @memberof actions/navigation - * @static - */ -function willNavigate() { - clearSourceMaps(); - clearDocuments(); - - return { type: constants.NAVIGATE }; -} - -/** - * @memberof actions/navigation - * @static - */ -function navigated() { - return ({ dispatch }) => { - // We need to load all the sources again because they might have - // come from bfcache, so we won't get a `newSource` notification. - // - // TODO: This seems to be buggy on the debugger server side. When - // the page is loaded from bfcache, we still get sources from the - // *previous* page as well. For now, emulate the current debugger - // behavior by not showing sources loaded by bfcache. - // return dispatch(sources.loadSources()); - }; -} - -module.exports = { - willNavigate, - navigated -}; diff --git a/src/actions/pause.js b/src/actions/pause.js deleted file mode 100644 index 3808dd1efd..0000000000 --- a/src/actions/pause.js +++ /dev/null @@ -1,308 +0,0 @@ -// @flow -const constants = require("../constants"); -const { selectSource } = require("./sources"); -const { PROMISE } = require("../utils/redux/middleware/promise"); - -const { getExpressions, getSelectedFrame, - getPause } = require("../selectors"); -const { updateFrameLocations } = require("../utils/pause"); - -import type { Pause, Frame, Expression, Grip } from "../types"; -import type { ThunkArgs } from "./types"; - -type CommandType = { type: string }; - -/** - * Redux actions for the pause state - * @module actions/pause - */ - -/** - * Debugger has just resumed - * - * @memberof actions/pause - * @static - */ -function resumed() { - return ({ dispatch, client }: ThunkArgs) => { - return dispatch({ - type: constants.RESUME, - value: undefined - }); - }; -} - -/** - * Debugger has just paused - * - * @param {object} pauseInfo - * @memberof actions/pause - * @static - */ -function paused(pauseInfo: Pause) { - return async function({ dispatch, getState, client }: ThunkArgs) { - let { frames, why } = pauseInfo; - frames = await updateFrameLocations(frames); - const frame = frames[0]; - - dispatch({ - type: constants.PAUSED, - pauseInfo: { why, frame }, - frames: frames, - selectedFrameId: frame.id - }); - - dispatch(evaluateExpressions()); - - dispatch(selectSource(frame.location.sourceId, - { line: frame.location.line })); - }; -} - -/** - * - * @memberof actions/pause - * @static - */ -function pauseOnExceptions( - shouldPauseOnExceptions: boolean, shouldIgnoreCaughtExceptions: boolean) { - return ({ dispatch, client }: ThunkArgs) => { - dispatch({ - type: constants.PAUSE_ON_EXCEPTIONS, - shouldPauseOnExceptions, - shouldIgnoreCaughtExceptions, - [PROMISE]: client.pauseOnExceptions( - shouldPauseOnExceptions, - shouldIgnoreCaughtExceptions - ) - }); - }; -} - -/** - * Debugger commands like stepOver, stepIn, stepUp - * - * @param string $0.type - * @memberof actions/pause - * @static - */ -function command({ type }: CommandType) { - return ({ dispatch, client }: ThunkArgs) => { - // execute debugger thread command e.g. stepIn, stepOver - client[type](); - - return dispatch({ - type: constants.COMMAND, - value: undefined - }); - }; -} - -/** - * StepIn - * @memberof actions/pause - * @static - * @returns {Function} {@link command} - */ -function stepIn() { - return ({ dispatch, getState }: ThunkArgs) => { - if (getPause(getState())) { - return dispatch(command({ type: "stepIn" })); - } - }; -} - -/** - * stepOver - * @memberof actions/pause - * @static - * @returns {Function} {@link command} - */ -function stepOver() { - return ({ dispatch, getState }: ThunkArgs) => { - if (getPause(getState())) { - return dispatch(command({ type: "stepOver" })); - } - }; -} - -/** - * stepOut - * @memberof actions/pause - * @static - * @returns {Function} {@link command} - */ -function stepOut() { - return ({ dispatch, getState }: ThunkArgs) => { - if (getPause(getState())) { - return dispatch(command({ type: "stepOut" })); - } - }; -} - -/** - * resume - * @memberof actions/pause - * @static - * @returns {Function} {@link command} - */ -function resume() { - return ({ dispatch, getState }: ThunkArgs) => { - if (getPause(getState())) { - return dispatch(command({ type: "resume" })); - } - }; -} - -/** - * Debugger breakOnNext command. - * It's different from the comand action because we also want to - * highlight the pause icon. - * - * @memberof actions/pause - * @static - */ -function breakOnNext() { - return ({ dispatch, client }: ThunkArgs) => { - client.breakOnNext(); - - return dispatch({ - type: constants.BREAK_ON_NEXT, - value: true - }); - }; -} - -/** - * Select a frame - * - * @param frame - * @memberof actions/pause - * @static - */ -function selectFrame(frame: Frame) { - return ({ dispatch }: ThunkArgs) => { - dispatch(selectSource(frame.location.sourceId, - { line: frame.location.line })); - dispatch({ - type: constants.SELECT_FRAME, - frame - }); - }; -} - -/** - * Load an object. - * - * @param grip - * TODO: Right now this if Firefox specific and is not implemented - * for Chrome, which is why it takes a grip. - * @memberof actions/pause - * @static - */ -function loadObjectProperties(grip: Grip) { - return ({ dispatch, client }: ThunkArgs) => { - dispatch({ - type: constants.LOAD_OBJECT_PROPERTIES, - objectId: grip.actor, - [PROMISE]: client.getProperties(grip) - }); - }; -} - -/** - * Add expression for debugger to watch - * - * @param {object} expression - * @param {number} expression.id - * @memberof actions/pause - * @static - */ -function addExpression(expression: Expression) { - return ({ dispatch, getState }: ThunkArgs) => { - const id = expression.id !== undefined ? parseInt(expression.id, 10) : - getExpressions(getState()).toSeq().size++; - dispatch({ - type: constants.ADD_EXPRESSION, - id: id, - input: expression.input - }); - dispatch(evaluateExpressions()); - }; -} - -/** - * - * @param {object} expression - * @param {number} expression.id - * @memberof actions/pause - * @static - */ -function updateExpression(expression: Expression) { - return ({ dispatch }: ThunkArgs) => { - dispatch({ - type: constants.UPDATE_EXPRESSION, - id: expression.id, - input: expression.input - }); - }; -} - -/** - * - * @param {object} expression - * @param {number} expression.id - * @memberof actions/pause - * @static - */ -function deleteExpression(expression: Expression) { - return ({ dispatch }: ThunkArgs) => { - dispatch({ - type: constants.DELETE_EXPRESSION, - id: expression.id - }); - }; -} - -/** - * - * @memberof actions/pause - * @static - */ -function evaluateExpressions() { - return async function({ dispatch, getState, client }: ThunkArgs) { - const selectedFrame = getSelectedFrame(getState()); - if (!selectedFrame) { - return; - } - - const frameId = selectedFrame.id; - - for (let expression of getExpressions(getState())) { - await dispatch({ - type: constants.EVALUATE_EXPRESSION, - id: expression.id, - input: expression.input, - [PROMISE]: client.evaluate(expression.input, { frameId }) - }); - } - }; -} - -module.exports = { - addExpression, - updateExpression, - deleteExpression, - evaluateExpressions, - resumed, - paused, - pauseOnExceptions, - command, - stepIn, - stepOut, - stepOver, - resume, - breakOnNext, - selectFrame, - loadObjectProperties -}; diff --git a/src/actions/sources.js b/src/actions/sources.js deleted file mode 100644 index 44ff61fc41..0000000000 --- a/src/actions/sources.js +++ /dev/null @@ -1,356 +0,0 @@ -// @flow - -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/** - * Redux actions for the sources state - * @module actions/sources - */ - -const defer = require("../utils/defer"); -const { PROMISE } = require("../utils/redux/middleware/promise"); -const assert = require("../utils/assert"); -const { updateFrameLocations } = require("../utils/pause"); -const { - getOriginalURLs, getOriginalSourceText, - generatedToOriginalId, isOriginalId, - isGeneratedId, applySourceMap, shouldSourceMap -} = require("../utils/source-map"); - -const { prettyPrint } = require("../utils/pretty-print"); -const { getPrettySourceURL } = require("../utils/source"); - -const constants = require("../constants"); -const { removeDocument } = require("../utils/source-documents"); - -const { - getSource, getSourceByURL, getSourceText, - getPendingSelectedLocation, getFrames -} = require("../selectors"); - -import type { Source } from "../types"; -import type { ThunkArgs } from "./types"; - -/** - * Handler for the debugger client's unsolicited newSource notification. - * @memberof actions/sources - * @static - */ -function newSource(source: Source) { - return ({ dispatch, getState }: ThunkArgs) => { - if (shouldSourceMap()) { - dispatch(loadSourceMap(source)); - } - - dispatch({ - type: constants.ADD_SOURCE, - source - }); - - // If a request has been made to show this source, go ahead and - // select it. - const pendingLocation = getPendingSelectedLocation(getState()); - if (pendingLocation && pendingLocation.url === source.url) { - dispatch(selectSource(source.id, { line: pendingLocation.line })); - } - }; -} - -function newSources(sources: Source[]) { - return ({ dispatch, getState }: ThunkArgs) => { - sources.filter(source => !getSource(getState(), source.id)) - .forEach(source => dispatch(newSource(source))); - }; -} - -/** - * @memberof actions/sources - * @static - */ -function loadSourceMap(generatedSource) { - return async function({ dispatch, getState }: ThunkArgs) { - const urls = await getOriginalURLs(generatedSource); - if (!urls) { - // If this source doesn't have a sourcemap, do nothing. - return; - } - - const originalSources = urls.map(originalUrl => { - return { - url: originalUrl, - id: generatedToOriginalId(generatedSource.id, originalUrl), - isPrettyPrinted: false - }; - }); - - originalSources.forEach(s => dispatch(newSource(s))); - }; -} - -type SelectSourceOptions = { - tabIndex?: number, - line?: number -}; - -/** - * Deterministically select a source that has a given URL. This will - * work regardless of the connection status or if the source exists - * yet. This exists mostly for external things to interact with the - * debugger. - * - * @memberof actions/sources - * @static - */ -function selectSourceURL(url: string, options: SelectSourceOptions = {}) { - return ({ dispatch, getState }: ThunkArgs) => { - const source = getSourceByURL(getState(), url); - if (source) { - dispatch(selectSource(source.get("id"), options)); - } else { - dispatch({ - type: constants.SELECT_SOURCE_URL, - url: url, - tabIndex: options.tabIndex, - line: options.line - }); - } - }; -} - -/** - * @memberof actions/sources - * @static - */ -function selectSource(id: string, options: SelectSourceOptions = {}) { - return ({ dispatch, getState, client }: ThunkArgs) => { - if (!client) { - // No connection, do nothing. This happens when the debugger is - // shut down too fast and it tries to display a default source. - return; - } - - const source = getSource(getState(), id).toJS(); - - // Make sure to start a request to load the source text. - dispatch(loadSourceText(source)); - - dispatch({ type: constants.TOGGLE_FILE_SEARCH, searchOn: false }); - - dispatch({ - type: constants.SELECT_SOURCE, - source: source, - tabIndex: options.tabIndex, - line: options.line - }); - }; -} - -/** - * @memberof actions/sources - * @static - */ -function closeTab(id: string) { - removeDocument(id); - return { - type: constants.CLOSE_TAB, - id: id, - }; -} - -/** - * @memberof actions/sources - * @static - */ -function closeTabs(ids: string[]) { - ids.forEach(removeDocument); - return { - type: constants.CLOSE_TABS, - ids: ids, - }; -} - -/** - * Toggle the pretty printing of a source's text. All subsequent calls to - * |getText| will return the pretty-toggled text. Nothing will happen for - * non-javascript files. - * - * @memberof actions/sources - * @static - * @param string id The source form from the RDP. - * @returns Promise - * A promise that resolves to [aSource, prettyText] or rejects to - * [aSource, error]. - */ -function togglePrettyPrint(sourceId: string) { - return ({ dispatch, getState, client }: ThunkArgs) => { - const source = getSource(getState(), sourceId).toJS(); - const sourceText = getSourceText(getState(), sourceId).toJS(); - - if (sourceText.loading) { - return {}; - } - - assert(isGeneratedId(sourceId), - "Pretty-printing only allowed on generated sources"); - - const url = getPrettySourceURL(source.url); - const id = generatedToOriginalId(source.id, url); - const originalSource = { url, id, isPrettyPrinted: false }; - dispatch({ - type: constants.ADD_SOURCE, - source: originalSource - }); - - return dispatch({ - type: constants.TOGGLE_PRETTY_PRINT, - source: originalSource, - [PROMISE]: (async function() { - const { code, mappings } = await prettyPrint({ - source, sourceText, url - }); - await applySourceMap(source.id, url, code, mappings); - - const frames = await updateFrameLocations(getFrames(getState())); - dispatch(selectSource(originalSource.id)); - - return { - text: code, - contentType: "text/javascript", - frames - }; - })() - }); - }; -} - -/** - * @memberof actions/sources - * @static - */ -function loadSourceText(source: Source) { - return ({ dispatch, getState, client }: ThunkArgs) => { - // Fetch the source text only once. - let textInfo = getSourceText(getState(), source.id); - if (textInfo) { - // It's already loaded or is loading - return Promise.resolve(textInfo); - } - - return dispatch({ - type: constants.LOAD_SOURCE_TEXT, - source: source, - [PROMISE]: (async function() { - if (isOriginalId(source.id)) { - return await getOriginalSourceText(source); - } - - const response = await client.sourceContents(source.id); - return { - text: response.source, - contentType: response.contentType || "text/javascript" - }; - - // Automatically pretty print if enabled and the test is - // detected to be "minified" - // if (Prefs.autoPrettyPrint && - // !source.isPrettyPrinted && - // SourceUtils.isMinified(source.id, response.source)) { - // dispatch(togglePrettyPrint(source)); - // } - })() - }); - }; -} - -// delay is in ms -const FETCH_SOURCE_RESPONSE_DELAY = 200; - -/** - * Starts fetching all the sources, silently. - * - * @memberof actions/sources - * @static - * @param array actors - * The urls for the sources to fetch. If fetching a source's text - * takes too long, it will be discarded. - * @returns {Promise} - * A promise that is resolved after source texts have been fetched. - */ -function getTextForSources(actors: any[]) { - return ({ dispatch, getState }: ThunkArgs) => { - let deferred = defer(); - let pending = new Set(actors); - type FetchedSourceType = [any, string, string]; - let fetched: FetchedSourceType[] = []; - - // Can't use promise.all, because if one fetch operation is rejected, then - // everything is considered rejected, thus no other subsequent source will - // be getting fetched. We don't want that. Something like Q's allSettled - // would work like a charm here. - - // Try to fetch as many sources as possible. - for (let actor of actors) { - let source = getSource(getState(), actor); - dispatch(loadSourceText(source)).then(({ text, contentType }) => { - onFetch([source, text, contentType]); - }, err => { - onError(source, err); - }); - } - - setTimeout(onTimeout, FETCH_SOURCE_RESPONSE_DELAY); - - /* Called if fetching a source takes too long. */ - function onTimeout() { - pending = new Set(); - maybeFinish(); - } - - /* Called if fetching a source finishes successfully. */ - function onFetch([aSource, aText, aContentType]: FetchedSourceType) { - // If fetching the source has previously timed out, discard it this time. - if (!pending.has(aSource.actor)) { - return; - } - pending.delete(aSource.actor); - fetched.push([aSource.actor, aText, aContentType]); - maybeFinish(); - } - - /* Called if fetching a source failed because of an error. */ - function onError([aSource, aError]) { - pending.delete(aSource.actor); - maybeFinish(); - } - - /* Called every time something interesting - * happens while fetching sources. - */ - function maybeFinish() { - if (pending.size == 0) { - // Sort the fetched sources alphabetically by their url. - if (deferred) { - deferred.resolve( - fetched.sort(([aFirst], [aSecond]) => aFirst > aSecond ? -1 : 1) - ); - } - } - } - - return deferred.promise; - }; -} - -module.exports = { - newSource, - newSources, - selectSource, - selectSourceURL, - closeTab, - closeTabs, - togglePrettyPrint, - loadSourceText, - getTextForSources -}; diff --git a/src/actions/tests/.eslintrc b/src/actions/tests/.eslintrc deleted file mode 100644 index e100bed599..0000000000 --- a/src/actions/tests/.eslintrc +++ /dev/null @@ -1,9 +0,0 @@ -{ - "env": { - "mocha": true - }, - "rules": { - "camelcase": 0, - "max-nested-callbacks": [2, 4], - } -} diff --git a/src/actions/tests/breakpoints.js b/src/actions/tests/breakpoints.js deleted file mode 100644 index 79bfe0b8fe..0000000000 --- a/src/actions/tests/breakpoints.js +++ /dev/null @@ -1,22 +0,0 @@ -const { createStore, selectors, actions } = require("../../utils/test-head"); -const { Task } = require("../../utils/task"); -const expect = require("expect.js"); - -const simpleMockThreadClient = { - setBreakpoint: (location, condition) => { - return new Promise((resolve, reject) => { - resolve({ id: "hi", actualLocation: location }); - }); - } -}; - -describe("breakpoints", () => { - it("should add a breakpoint", () => { - return Task.spawn(function* () { - const store = createStore(simpleMockThreadClient); - yield store.dispatch(actions.addBreakpoint({ sourceId: "a", line: 5 })); - yield store.dispatch(actions.addBreakpoint({ sourceId: "b", line: 6 })); - expect(selectors.getBreakpoints(store.getState()).size).to.be(2); - }); - }); -}); diff --git a/src/actions/tests/sources.js b/src/actions/tests/sources.js deleted file mode 100644 index 6509028207..0000000000 --- a/src/actions/tests/sources.js +++ /dev/null @@ -1,259 +0,0 @@ -const expect = require("expect.js"); -const { Task } = require("../../utils/task"); -const { - actions, selectors, createStore, makeSource, - waitForState -} = require("../../utils/test-head"); -const { - getSourceByURL, getSourceById, getSources, getSelectedSource, - getSourceText, getSourceTabs -} = selectors; -const sourceMap = require("../../utils/source-map"); - -const threadClient = { - sourceContents: function(sourceId) { - return new Promise((resolve, reject) => { - switch (sourceId) { - case "foo1": - resolve({ - source: "function() {\n return 5;\n}", - contentType: "text/javascript" - }); - break; - case "foo2": - resolve({ - source: "function(x, y) {\n return x + y;\n}", - contentType: "text/javascript" - }); - break; - } - - reject("unknown source: " + sourceId); - }); - } -}; - -process.on("unhandledRejection", (reason, p) => {}); - -// Create a sourcemapped source that all the sourcemap tests can use. -const bundleSource = makeSource("bundle.js", { - sourceMapURL: "bundle.js.map" -}); - -describe("sources", () => { - it("should add sources to state", () => { - const { dispatch, getState } = createStore(); - dispatch(actions.newSource(makeSource("base.js"))); - dispatch(actions.newSource(makeSource("jquery.js"))); - - expect(getSources(getState()).size).to.equal(2); - const base = getSourceById(getState(), "base.js"); - const jquery = getSourceById(getState(), "jquery.js"); - expect(base.get("id")).to.equal("base.js"); - expect(jquery.get("id")).to.equal("jquery.js"); - }); - - it("should select a source", () => { - // Note that we pass an empty client in because the action checks - // if it exists. - const { dispatch, getState } = createStore({}); - - dispatch(actions.newSource(makeSource("foo.js"))); - dispatch(actions.selectSource("foo.js")); - expect(getSelectedSource(getState()).get("id")).to.equal("foo.js"); - }); - - it("should automatically select a pending source", () => { - const { dispatch, getState } = createStore({}); - const baseSource = makeSource("base.js"); - dispatch(actions.selectSourceURL(baseSource.url)); - - expect(getSelectedSource(getState())).to.be(undefined); - dispatch(actions.newSource(baseSource)); - expect(getSelectedSource(getState()).get("url")).to.be(baseSource.url); - }); - - it("should open a tab for the source", () => { - const { dispatch, getState } = createStore({}); - dispatch(actions.newSource(makeSource("foo.js"))); - dispatch(actions.selectSource("foo.js")); - - const tabs = getSourceTabs(getState()); - expect(tabs.size).to.equal(1); - expect(tabs.getIn([0, "id"])).to.equal("foo.js"); - }); - - it("should select previous tab on tab closed", () => { - const { dispatch, getState } = createStore({}); - dispatch(actions.newSource(makeSource("foo.js"))); - dispatch(actions.newSource(makeSource("bar.js"))); - dispatch(actions.newSource(makeSource("baz.js"))); - dispatch(actions.selectSource("foo.js")); - dispatch(actions.selectSource("bar.js")); - dispatch(actions.selectSource("baz.js")); - dispatch(actions.closeTab("baz.js")); - expect(getSelectedSource(getState()).get("id")).to.be("bar.js"); - expect(getSourceTabs(getState()).size).to.be(2); - }); - - it("should select next tab on tab closed if no previous tab", () => { - const { dispatch, getState } = createStore({}); - dispatch(actions.newSource(makeSource("foo.js"))); - dispatch(actions.newSource(makeSource("bar.js"))); - dispatch(actions.newSource(makeSource("baz.js"))); - dispatch(actions.selectSource("foo.js")); - dispatch(actions.selectSource("bar.js")); - dispatch(actions.selectSource("baz.js")); - dispatch(actions.selectSource("foo.js")); - dispatch(actions.closeTab("foo.js")); - expect(getSelectedSource(getState()).get("id")).to.be("bar.js"); - expect(getSourceTabs(getState()).size).to.be(2); - }); - - it("should load source text", Task.async(function* () { - const { dispatch, getState } = createStore(threadClient); - - yield dispatch(actions.loadSourceText({ id: "foo1" })); - const fooSourceText = getSourceText(getState(), "foo1"); - expect(fooSourceText.get("text").indexOf("return 5")).to.not.be(-1); - - yield dispatch(actions.loadSourceText({ id: "foo2" })); - const foo2SourceText = getSourceText(getState(), "foo2"); - expect(foo2SourceText.get("text").indexOf("return x + y")).to.not.be(-1); - })); - - it("should cache subsequent source text loads", Task.async(function* () { - const { dispatch, getState } = createStore(threadClient); - - yield dispatch(actions.loadSourceText({ id: "foo1" })); - const prevText = getSourceText(getState(), "foo1"); - - yield dispatch(actions.loadSourceText({ id: "foo1" })); - const curText = getSourceText(getState(), "foo1"); - - expect(prevText === curText).to.be.ok(); - })); - - it("should indicate a loading source text", Task.async(function*() { - const { dispatch, getState } = createStore(threadClient); - - // Don't block on this so we can check the loading state. - dispatch(actions.loadSourceText({ id: "foo1" })); - const fooSourceText = getSourceText(getState(), "foo1"); - expect(fooSourceText.get("loading")).to.equal(true); - })); - - it("should indicate an errored source text", Task.async(function* () { - const { dispatch, getState } = createStore(threadClient); - - yield dispatch(actions.loadSourceText({ id: "bad-id" })).catch(() => {}); - const badText = getSourceText(getState(), "bad-id"); - expect(badText.get("error").indexOf("unknown source")).to.not.be(-1); - })); - - it("should download a sourcemap and create sources", Task.async(function* () { - const store = createStore(); - const { dispatch, getState } = store; - dispatch(actions.newSource(bundleSource)); - yield waitForState(store, state => getSourceByURL(state, "webpack:///entry.js")); - - expect(getSources(getState()).size).to.be(6); - const entrySource = getSourceByURL(getState(), "webpack:///entry.js"); - const times2Source = getSourceByURL(getState(), "webpack:///times2.js"); - const optsSource = getSourceByURL(getState(), "webpack:///opts.js"); - - expect(entrySource).to.be.ok(); - expect(times2Source).to.be.ok(); - expect(optsSource).to.be.ok(); - expect(sourceMap.isGeneratedId(bundleSource.id)).to.be.ok(); - expect(sourceMap.isOriginalId(entrySource.get("id"))).to.be.ok(); - expect(sourceMap.isOriginalId(times2Source.get("id"))).to.be.ok(); - expect(sourceMap.isOriginalId(optsSource.get("id"))).to.be.ok(); - })); -}); - -describe("closing tabs", () => { - it("closing a tab", () => { - const { dispatch, getState } = createStore({}); - dispatch(actions.newSource(makeSource("foo.js"))); - dispatch(actions.selectSource("foo.js")); - dispatch(actions.closeTab("foo.js")); - - expect(getSelectedSource(getState())).to.be(undefined); - expect(getSourceTabs(getState()).size).to.be(0); - }); - - it("closing the inactive tab", () => { - const { dispatch, getState } = createStore({}); - dispatch(actions.newSource(makeSource("foo.js"))); - dispatch(actions.newSource(makeSource("bar.js"))); - dispatch(actions.selectSource("foo.js")); - dispatch(actions.selectSource("bar.js")); - dispatch(actions.closeTab("foo.js")); - - expect(getSelectedSource(getState()).get("id")).to.be("bar.js"); - expect(getSourceTabs(getState()).size).to.be(1); - }); - - it("closing the only tab", () => { - const { dispatch, getState } = createStore({}); - dispatch(actions.newSource(makeSource("foo.js"))); - dispatch(actions.selectSource("foo.js")); - dispatch(actions.closeTab("foo.js")); - - expect(getSelectedSource(getState())).to.be(undefined); - expect(getSourceTabs(getState()).size).to.be(0); - }); - - it("closing the active tab", () => { - const { dispatch, getState } = createStore({}); - dispatch(actions.newSource(makeSource("foo.js"))); - dispatch(actions.newSource(makeSource("bar.js"))); - dispatch(actions.selectSource("foo.js")); - dispatch(actions.selectSource("bar.js")); - dispatch(actions.closeTab("bar.js")); - - expect(getSelectedSource(getState()).get("id")).to.be("foo.js"); - expect(getSourceTabs(getState()).size).to.be(1); - }); - - it("closing many inactive tabs", () => { - const { dispatch, getState } = createStore({}); - dispatch(actions.newSource(makeSource("foo.js"))); - dispatch(actions.newSource(makeSource("bar.js"))); - dispatch(actions.newSource(makeSource("bazz.js"))); - dispatch(actions.selectSource("foo.js")); - dispatch(actions.selectSource("bar.js")); - dispatch(actions.selectSource("bazz.js")); - dispatch(actions.closeTabs(["foo.js", "bar.js"])); - - expect(getSelectedSource(getState()).get("id")).to.be("bazz.js"); - expect(getSourceTabs(getState()).size).to.be(1); - }); - - it("closing many tabs including the active tab", () => { - const { dispatch, getState } = createStore({}); - dispatch(actions.newSource(makeSource("foo.js"))); - dispatch(actions.newSource(makeSource("bar.js"))); - dispatch(actions.newSource(makeSource("bazz.js"))); - dispatch(actions.selectSource("foo.js")); - dispatch(actions.selectSource("bar.js")); - dispatch(actions.selectSource("bazz.js")); - dispatch(actions.closeTabs(["bar.js", "bazz.js"])); - - expect(getSelectedSource(getState()).get("id")).to.be("foo.js"); - expect(getSourceTabs(getState()).size).to.be(1); - }); - - it("closing all the tabs", () => { - const { dispatch, getState } = createStore({}); - dispatch(actions.newSource(makeSource("foo.js"))); - dispatch(actions.newSource(makeSource("bar.js"))); - dispatch(actions.selectSource("foo.js")); - dispatch(actions.selectSource("bar.js")); - dispatch(actions.closeTabs(["foo.js", "bar.js"])); - - expect(getSelectedSource(getState())).to.be(undefined); - expect(getSourceTabs(getState()).size).to.be(0); - }); -}); diff --git a/src/actions/tests/ui.js b/src/actions/tests/ui.js deleted file mode 100644 index bea03c4959..0000000000 --- a/src/actions/tests/ui.js +++ /dev/null @@ -1,13 +0,0 @@ -const { createStore, selectors, actions } = require("../../utils/test-head"); -const expect = require("expect.js"); - -const { getFileSearchState } = selectors; - -describe("ui", () => { - it("should toggle the visible state of file search", () => { - const { dispatch, getState } = createStore(); - expect(getFileSearchState(getState())).to.be(false); - dispatch(actions.toggleFileSearch(true)); - expect(getFileSearchState(getState())).to.be(true); - }); -}); diff --git a/src/actions/types.js b/src/actions/types.js deleted file mode 100644 index fb1e687030..0000000000 --- a/src/actions/types.js +++ /dev/null @@ -1,145 +0,0 @@ -// @flow - -import type { Source, - Breakpoint, - Location, - SourceText, - Frame, - Why } from "../types"; - -/** - * Flow types - * @module actions/types - */ - -/** - * Argument parameters via Thunk middleware for {@link https://github.com/gaearon/redux-thunk|Redux Thunk} - * - * @memberof actions/breakpoints - * @static - * @typedef {Object} ThunkArgs - */ -export type ThunkArgs = { - dispatch: () => Promise, - getState: () => any, - client: any -}; - -/** - * Tri-state status for async operations - * - * Available options are: - * `"start"` or `"done"` or `"error"` - * - * @memberof actions/types - * @static - * @enum - */ -export type AsyncStatus = "start" | "done" | "error"; - -type BreakpointResult = { - actualLocation: Location, - id: string, - text: string -} - -type BreakpointAction = - { type: "ADD_BREAKPOINT", - breakpoint: Breakpoint, - condition: string, - status: AsyncStatus, - error: string, - value: BreakpointResult} - | { type: "REMOVE_BREAKPOINT", - breakpoint: Breakpoint, - status: AsyncStatus, - error: string, - disabled: boolean } - | { type: "SET_BREAKPOINT_CONDITION", - breakpoint: Breakpoint, - condition: string, - status: AsyncStatus, - value: BreakpointResult, - error: string } - | { type: "TOGGLE_BREAKPOINTS", - shouldDisableBreakpoints: boolean, - status: AsyncStatus, - error: string, - value: any }; - -type SourceAction = - { type: "ADD_SOURCE", source: Source } - | { type: "SELECT_SOURCE", source: Source, - line?: number, - tabIndex?: number } - | { type: "SELECT_SOURCE_URL", url: string, line?: number } - | { type: "LOAD_SOURCE_TEXT", - source: Source, - status: AsyncStatus, - error: string, - value: SourceText } - | { type: "BLACKBOX", - source: Source, - status: AsyncStatus, - error: string, - value: { isBlackBoxed: boolean }} - | { type: "TOGGLE_PRETTY_PRINT", - source: Source, - originalSource: Source, - status: AsyncStatus, - error: string, - value: { isPrettyPrinted: boolean, - sourceText: SourceText, - frames: Frame[] }} - | { type: "CLOSE_TAB", id: string }; - -type UIAction = { type: "TOGGLE_FILE_SEARCH", searchOn: boolean }; - -type PauseAction = - { type: "BREAK_ON_NEXT", value: boolean } - | { type: "RESUME", value: void } - | { type: "PAUSED", - pauseInfo: { why: Why, - frame: Frame, - isInterrupted?: boolean }, - frames: Frame[], - selectedFrameId: string, - } - | { type: "PAUSE_ON_EXCEPTIONS", - shouldPauseOnExceptions: boolean, - shouldIgnoreCaughtExceptions: boolean } - | { type: "COMMAND", value: void } - | { type: "SELECT_FRAME", frame: Frame } - | { type: "LOAD_OBJECT_PROPERTIES", - objectId: string, - status: string, - value: Object, - "@@dispatch/promise": any } - | { type: "ADD_EXPRESSION", - id: number, - input: string, - value: string } - | { type: "EVALUATE_EXPRESSION", - id: number, - input: string, - status: string, - value: Object, - "@@dispatch/promise": any } - | { type: "UPDATE_EXPRESSION", - id: number, - input: string } - | { type: "DELETE_EXPRESSION", - id: number }; - -/** - * Actions: Source, Breakpoint, and Navigation - * - * @memberof actions/types - * @static - */ -export type Action = - SourceAction - | BreakpointAction - | PauseAction - | { type: "NAVIGATE" } - | UIAction; diff --git a/src/actions/ui.js b/src/actions/ui.js deleted file mode 100644 index 960b6f7d75..0000000000 --- a/src/actions/ui.js +++ /dev/null @@ -1,13 +0,0 @@ -// @flow -const constants = require("../constants"); - -function toggleFileSearch(searchOn: boolean) { - return { - type: constants.TOGGLE_FILE_SEARCH, - searchOn - }; -} - -module.exports = { - toggleFileSearch -}; diff --git a/src/components/Accordion.css b/src/components/Accordion.css deleted file mode 100644 index baa2379d60..0000000000 --- a/src/components/Accordion.css +++ /dev/null @@ -1,33 +0,0 @@ -.accordion { - background-color: var(--theme-body-background); - width: 100%; -} - -.accordion ._header { - background-color: var(--theme-toolbar-background); - border-bottom: 1px solid var(--theme-splitter-color); - cursor: pointer; - font-size: 12px; - padding: 5px; - transition: all 0.25s ease; - width: 100%; - - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - -o-user-select: none; - user-select: none; -} - -.accordion ._header:hover { - background-color: var(--theme-search-overlays-semitransparent); -} - -.accordion ._header:hover svg { - fill: var(--theme-comment-alt); -} - -.accordion ._content { - border-bottom: 1px solid var(--theme-splitter-color); - font-size: 12px; -} diff --git a/src/components/Accordion.js b/src/components/Accordion.js deleted file mode 100644 index 878a587677..0000000000 --- a/src/components/Accordion.js +++ /dev/null @@ -1,75 +0,0 @@ -const React = require("react"); -const { DOM: dom, PropTypes } = React; - -const { div, span } = dom; -const Svg = require("./utils/Svg"); - -require("./Accordion.css"); - -const Accordion = React.createClass({ - propTypes: { - items: PropTypes.array - }, - - displayName: "Accordion", - - getInitialState: function() { - return { opened: this.props.items.map(item => item.opened), - created: [] }; - }, - - handleHeaderClick: function(i) { - const opened = [...this.state.opened]; - const created = [...this.state.created]; - const item = this.props.items[i]; - - opened[i] = !opened[i]; - created[i] = true; - - if (opened[i] && item.onOpened) { - item.onOpened(); - } - - this.setState({ opened, created }); - }, - - renderContainer: function(item, i) { - const { opened, created } = this.state; - const containerClassName = - `${item.header.toLowerCase().replace(/\s/g, "-")}-pane`; - - return div( - { className: containerClassName, key: i }, - - div( - { className: "_header", - onClick: () => this.handleHeaderClick(i) }, - Svg("arrow", { className: opened[i] ? "expanded" : "" }), - item.header, - item.buttons ? - dom.button({ className: "header-buttons" }, - item.buttons.map((button, id) => span({ key: id }, button)) - ) : - null - ), - - (created[i] || opened[i]) ? - div( - { className: "_content", - style: { display: opened[i] ? "block" : "none" } - }, - React.createElement(item.component, item.componentProps || {}) - ) : - null - ); - }, - - render: function() { - return div( - { className: "accordion" }, - this.props.items.map(this.renderContainer) - ); - } -}); - -module.exports = Accordion; diff --git a/src/components/App.css b/src/components/App.css deleted file mode 100644 index 8f1d346584..0000000000 --- a/src/components/App.css +++ /dev/null @@ -1,94 +0,0 @@ -/* vim:set ts=2 sw=2 sts=2 et: */ - -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -:root.theme-light, -:root .theme-light { - --theme-search-overlays-semitransparent: rgba(221, 225, 228, 0.66); - --theme-faded-tab-color: #7e7e7e; -} - -:root.theme-dark, -:root .theme-dark { - --theme-faded-tab-color: #6e7d8c; -} - -* { - box-sizing: border-box; -} - -html, -body { - height: 100%; - margin: 0; - padding: 0; - width: 100%; -} - -#mount { - display: flex; - height: 100%; -} - -.debugger { - display: flex; - flex: 1; - height: 100%; -} - -.center-pane { - display: flex; - position: relative; - flex: 1; - background-color: var(--theme-tab-toolbar-background); - overflow: hidden; -} - -.editor-container { - display: flex; - flex: 1; -} - -.subsettings:hover { - cursor: pointer; -} - -.search-container { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - display: flex; - z-index: 200; - background-color: var(--theme-search-overlays-semitransparent); -} - -.search-container .autocomplete { - flex: 1; -} - -.search-container .close-button { - width: 16px; - margin-top: 25px; - margin-right: 20px; -} - -.welcomebox { - width: calc(100% - 1px); - - /* Offsetting it by 30px for the sources-header area */ - height: calc(100% - 30px); - position: absolute; - top: 30px; - left: 0; - padding: 50px 0; - text-align: center; - font-size: 1.25em; - color: var(--theme-comment-alt); - background-color: var(--theme-tab-toolbar-background); - font-weight: lighter; - z-index: 100; -} diff --git a/src/components/App.js b/src/components/App.js deleted file mode 100644 index 6cb1684202..0000000000 --- a/src/components/App.js +++ /dev/null @@ -1,93 +0,0 @@ -const React = require("react"); -const { DOM: dom, PropTypes, createFactory } = React; -const { connect } = require("react-redux"); -const { bindActionCreators } = require("redux"); -const { cmdString } = require("../utils/text"); -const actions = require("../actions"); -const { getSources, getSelectedSource } = require("../selectors"); - -const { KeyShortcuts } = require("devtools-sham-modules"); -const shortcuts = new KeyShortcuts({ window }); - -const cmd = `${cmdString()}+P`; - -require("./App.css"); -require("./menu.css"); -require("./SplitBox.css"); -require("./reps.css"); -let { SplitBox } = require("devtools-modules"); -SplitBox = createFactory(SplitBox); - -const SourceSearch = createFactory(require("./SourceSearch")); -const Sources = createFactory(require("./Sources")); -const Editor = createFactory(require("./Editor")); -const RightSidebar = createFactory(require("./RightSidebar")); -const SourceTabs = createFactory(require("./SourceTabs")); - -const App = React.createClass({ - propTypes: { - sources: PropTypes.object, - selectSource: PropTypes.func, - selectedSource: PropTypes.object, - }, - - displayName: "App", - - getChildContext() { - return { shortcuts }; - }, - - renderWelcomeBox() { - return dom.div( - { className: "welcomebox" }, - L10N.getFormatStr("welcome.search", cmd) - ); - }, - - renderCenterPane() { - return dom.div( - { className: "center-pane" }, - dom.div( - { className: "editor-container" }, - SourceTabs(), - Editor(), - !this.props.selectedSource ? this.renderWelcomeBox() : null, - SourceSearch() - ) - ); - }, - - render: function() { - return dom.div( - { className: "debugger" }, - SplitBox({ - style: { width: "100vw" }, - initialSize: "300px", - minSize: 10, - maxSize: "50%", - splitterSize: 1, - startPanel: Sources({ sources: this.props.sources }), - endPanel: SplitBox({ - initialSize: "300px", - minSize: 10, - maxSize: "80%", - splitterSize: 1, - endPanelControl: true, - startPanel: this.renderCenterPane(this.props), - endPanel: RightSidebar() - }) - }) - ); - } -}); - -App.childContextTypes = { - shortcuts: PropTypes.object -}; - -module.exports = connect( - state => ({ sources: getSources(state), - selectedSource: getSelectedSource(state), - }), - dispatch => bindActionCreators(actions, dispatch) -)(App); diff --git a/src/components/Autocomplete.css b/src/components/Autocomplete.css deleted file mode 100644 index 4a3fcef548..0000000000 --- a/src/components/Autocomplete.css +++ /dev/null @@ -1,106 +0,0 @@ - -.autocomplete { - width: 100%; -} - -.autocomplete .results * { - -moz-user-select: none; - user-select: none; -} - -.autocomplete .results-summary { - margin: 10px; -} - -.autocomplete ul { - list-style: none; - width: 100%; - max-height: calc(100% - 32px); - margin: 0px; - padding: 0px; - overflow: auto; -} - -.autocomplete li { - border: 2px solid var(--theme-splitter-color); - background-color: var(--theme-tab-toolbar-background); - padding: 10px; - margin: 10px; -} - -.autocomplete li:hover { - background: var(--theme-tab-toolbar-background); - cursor: pointer; -} - -.autocomplete li.selected { - border: 2px solid var(--theme-selection-background); -} - -.autocomplete li .title { - line-height: 1.5em; - word-break: break-all; -} - -.autocomplete li .subtitle { - line-height: 1.5em; - color: grey; - word-break: break-all; -} - -.autocomplete input { - width: 100%; - border: none; - background-color: var(--theme-body-background); - color: var(--theme-comment); - border-bottom: 1px solid var(--theme-splitter-color); - outline: none; - line-height: 30px; - font-size: 14px; - height: 40px; - padding-left: 30px; -} - -.autocomplete input::placeholder { - color: var(--theme-body-color-inactive); -} - -.autocomplete .magnifying-glass svg { - width: 16px; - position: absolute; - top: 12px; - left: 10px; -} - -.autocomplete.focused .magnifying-glass path, -.autocomplete.focused .magnifying-glass ellipse { - stroke: var(--theme-highlight-blue); -} - -.autocomplete .magnifying-glass path, -.autocomplete .magnifying-glass ellipse { - stroke: var(--theme-splitter-color); -} - -.autocomplete .no-result-msg { - display: flex; - align-items: center; - justify-content: center; - width: 100%; - height: 100%; - color: var(--theme-graphs-full-red); - font-size: 24px; - padding: 4px; - word-break: break-all; -} - -.autocomplete .no-result-msg .sad-face { - width: 24px; - margin-right: 4px; - line-height: 0; - flex-shrink: 0; -} - -.autocomplete .no-result-msg .sad-face svg { - fill: var(--theme-graphs-full-red); -} diff --git a/src/components/Autocomplete.js b/src/components/Autocomplete.js deleted file mode 100644 index c2d03a1394..0000000000 --- a/src/components/Autocomplete.js +++ /dev/null @@ -1,171 +0,0 @@ -const React = require("react"); -const { DOM: dom, PropTypes } = React; -const { filter } = require("fuzzaldrin-plus"); -const classnames = require("classnames"); -require("./Autocomplete.css"); -const Svg = require("./utils/Svg"); -const CloseButton = require("./CloseButton"); - -const INITIAL_SELECTED_INDEX = 0; - -const Autocomplete = React.createClass({ - propTypes: { - selectItem: PropTypes.func, - items: PropTypes.array, - close: PropTypes.func, - inputValue: PropTypes.string - }, - - displayName: "Autocomplete", - - getInitialState() { - return { - inputValue: this.props.inputValue, - selectedIndex: INITIAL_SELECTED_INDEX - }; - }, - - componentDidMount() { - const endOfInput = this.state.inputValue.length; - this.refs.searchInput.focus(); - this.refs.searchInput.setSelectionRange(endOfInput, endOfInput); - }, - - componentDidUpdate() { - this.scrollList(); - }, - - scrollList() { - const resultsEl = this.refs.results; - if (!resultsEl || resultsEl.children.length === 0) { - return; - } - - const resultsHeight = resultsEl.clientHeight; - const itemHeight = resultsEl.children[0].clientHeight; - const numVisible = resultsHeight / itemHeight; - const positionsToScroll = this.state.selectedIndex - numVisible + 1; - const itemOffset = resultsHeight % itemHeight; - const scroll = positionsToScroll * (itemHeight + 2) + itemOffset; - - resultsEl.scrollTop = Math.max(0, scroll); - }, - - getSearchResults() { - let inputValue = this.state.inputValue; - - if (inputValue == "") { - return []; - } - return filter(this.props.items, this.state.inputValue, { - key: "value" - }); - }, - - onKeyDown(e) { - const searchResults = this.getSearchResults(), - resultCount = searchResults.length; - - if (e.key === "ArrowUp") { - this.setState({ - selectedIndex: Math.max(0, this.state.selectedIndex - 1) - }); - e.preventDefault(); - } else if (e.key === "ArrowDown") { - this.setState({ - selectedIndex: Math.min(resultCount - 1, this.state.selectedIndex + 1) - }); - e.preventDefault(); - } else if (e.key === "Enter") { - if (searchResults.length) { - this.props.selectItem(searchResults[this.state.selectedIndex]); - } else { - this.props.close(this.state.inputValue); - } - e.preventDefault(); - } else if (e.key === "Tab") { - this.props.close(this.state.inputValue); - e.preventDefault(); - } - }, - - renderSearchItem(result, index) { - return dom.li( - { - onClick: () => this.props.selectItem(result), - key: result.value, - className: classnames({ - selected: index === this.state.selectedIndex - }) - }, - dom.div({ className: "title" }, result.title), - dom.div({ className: "subtitle" }, result.subtitle) - ); - }, - - renderInput() { - return dom.input( - { - ref: "searchInput", - value: this.state.inputValue, - onChange: (e) => this.setState({ - inputValue: e.target.value, - selectedIndex: INITIAL_SELECTED_INDEX - }), - onFocus: e => this.setState({ focused: true }), - onBlur: e => this.setState({ focused: false }), - onKeyDown: this.onKeyDown, - placeholder: L10N.getStr("sourceSearch.search") - } - ); - }, - - renderResults(results) { - if (results.length) { - return dom.ul({ className: "results", ref: "results" }, - results.map(this.renderSearchItem)); - } else if (this.state.inputValue && !results.length) { - return dom.div({ className: "no-result-msg" }, - Svg("sad-face"), - L10N.getFormatStr("sourceSearch.noResults", this.state.inputValue) - ); - } - }, - - renderSummary(searchResults) { - if (searchResults && searchResults.length === 0) { - return; - } - - let resultCountSummary = ""; - if (this.state.inputValue) { - resultCountSummary = L10N.getFormatStr( - "sourceSearch.resultsSummary", - searchResults.length, - this.state.inputValue); - } - return dom.div({ className: "results-summary" }, resultCountSummary); - }, - - render() { - const searchResults = this.getSearchResults(); - return dom.div( - { className: - classnames({ - autocomplete: true, - focused: this.state.focused - }) - }, - dom.div({ className: "searchinput-container" }, - Svg("magnifying-glass"), - this.renderInput(), - CloseButton({ - buttonClass: "big", - handleClick: e => this.props.close() - })), - this.renderSummary(searchResults), - this.renderResults(searchResults)); - } -}); - -module.exports = Autocomplete; diff --git a/src/components/Breakpoints.css b/src/components/Breakpoints.css deleted file mode 100644 index 599670008b..0000000000 --- a/src/components/Breakpoints.css +++ /dev/null @@ -1,71 +0,0 @@ -.breakpoints-list * { - -moz-user-select: none; - user-select: none; -} - -.breakpoints-list .breakpoint { - font-size: 12px; - color: var(--theme-content-color1); - padding: 0.5em 1px; - line-height: 1em; - position: relative; - border-left: 4px solid transparent; - transition: all 0.25s ease; -} - -.breakpoints-list .breakpoint:last-of-type { - padding-bottom: 0.45em; -} - -.breakpoints-list .breakpoint.paused { - background-color: var(--theme-toolbar-background-alt); - border-color: var(--breakpoint-active-color); -} - -.breakpoints-list .breakpoint.disabled .breakpoint-label { - color: var(--theme-content-color3); - transition: color 0.5s linear; -} - -.breakpoints-list .breakpoint:hover { - cursor: pointer; - background-color: var(--theme-search-overlays-semitransparent); -} - -.breakpoints-list .breakpoint.paused:hover { - border-color: var(--breakpoint-active-color-hover); -} - -.breakpoints-list .breakpoint-checkbox { - margin-left: 0; -} - -.breakpoints-list .breakpoint-label { - display: inline-block; - padding-left: 2px; - padding-bottom: 4px; -} - -.breakpoints-list .pause-indicator { - flex: 0 1 content; - order: 3; -} - -.breakpoint-snippet { - color: var(--theme-comment); - padding-left: 18px; -} - -.breakpoint .close-btn { - position: absolute; - right: 6px; - top: 12px; -} - -.breakpoint .close { - display: none; -} - -.breakpoint:hover .close { - display: block; -} diff --git a/src/components/Breakpoints.js b/src/components/Breakpoints.js deleted file mode 100644 index 8c79f4d2f9..0000000000 --- a/src/components/Breakpoints.js +++ /dev/null @@ -1,144 +0,0 @@ -const React = require("react"); -const { connect } = require("react-redux"); -const { bindActionCreators } = require("redux"); -const ImPropTypes = require("react-immutable-proptypes"); -const classnames = require("classnames"); -const actions = require("../actions"); -const { getSource, getPause, getBreakpoints } = require("../selectors"); -const { makeLocationId } = require("../reducers/breakpoints"); -const { truncateStr } = require("../utils/utils"); -const { DOM: dom, PropTypes } = React; -const { endTruncateStr } = require("../utils/utils"); -const { basename } = require("../utils/path"); -const CloseButton = require("./CloseButton"); - -require("./Breakpoints.css"); - -function isCurrentlyPausedAtBreakpoint(state, breakpoint) { - const pause = getPause(state); - if (!pause || pause.get("isInterrupted")) { - return false; - } - - const bpId = makeLocationId(breakpoint.location); - const pausedId = makeLocationId( - pause.getIn(["frame", "location"]).toJS() - ); - - return bpId === pausedId; -} - -function renderSourceLocation(source, line) { - const url = source.get("url") ? basename(source.get("url")) : null; - // const line = url !== "" ? `: ${line}` : ""; - return url ? - dom.div( - { className: "location" }, - `${endTruncateStr(url, 30)}: ${line}` - ) : null; -} - -const Breakpoints = React.createClass({ - propTypes: { - breakpoints: ImPropTypes.map.isRequired, - enableBreakpoint: PropTypes.func.isRequired, - disableBreakpoint: PropTypes.func.isRequired, - selectSource: PropTypes.func.isRequired, - removeBreakpoint: PropTypes.func.isRequired - }, - - displayName: "Breakpoints", - - handleCheckbox(breakpoint) { - if (breakpoint.loading) { - return; - } - - if (breakpoint.disabled) { - this.props.enableBreakpoint(breakpoint.location); - } else { - this.props.disableBreakpoint(breakpoint.location); - } - }, - - selectBreakpoint(breakpoint) { - const sourceId = breakpoint.location.sourceId; - const line = breakpoint.location.line; - this.props.selectSource(sourceId, { line }); - }, - - removeBreakpoint(event, breakpoint) { - event.stopPropagation(); - this.props.removeBreakpoint(breakpoint.location); - }, - - renderBreakpoint(breakpoint) { - const snippet = truncateStr(breakpoint.text || "", 30); - const locationId = breakpoint.locationId; - const line = breakpoint.location.line; - const isCurrentlyPaused = breakpoint.isCurrentlyPaused; - const isDisabled = breakpoint.disabled; - - return dom.div( - { - className: classnames({ - breakpoint, - paused: isCurrentlyPaused, - disabled: isDisabled - }), - key: locationId, - onClick: () => this.selectBreakpoint(breakpoint) - }, - dom.input({ - type: "checkbox", - className: "breakpoint-checkbox", - checked: !isDisabled, - onChange: () => this.handleCheckbox(breakpoint), - // Prevent clicking on the checkbox from triggering the onClick of - // the surrounding div - onClick: (ev) => ev.stopPropagation() - }), - dom.div( - { className: "breakpoint-label", title: breakpoint.text }, - dom.div({}, renderSourceLocation(breakpoint.location.source, line)) - ), - dom.div({ className: "breakpoint-snippet" }, snippet), - CloseButton({ - handleClick: (ev) => this.removeBreakpoint(ev, breakpoint) - })); - }, - - render() { - const { breakpoints } = this.props; - return dom.div( - { className: "pane breakpoints-list" }, - (breakpoints.size === 0 ? - dom.div({ className: "pane-info" }, L10N.getStr("breakpoints.none")) : - breakpoints.valueSeq().map(bp => { - return this.renderBreakpoint(bp); - })) - ); - } -}); - -function _getBreakpoints(state) { - return getBreakpoints(state).map(bp => { - const source = getSource(state, bp.location.sourceId); - const isCurrentlyPaused = isCurrentlyPausedAtBreakpoint(state, bp); - const locationId = makeLocationId(bp.location); - - bp = Object.assign({}, bp); - bp.location.source = source; - bp.locationId = locationId; - bp.isCurrentlyPaused = isCurrentlyPaused; - return bp; - }) - .filter(bp => bp.location.source); -} - -module.exports = connect( - (state, props) => ({ - breakpoints: _getBreakpoints(state) - }), - dispatch => bindActionCreators(actions, dispatch) -)(Breakpoints); diff --git a/src/components/CloseButton.css b/src/components/CloseButton.css deleted file mode 100644 index a5ccc5ace2..0000000000 --- a/src/components/CloseButton.css +++ /dev/null @@ -1,62 +0,0 @@ -.close-btn path { - fill: var(--theme-body-color); -} - -.close-btn .close { - cursor: pointer; - width: 12px; - height: 12px; - padding: 2px; - text-align: center; - margin-top: 2px; - line-height: 5px; - transition: all 0.25s easeinout; -} - -.close-btn .close svg { - width: 6px; -} - -.close-btn .close:hover { - background: var(--theme-selection-background); - border-radius: 2px; -} - -.close-btn .close:hover path { - fill: white; -} - -.close-btn-big { - padding: 13px; - width: 40px; - height: 40px; -} - -.close-btn-big path { - fill: var(--theme-body-color); -} - -.close-btn-big .close { - cursor: pointer; - display: inline-block; - padding: 2px; - text-align: center; - transition: all 0.25s easeinout; - line-height: 100%; - width: 16px; - height: 16px; -} - -.close-btn-big .close svg { - width: 9px; - height: 9px; -} - -.close-btn-big .close:hover { - background: var(--theme-selection-background); - border-radius: 2px; -} - -.close-btn-big .close:hover path { - fill: white; -} diff --git a/src/components/CloseButton.js b/src/components/CloseButton.js deleted file mode 100644 index 57777dcc53..0000000000 --- a/src/components/CloseButton.js +++ /dev/null @@ -1,19 +0,0 @@ -const React = require("react"); -const { DOM: dom, PropTypes } = React; -const Svg = require("./utils/Svg"); - -require("./CloseButton.css"); - -function CloseButton({ handleClick, buttonClass }) { - return dom.div({ - className: buttonClass ? `close-btn-${buttonClass}` : "close-btn", - onClick: handleClick - }, - Svg("close")); -} - -CloseButton.propTypes = { - handleClick: PropTypes.func.isRequired -}; - -module.exports = CloseButton; diff --git a/src/components/CommandBar.css b/src/components/CommandBar.css deleted file mode 100644 index 132a822d7d..0000000000 --- a/src/components/CommandBar.css +++ /dev/null @@ -1,69 +0,0 @@ -.right-sidebar .command-bar { - border-bottom: 1px solid var(--theme-splitter-color); -} - -.command-bar { - height: 30px; -} - -html:not([dir="rtl"]) .command-bar { - padding: 8px 5px 10px 1px; -} - -html[dir="rtl"] .command-bar { - padding: 8px 1px 10px 5px; -} - -.command-bar > span { - cursor: pointer; - width: 16px; - height: 17px; - display: inline-block; - text-align: center; - transition: all 0.25s ease; -} - -:root.theme-dark .command-bar > span { - fill: var(--theme-body-color); -} - -:root.theme-dark .command-bar > span:hover { - fill: var(--theme-selection-color); -} - -html:not([dir="rtl"]) .command-bar > span { - margin-right: 0.7em; -} - -html[dir="rtl"] .command-bar > span { - margin-left: 0.7em; -} - -.command-bar > span.disabled { - opacity: 0.3; - cursor: default; -} - -html:not([dir="rtl"]) .command-bar .stepOut { - margin-right: 2em; -} - -html[dir="rtl"] .command-bar .stepOut { - margin-left: 2em; -} - -.command-bar .subSettings { - float: right; -} - -.command-bar .toggleBreakpoints.breakpoints-disabled path { - stroke: var(--theme-highlight-blue); -} - -.command-bar span.pause-exceptions.uncaught { - stroke: var(--theme-highlight-purple); -} - -.command-bar span.pause-exceptions.all { - stroke: var(--theme-highlight-blue); -} diff --git a/src/components/CommandBar.js b/src/components/CommandBar.js deleted file mode 100644 index 22d4663f30..0000000000 --- a/src/components/CommandBar.js +++ /dev/null @@ -1,185 +0,0 @@ -const React = require("react"); -const { DOM: dom, PropTypes } = React; -const { connect } = require("react-redux"); -const { bindActionCreators } = require("redux"); -const { getPause, getIsWaitingOnBreak, getBreakpointsDisabled, - getShouldPauseOnExceptions, getShouldIgnoreCaughtExceptions, - getBreakpoints, getBreakpointsLoading - } = require("../selectors"); -const Svg = require("./utils/Svg"); -const ImPropTypes = require("react-immutable-proptypes"); - -const { Services: { appinfo }} = require("devtools-modules"); - -const shiftKey = appinfo.OS === "Darwin" ? "\u21E7" : "Shift+"; -const ctrlKey = appinfo.OS === "Linux" ? "Ctrl+" : ""; - -const actions = require("../actions"); -require("./CommandBar.css"); - -function debugBtn(onClick, type, className, tooltip) { - className = `${type} ${className}`; - return dom.span( - { onClick, className, key: type }, - Svg(type, { title: tooltip }) - ); -} - -const CommandBar = React.createClass({ - propTypes: { - sources: PropTypes.object, - selectedSource: PropTypes.object, - resume: PropTypes.func, - stepIn: PropTypes.func, - stepOut: PropTypes.func, - stepOver: PropTypes.func, - toggleAllBreakpoints: PropTypes.func, - breakOnNext: PropTypes.func, - pause: ImPropTypes.map, - pauseOnExceptions: PropTypes.func, - shouldPauseOnExceptions: PropTypes.bool, - shouldIgnoreCaughtExceptions: PropTypes.bool, - breakpoints: ImPropTypes.map, - isWaitingOnBreak: PropTypes.bool, - breakpointsDisabled: PropTypes.bool, - breakpointsLoading: PropTypes.bool, - }, - - contextTypes: { - shortcuts: PropTypes.object - }, - - displayName: "CommandBar", - - componentWillUnmount() { - const shortcuts = this.context.shortcuts; - shortcuts.off("F8", this.props.resume); - shortcuts.off("F10", this.props.stepOver); - shortcuts.off(`${ctrlKey}F11`, this.props.stepIn); - shortcuts.off(`${ctrlKey}Shift+F11`, this.props.stepOut); - }, - - componentDidMount() { - const shortcuts = this.context.shortcuts; - shortcuts.on("F8", this.props.resume); - shortcuts.on("F10", this.props.stepOver); - shortcuts.on(`${ctrlKey}F11`, this.props.stepIn); - shortcuts.on(`${ctrlKey}Shift+F11`, this.props.stepOut); - }, - - renderStepButtons() { - const className = this.props.pause ? "active" : "disabled"; - return [ - debugBtn(this.props.stepOver, "stepOver", className, - L10N.getStr("stepOverTooltip") - ), - debugBtn(this.props.stepIn, "stepIn", className, - L10N.getFormatStr("stepInTooltip", ctrlKey) - ), - debugBtn(this.props.stepOut, "stepOut", className, - L10N.getFormatStr("stepOutTooltip", ctrlKey + shiftKey) - ) - ]; - }, - - renderPauseButton() { - const { pause, breakOnNext, isWaitingOnBreak } = this.props; - - if (pause) { - return debugBtn(this.props.resume, "resume", "active", - L10N.getStr("resumeButtonTooltip") - ); - } - - if (isWaitingOnBreak) { - return debugBtn(null, "pause", "disabled", - L10N.getStr("pausePendingButtonTooltip") - ); - } - - return debugBtn(breakOnNext, "pause", "active", - L10N.getStr("pauseButtonTooltip") - ); - }, - - /* - * The pause on exception button has three states in this order: - * 1. don't pause on exceptions [false, false] - * 2. pause on uncaught exceptions [true, true] - * 3. pause on all exceptions [true, false] - */ - renderPauseOnExceptions() { - const { shouldPauseOnExceptions, shouldIgnoreCaughtExceptions, - pauseOnExceptions } = this.props; - - if (!shouldPauseOnExceptions && !shouldIgnoreCaughtExceptions) { - return debugBtn( - () => pauseOnExceptions(true, true), - "pause-exceptions", - "enabled", - L10N.getStr("ignoreExceptions") - ); - } - - if (shouldPauseOnExceptions && shouldIgnoreCaughtExceptions) { - return debugBtn( - () => pauseOnExceptions(true, false), - "pause-exceptions", - "uncaught enabled", - L10N.getStr("pauseOnUncaughtExceptions") - ); - } - - return debugBtn( - () => pauseOnExceptions(false, false), - "pause-exceptions", - "all enabled", - L10N.getStr("pauseOnExceptions") - ); - }, - - renderDisableBreakpoints() { - const { toggleAllBreakpoints, breakpoints, - breakpointsDisabled, breakpointsLoading } = this.props; - - if (breakpoints.size == 0 || breakpointsLoading) { - return debugBtn( - null, "toggleBreakpoints", "disabled", "Disable Breakpoints" - ); - } - - return debugBtn( - () => toggleAllBreakpoints(!breakpointsDisabled), - "toggleBreakpoints", - breakpointsDisabled ? "breakpoints-disabled" : "", - "Disable Breakpoints" - ); - }, - - render() { - return ( - dom.div( - { className: "command-bar" }, - this.renderPauseButton(), - this.renderStepButtons(), - this.renderDisableBreakpoints(), - this.renderPauseOnExceptions() - ) - ); - } -}); - -module.exports = connect( - state => { - return { - pause: getPause(state), - isWaitingOnBreak: getIsWaitingOnBreak(state), - shouldPauseOnExceptions: getShouldPauseOnExceptions(state), - shouldIgnoreCaughtExceptions: getShouldIgnoreCaughtExceptions(state), - breakpointsDisabled: getBreakpointsDisabled(state), - breakpoints: getBreakpoints(state), - breakpointsLoading: getBreakpointsLoading(state), - }; - }, - dispatch => bindActionCreators(actions, dispatch) -)(CommandBar); diff --git a/src/components/Dropdown.css b/src/components/Dropdown.css deleted file mode 100644 index 18a978571b..0000000000 --- a/src/components/Dropdown.css +++ /dev/null @@ -1,53 +0,0 @@ -.dropdown { - background: var(--theme-body-background); - border: 1px solid var(--theme-splitter-color); - box-shadow: 0 4px 4px 0 var(--theme-search-overlays-semitransparent); - max-height: 300px; - position: absolute; - right: 8px; - top: 35px; - width: 150px; - z-index: 1000; -} - -.dropdown-button { - position: absolute; - right: 12px; - top: 5px; - font-size: 16px; - color: var(--theme-body-color); - cursor: pointer; - background: none; - border: none; -} - -.dropdown li { - transition: all 0.25s ease; - padding: 2px 10px 10px 5px; - overflow: hidden; - height: 30px; - text-overflow: ellipsis; -} - -.dropdown li:hover { - background-color: var(--theme-search-overlays-semitransparent); - cursor: pointer; -} - -.dropdown ul { - list-style: none; - line-height: 2em; - font-size: 1em; - margin: 0; - padding: 0; -} - -.dropdown-mask { - position: fixed; - width: 100%; - height: 100%; - background: transparent; - z-index: 999; - left: 0; - top: 0; -} diff --git a/src/components/Dropdown.js b/src/components/Dropdown.js deleted file mode 100644 index ebba9ac2b6..0000000000 --- a/src/components/Dropdown.js +++ /dev/null @@ -1,62 +0,0 @@ -const React = require("react"); -const { DOM: dom, PropTypes } = React; - -const Dropdown = React.createClass({ - propTypes: { - panel: PropTypes.object - }, - - displayName: "Dropdown", - - getInitialState() { - return { - dropdownShown: false - }; - }, - - toggleDropdown(e) { - this.setState({ - dropdownShown: !this.state.dropdownShown, - }); - }, - - renderPanel() { - return dom.div( - { - className: "dropdown", - onClick: this.toggleDropdown, - style: { display: (this.state.dropdownShown ? "block" : "none") } - }, - this.props.panel - ); - }, - - renderButton() { - return dom.button( - { - className: "dropdown-button", - onClick: this.toggleDropdown - }, - "»" - ); - }, - - renderMask() { - return dom.div({ - className: "dropdown-mask", - onClick: this.toggleDropdown, - style: { display: (this.state.dropdownShown ? "block" : "none") } - }); - }, - - render() { - return dom.div({}, - this.renderPanel(), - this.renderButton(), - this.renderMask() - ); - } - -}); - -module.exports = Dropdown; diff --git a/src/components/Editor.css b/src/components/Editor.css deleted file mode 100644 index 99f270a7da..0000000000 --- a/src/components/Editor.css +++ /dev/null @@ -1,140 +0,0 @@ -/* vim:set ts=2 sw=2 sts=2 et: */ - -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/** - * There's a known codemirror flex issue with chrome that this addresses. - * BUG https://github.com/devtools-html/debugger.html/issues/63 - */ -.editor-wrapper { - position: absolute; - height: calc(100% - 31px); - width: 100%; - top: 30px; - left: 0px; -} - -html[dir="rtl"] .editor-mount { - direction: ltr; -} - -.editor-wrapper .breakpoints { - position: absolute; - top: 0; - left: 0; -} - -.editor.new-breakpoint svg { - fill: var(--theme-selection-background); - width: 60px; - height: 14px; - position: absolute; - top: 0px; - right: -4px; -} - -.new-breakpoint.has-condition svg { - fill: var(--theme-graphs-yellow); -} - -.editor.new-breakpoint.breakpoint-disabled svg { - opacity: 0.3; -} - -.CodeMirror { - width: 100%; - height: 100%; -} - -.editor-wrapper .editor-mount { - width: 100%; - height: calc(100% - 32px); - background-color: var(--theme-body-background); -} - -.search-bar ~ .editor-mount { - height: calc(100% - 72px); -} - -.CodeMirror-linenumber { - font-size: 11px; - line-height: 14px; -} - -/* set the linenumber white when there is a breakpoint */ -.new-breakpoint .CodeMirror-gutter-wrapper .CodeMirror-linenumber { - color: white; -} - -/* move the breakpoint below the linenumber */ -.new-breakpoint .CodeMirror-gutter-elt:last-child { - z-index: 0; -} - -.editor-wrapper .CodeMirror-line { - font-size: 11px; - line-height: 14px; -} - -.debug-line .CodeMirror-line { - background-color: var(--breakpoint-active-color) !important; -} - -/* Don't display the highlight color since the debug line - is already highlighted */ -.debug-line .CodeMirror-activeline-background { - display: none; -} - -.highlight-line .CodeMirror-line { - animation: fade-highlight-out 1.5s normal forwards; -} - -@keyframes fade-highlight-out { - 0% { background-color: var(--theme-highlight-gray); } - 100% { background-color: transparent; } -} - -.welcomebox { - width: calc(100% - 1px); - - /* Offsetting it by 30px for the sources-header area */ - height: calc(100% - 30px); - position: absolute; - top: 30px; - left: 0; - padding: 50px 0; - text-align: center; - font-size: 1.25em; - color: var(--theme-comment-alt); - background-color: var(--theme-tab-toolbar-background); - font-weight: lighter; - z-index: 100; - -moz-user-select: none; - user-select: none; -} - -.conditional-breakpoint-panel { - cursor: initial; - margin: 1em 0; - position: relative; - background: var(--theme-toolbar-background); - border-top: 1px solid var(--theme-splitter-color); - border-bottom: 1px solid var(--theme-splitter-color); -} - -.conditional-breakpoint-panel input { - margin: 5px 10px; - width: calc(100% - 2em); - border: none; - background: var(--theme-toolbar-background); - font-size: 14px; - color: var(--theme-comment); - line-height: 30px; -} - -.conditional-breakpoint-panel input:focus { - outline-width: 0; -} diff --git a/src/components/Editor.js b/src/components/Editor.js deleted file mode 100644 index b24d9dd770..0000000000 --- a/src/components/Editor.js +++ /dev/null @@ -1,526 +0,0 @@ -const React = require("react"); -const { DOM: dom, PropTypes, createFactory } = React; - -const ReactDOM = require("react-dom"); -const ImPropTypes = require("react-immutable-proptypes"); -const { bindActionCreators } = require("redux"); -const { connect } = require("react-redux"); -const SourceEditor = require("../utils/source-editor"); -const SourceFooter = createFactory(require("./SourceFooter")); -const EditorSearchBar = createFactory(require("./EditorSearchBar")); -const { renderConditionalPanel } = require("./EditorConditionalPanel"); -const { debugGlobal } = require("devtools-local-toolbox"); -const { - getSourceText, getBreakpointsForSource, - getSelectedLocation, getSelectedFrame, - getSelectedSource -} = require("../selectors"); -const { makeLocationId } = require("../reducers/breakpoints"); -const actions = require("../actions"); -const Breakpoint = React.createFactory(require("./EditorBreakpoint")); - -const { getDocument, setDocument } = require("../utils/source-documents"); -const { shouldShowFooter } = require("../utils/editor"); -const { isFirefox } = require("devtools-config"); -const { showMenu } = require("../utils/menu"); -const { isEnabled } = require("devtools-config"); - -require("./Editor.css"); - -function isTextForSource(sourceText) { - return !sourceText.get("loading") && !sourceText.get("error"); -} - -function breakpointAtLine(breakpoints, line) { - return breakpoints.find(b => { - return b.location.line === line + 1; - }); -} - -function getTextForLine(codeMirror, line) { - return codeMirror.getLine(line - 1).trim(); -} - -function getCursorLine(codeMirror) { - return codeMirror.getCursor().line; -} -/** - * Forces the breakpoint gutter to be the same size as the line - * numbers gutter. Editor CSS will absolutely position the gutter - * beneath the line numbers. This makes it easy to be flexible with - * how we overlay breakpoints. - */ -function resizeBreakpointGutter(editor) { - const gutters = editor.display.gutters; - const lineNumbers = gutters.querySelector(".CodeMirror-linenumbers"); - const breakpoints = gutters.querySelector(".breakpoints"); - breakpoints.style.width = `${lineNumbers.clientWidth}px`; -} - -const Editor = React.createClass({ - propTypes: { - breakpoints: ImPropTypes.map.isRequired, - selectedLocation: PropTypes.object, - selectedSource: ImPropTypes.map, - sourceText: PropTypes.object, - addBreakpoint: PropTypes.func, - disableBreakpoint: PropTypes.func, - enableBreakpoint: PropTypes.func, - removeBreakpoint: PropTypes.func, - setBreakpointCondition: PropTypes.func, - selectedFrame: PropTypes.object - }, - - displayName: "Editor", - - contextTypes: { - shortcuts: PropTypes.object - }, - - onGutterClick(cm, line, gutter, ev) { - // ignore right clicks in the gutter - if (ev.which === 3) { - return; - } - - if (this.isCbPanelOpen()) { - return this.closeConditionalPanel(line); - } - - this.toggleBreakpoint(line); - }, - - onGutterContextMenu(event) { - event.preventDefault(); - const line = this.editor.codeMirror.lineAtHeight(event.clientY); - const bp = breakpointAtLine(this.props.breakpoints, line); - this.showGutterMenu(event, line, bp); - }, - - showConditionalPanel(line) { - if (this.isCbPanelOpen()) { - return; - } - - const { selectedLocation: { sourceId }, - setBreakpointCondition, breakpoints } = this.props; - - const bp = breakpointAtLine(breakpoints, line); - const location = { sourceId, line: line + 1 }; - const condition = bp ? bp.condition : ""; - - const setBreakpoint = value => { - setBreakpointCondition(location, { - condition: value, - getTextForLine: l => getTextForLine(this.editor.codeMirror, l) - }); - }; - - const panel = renderConditionalPanel({ - condition, - setBreakpoint, - closePanel: this.closeConditionalPanel - }); - - this.cbPanel = this.editor.codeMirror.addLineWidget(line, panel); - this.cbPanel.node.querySelector("input").focus(); - }, - - closeConditionalPanel() { - this.cbPanel.clear(); - this.cbPanel = null; - }, - - isCbPanelOpen() { - return !!this.cbPanel; - }, - - toggleBreakpoint(line) { - const bp = breakpointAtLine(this.props.breakpoints, line); - - if (bp && bp.loading) { - return; - } - - if (bp) { - this.props.removeBreakpoint({ - sourceId: this.props.selectedLocation.sourceId, - line: line + 1 - }); - } else { - this.props.addBreakpoint( - { sourceId: this.props.selectedLocation.sourceId, - line: line + 1 }, - // Pass in a function to get line text because the breakpoint - // may slide and it needs to compute the value at the new - // line. - { getTextForLine: l => getTextForLine(this.editor.codeMirror, l) } - ); - } - }, - - toggleBreakpointDisabledStatus(line) { - const bp = breakpointAtLine(this.props.breakpoints, line); - - if (bp && bp.loading) { - return; - } - - if (!bp) { - throw new Error("attempt to disable breakpoint that does not exist"); - } - - if (!bp.disabled) { - this.props.disableBreakpoint({ - sourceId: this.props.selectedLocation.sourceId, - line: line + 1 - }); - } else { - this.props.enableBreakpoint({ - sourceId: this.props.selectedLocation.sourceId, - line: line + 1 - }); - } - }, - - clearDebugLine(selectedFrame) { - if (selectedFrame) { - const line = selectedFrame.location.line; - this.editor.codeMirror.removeLineClass(line - 1, "line", "debug-line"); - } - }, - - setDebugLine(selectedFrame, selectedLocation) { - if (selectedFrame && selectedLocation && - selectedFrame.location.sourceId === selectedLocation.sourceId) { - const line = selectedFrame.location.line; - this.editor.codeMirror.addLineClass(line - 1, "line", "debug-line"); - } - }, - - highlightLine() { - if (!this.pendingJumpLine) { - return; - } - - // If the location has changed and a specific line is requested, - // move to that line and flash it. - const codeMirror = this.editor.codeMirror; - - // Make sure to clean up after ourselves. Not only does this - // cancel any existing animation, but it avoids it from - // happening ever again (in case CodeMirror re-applies the - // class, etc). - if (this.lastJumpLine) { - codeMirror.removeLineClass( - this.lastJumpLine - 1, "line", "highlight-line" - ); - } - - const line = this.pendingJumpLine; - this.editor.alignLine(line); - - // We only want to do the flashing animation if it's not a debug - // line, which has it's own styling. - if (!this.props.selectedFrame || - this.props.selectedFrame.location.line !== line) { - this.editor.codeMirror.addLineClass(line - 1, "line", "highlight-line"); - } - - this.lastJumpLine = line; - this.pendingJumpLine = null; - }, - - setText(text) { - if (!text || !this.editor) { - return; - } - - this.editor.setText(text); - }, - - setMode(sourceText) { - const contentType = sourceText.get("contentType"); - - if (contentType.includes("javascript")) { - this.editor.setMode({ name: "javascript" }); - } else if (contentType === "text/wasm") { - this.editor.setMode({ name: "text" }); - } else if (sourceText.get("text").match(/^\s* { - this.toggleBreakpoint(line); - if (this.isCbPanelOpen()) { - this.closeConditionalPanel(); - } - } - }, breakpoint); - - const conditionalBreakpoint = Object.assign({ - accesskey: "C", - disabled: false, - click: () => this.showConditionalPanel(line) - }, conditional); - - let items = [ - toggleBreakpoint, - conditionalBreakpoint - ]; - - if (bp) { - const disableBreakpoint = Object.assign({ - accesskey: "D", - disabled: false, - click: () => this.toggleBreakpointDisabledStatus(line) - }, disabled); - items.push(disableBreakpoint); - } - - showMenu(e, items); - }, - - componentDidMount() { - this.cbPanel = null; - - this.editor = new SourceEditor({ - mode: "javascript", - readOnly: true, - lineNumbers: true, - theme: "mozilla", - lineWrapping: false, - matchBrackets: true, - showAnnotationRuler: true, - enableCodeFolding: false, - gutters: ["breakpoints"], - value: " ", - extraKeys: {} - }); - - // disables the default search shortcuts - if (isEnabled("editorSearch")) { - this.editor._initShortcuts = () => {}; - } - - this.editor.appendToLocalElement( - ReactDOM.findDOMNode(this).querySelector(".editor-mount") - ); - - this.editor.codeMirror.on("gutterClick", this.onGutterClick); - - if (!isFirefox()) { - this.editor.codeMirror.on( - "gutterContextMenu", - (cm, line, eventName, event) => this.onGutterContextMenu(event) - ); - } else { - this.editor.codeMirror.getWrapperElement().addEventListener( - "contextmenu", - event => this.onGutterContextMenu(event), - false - ); - } - const shortcuts = this.context.shortcuts; - shortcuts.on("CmdOrCtrl+B", () => this.toggleBreakpoint( - getCursorLine(this.editor.codeMirror) - )); - shortcuts.on("CmdOrCtrl+Shift+B", () => this.showConditionalPanel( - getCursorLine(this.editor.codeMirror) - )); - - resizeBreakpointGutter(this.editor.codeMirror); - debugGlobal("cm", this.editor.codeMirror); - - if (this.props.sourceText) { - this.setText(this.props.sourceText.get("text")); - } - }, - - componentWillUnmount() { - this.editor.destroy(); - this.editor = null; - - const shortcuts = this.context.shortcuts; - shortcuts.off("CmdOrCtrl+B"); - shortcuts.off("CmdOrCtrl+Shift+B"); - }, - - componentWillReceiveProps(nextProps) { - // This lifecycle method is responsible for updating the editor - // text. - const { sourceText, selectedLocation } = nextProps; - this.clearDebugLine(this.props.selectedFrame); - - if (!sourceText) { - this.showMessage(""); - } else if (!isTextForSource(sourceText)) { - this.showMessage(sourceText.get("error") || - L10N.getStr("loadingText")); - } else if (this.props.sourceText !== sourceText) { - this.showSourceText(sourceText, selectedLocation); - } - - this.setDebugLine(nextProps.selectedFrame, selectedLocation); - resizeBreakpointGutter(this.editor.codeMirror); - }, - - showMessage(msg) { - this.editor.replaceDocument(this.editor.createDocument()); - this.setText(msg); - this.editor.setMode({ name: "text" }); - }, - - /** - * Handle getting the source document or creating a new - * document with the correct mode and text. - * - */ - showSourceText(sourceText, selectedLocation) { - let doc = getDocument(selectedLocation.sourceId); - if (doc) { - this.editor.replaceDocument(doc); - return doc; - } - - doc = this.editor.createDocument(); - setDocument(selectedLocation.sourceId, doc); - this.editor.replaceDocument(doc); - - this.setText(sourceText.get("text")); - this.setMode(sourceText); - }, - - componentDidUpdate(prevProps) { - // This is in `componentDidUpdate` so helper functions can expect - // `this.props` to be the current props. This lifecycle method is - // responsible for updating the editor annotations. - const { selectedLocation } = this.props; - - // If the location is different and a new line is requested, - // update the pending jump line. Note that if jumping to a line in - // a source where the text hasn't been loaded yet, we will set the - // line here but not jump until rendering the actual source. - if (prevProps.selectedLocation !== selectedLocation) { - if (selectedLocation && - selectedLocation.line != undefined) { - this.pendingJumpLine = selectedLocation.line; - } else { - this.pendingJumpLine = null; - } - } - - // Only update and jump around in real source texts. This will - // keep the jump state around until the real source text is - // loaded. - if (this.props.sourceText && isTextForSource(this.props.sourceText)) { - this.highlightLine(); - } - }, - - renderBreakpoints() { - const { breakpoints, sourceText } = this.props; - const isLoading = sourceText && sourceText.get("loading"); - - if (isLoading) { - return; - } - - return breakpoints.valueSeq().map(bp => { - return Breakpoint({ - key: makeLocationId(bp.location), - breakpoint: bp, - editor: this.editor && this.editor.codeMirror - }); - }); - }, - - editorHeight() { - const { selectedSource } = this.props; - - if (!selectedSource || !shouldShowFooter(selectedSource.toJS())) { - return "100%"; - } - - return ""; - }, - - render() { - const { sourceText, selectedSource } = this.props; - - return ( - dom.div( - { className: "editor-wrapper devtools-monospace" }, - EditorSearchBar({ - editor: this.editor, - selectedSource, - sourceText - }), - dom.div({ - className: "editor-mount", - style: { height: this.editorHeight() } - }), - this.renderBreakpoints(), - SourceFooter({ editor: this.editor }) - ) - ); - } -}); - -module.exports = connect( - state => { - const selectedLocation = getSelectedLocation(state); - const sourceId = selectedLocation && selectedLocation.sourceId; - const selectedSource = getSelectedSource(state); - - return { - selectedLocation, - selectedSource, - sourceText: getSourceText(state, sourceId), - breakpoints: getBreakpointsForSource(state, sourceId), - selectedFrame: getSelectedFrame(state) - }; - }, - dispatch => bindActionCreators(actions, dispatch) -)(Editor); diff --git a/src/components/EditorBreakpoint.js b/src/components/EditorBreakpoint.js deleted file mode 100644 index 1e2a35af61..0000000000 --- a/src/components/EditorBreakpoint.js +++ /dev/null @@ -1,80 +0,0 @@ -const React = require("react"); -const ReactDOM = require("react-dom"); - -const { PropTypes } = React; -const classnames = require("classnames"); -const Svg = require("./utils/Svg"); - -let breakpointSvg = document.createElement("div"); -ReactDOM.render(Svg("breakpoint"), breakpointSvg); - -function makeMarker(isDisabled) { - let bp = breakpointSvg.cloneNode(true); - bp.className = classnames( - "editor new-breakpoint", - { "breakpoint-disabled": isDisabled } - ); - - return bp; -} - -const Breakpoint = React.createClass({ - propTypes: { - breakpoint: PropTypes.object, - editor: PropTypes.object - }, - - displayName: "Breakpoint", - - addBreakpoint() { - const bp = this.props.breakpoint; - const line = bp.location.line - 1; - - this.props.editor.setGutterMarker( - line, - "breakpoints", - makeMarker(bp.disabled) - ); - this.props.editor.addLineClass(line, "line", "new-breakpoint"); - if (bp.condition) { - this.props.editor.addLineClass(line, "line", "has-condition"); - } - }, - - shouldComponentUpdate(nextProps) { - return this.props.editor !== nextProps.editor || - this.props.breakpoint.disabled !== nextProps.breakpoint.disabled || - this.props.breakpoint.condition !== nextProps.breakpoint.condition; - }, - - componentDidMount() { - if (!this.props.editor) { - return; - } - - this.addBreakpoint(); - }, - - componentDidUpdate() { - this.addBreakpoint(); - }, - - componentWillUnmount() { - if (!this.props.editor) { - return; - } - - const bp = this.props.breakpoint; - const line = bp.location.line - 1; - - this.props.editor.setGutterMarker(line, "breakpoints", null); - this.props.editor.removeLineClass(line, "line", "new-breakpoint"); - this.props.editor.removeLineClass(line, "line", "has-condition"); - }, - - render() { - return null; - } -}); - -module.exports = Breakpoint; diff --git a/src/components/EditorConditionalPanel.js b/src/components/EditorConditionalPanel.js deleted file mode 100644 index b61bb76082..0000000000 --- a/src/components/EditorConditionalPanel.js +++ /dev/null @@ -1,35 +0,0 @@ -const React = require("react"); -const { DOM: dom } = React; - -const ReactDOM = require("react-dom"); - -function renderConditionalPanel({ condition, closePanel, setBreakpoint }) { - let panel = document.createElement("div"); - - function onKey(e) { - if (e.key != "Enter") { - return; - } - - setBreakpoint(e.target.value); - closePanel(); - } - - ReactDOM.render( - dom.div( - { className: "conditional-breakpoint-panel" }, - dom.input({ - defaultValue: condition, - placeholder: L10N.getStr("editor.conditionalPanel.placeholder"), - onKeyPress: onKey - }) - ), - panel - ); - - return panel; -} - -module.exports = { - renderConditionalPanel -}; diff --git a/src/components/EditorSearchBar.css b/src/components/EditorSearchBar.css deleted file mode 100644 index ec1e8ce000..0000000000 --- a/src/components/EditorSearchBar.css +++ /dev/null @@ -1,55 +0,0 @@ -.search-bar { - width: calc(100% - 1px); - height: 40px; - background-color: var(--theme-body-background); - border-bottom: 1px solid var(--theme-splitter-color); - display: flex; -} - -.search-bar i { - display: block; - padding: 13px 0 0 13px; - width: 40px; -} - -.search-bar i svg { - width: 16px; -} - -.search-bar input { - border: none; - line-height: 30px; - font-size: 14px; - background-color: var(--theme-body-background); - color: var(--theme-comment); - width: calc(100% - 38px); - flex: 1; -} - -.search-bar .magnifying-glass { - background-color: var(--theme-body-background); - width: 40px; -} - -.search-bar .magnifying-glass path, -.search-bar .magnifying-glass ellipse { - stroke: var(--theme-splitter-color); -} - -.search-bar input::placeholder { - color: var(--theme-body-color-inactive); -} - -.search-bar input:focus { - outline-width: 0; -} - -.search-bar input.empty { - color: var(--theme-highlight-orange); -} - -.search-bar .summary { - line-height: 40px; - padding-right: 10px; - color: var(--theme-body-color-inactive); -} diff --git a/src/components/EditorSearchBar.js b/src/components/EditorSearchBar.js deleted file mode 100644 index cc92cedb20..0000000000 --- a/src/components/EditorSearchBar.js +++ /dev/null @@ -1,249 +0,0 @@ -const React = require("react"); -const { DOM: dom, PropTypes } = React; -const { findDOMNode } = require("react-dom"); -const Svg = require("./utils/Svg"); -const { find, findNext, findPrev, removeOverlay } = require("../utils/source-search"); -const classnames = require("classnames"); -const { debounce, escapeRegExp } = require("lodash"); -const CloseButton = require("./CloseButton"); -const { isEnabled } = require("devtools-config"); -const ImPropTypes = require("react-immutable-proptypes"); - -require("./EditorSearchBar.css"); - -function countMatches(query, text) { - const re = new RegExp(escapeRegExp(query), "g"); - const match = text.match(re); - return match ? match.length : 0; -} - -const EditorSearchBar = React.createClass({ - - propTypes: { - editor: PropTypes.object, - sourceText: PropTypes.object, - selectedSource: ImPropTypes.map - }, - - displayName: "EditorSearchBar", - - getInitialState() { - return { - enabled: false, - query: "", - count: 0, - index: 0 - }; - }, - - contextTypes: { - shortcuts: PropTypes.object - }, - - componentWillUnmount() { - const shortcuts = this.context.shortcuts; - if (isEnabled("editorSearch")) { - shortcuts.off("CmdOrCtrl+F"); - shortcuts.off("Escape"); - shortcuts.off("CmdOrCtrl+Shift+G"); - shortcuts.off("CmdOrCtrl+G"); - } - }, - - componentDidMount() { - const shortcuts = this.context.shortcuts; - if (isEnabled("editorSearch")) { - shortcuts.on("CmdOrCtrl+F", (_, e) => this.toggleSearch(e)); - shortcuts.on("Escape", (_, e) => this.onEscape(e)); - shortcuts.on("CmdOrCtrl+Shift+G", (_, e) => this.traverseResultsPrev(e)); - shortcuts.on("CmdOrCtrl+G", (_, e) => this.traverseResultsNext(e)); - } - }, - - componentDidUpdate(prevProps) { - const { sourceText, selectedSource } = this.props; - - if (this.searchInput()) { - this.searchInput().focus(); - } - - if (sourceText && sourceText.get("text") && - selectedSource != prevProps.selectedSource) { - const query = this.state.query; - const count = countMatches(query, sourceText.get("text")); - this.setState({ count: count, index: 0 }); - this.search(query); - } - }, - - onEscape(e) { - this.closeSearch(e); - }, - - closeSearch(e) { - if (this.state.enabled) { - this.setState({ enabled: false }); - const ed = this.props.editor; - const ctx = { ed, cm: ed.codeMirror }; - removeOverlay(ctx); - e.stopPropagation(); - e.preventDefault(); - } - }, - - toggleSearch(e) { - e.stopPropagation(); - e.preventDefault(); - - this.setState({ enabled: !this.state.enabled }); - - if (this.state.enabled) { - const selection = this.props.editor.codeMirror.getSelection(); - this.setSearchValue(selection); - this.selectSearchInput(); - } - }, - - setSearchValue(value: string) { - if (value == "") { - return; - } - - this.searchInput().value = value; - }, - - selectSearchInput() { - const node = this.searchInput(); - if (node) { - node.setSelectionRange(0, node.value.length); - } - }, - - searchInput() { - return findDOMNode(this).querySelector("input"); - }, - - onChange(e) { - this.search(e.target.value); - }, - - traverseResultsPrev(e) { - e.stopPropagation(); - e.preventDefault(); - - const ed = this.props.editor; - const ctx = { ed, cm: ed.codeMirror }; - const { query, index, count } = this.state; - - if (query == "") { - this.setState({ enabled: true }); - } - - findPrev(ctx, query); - const nextIndex = index == 0 ? count - 1 : index - 1; - this.setState({ index: nextIndex }); - }, - - traverseResultsNext(e) { - e.stopPropagation(); - e.preventDefault(); - - const ed = this.props.editor; - const ctx = { ed, cm: ed.codeMirror }; - const { query, index, count } = this.state; - - if (query == "") { - this.setState({ enabled: true }); - } - - findNext(ctx, query); - const nextIndex = index == count - 1 ? 0 : index + 1; - this.setState({ index: nextIndex }); - }, - - onKeyUp(e) { - if (e.key != "Enter") { - return; - } - - if (e.shiftKey) { - this.traverseResultsPrev(e); - } else { - this.traverseResultsNext(e); - } - }, - - search: debounce(function(query) { - const sourceText = this.props.sourceText; - - if (!sourceText.get("text")) { - return; - } - - const count = countMatches(query, sourceText.get("text")); - this.setState({ query, count, index: 0 }); - - const ed = this.props.editor; - const ctx = { ed, cm: ed.codeMirror }; - - find(ctx, query); - }, 100), - - renderSummary() { - const { count, index, query } = this.state; - - if (query.trim() == "") { - return dom.div({}); - } else if (count == 0) { - return dom.div( - { className: "summary" }, - L10N.getStr("editor.noResults") - ); - } - - return dom.div( - { className: "summary" }, - L10N.getFormatStr("editor.searchResults", index + 1, count) - ); - }, - - renderSvg() { - const { count, query } = this.state; - - if (count == 0 && query.trim() != "") { - return Svg("sad-face"); - } - - return Svg("magnifying-glass"); - }, - - render() { - if (!this.state.enabled) { - return dom.div(); - } - - const { count, query } = this.state; - - return dom.div( - { className: "search-bar" }, - this.renderSvg(), - dom.input({ - className: classnames({ - empty: count == 0 && query.trim() != "" - }), - onChange: this.onChange, - onKeyUp: this.onKeyUp, - placeholder: "Search in file...", - value: this.state.query, - spellCheck: false - }), - this.renderSummary(), - CloseButton({ - handleClick: this.closeSearch, - buttonClass: "big" - }) - ); - } -}); - -module.exports = EditorSearchBar; diff --git a/src/components/Expressions.css b/src/components/Expressions.css deleted file mode 100644 index 46fccb7c0c..0000000000 --- a/src/components/Expressions.css +++ /dev/null @@ -1,45 +0,0 @@ -.input-expression { - width: 100%; - padding: 5px; - margin: 0px; - border: none; - cursor: hand; -} - -.expression-container { - border: 1px; - padding: 5px 2px 5px 5px; - margin: 1px; - width: 100%; - color: var(--theme-body-color) !important; - background-color: var(--theme-tab-toolbar-background); -} - -.expression-container:hover { - background-color: var(--theme-selection-background); - color: var(--theme-body-background) !important; -} - -.expression-output-container .close-btn { - width: 6px; - height: 6px; - float: right; - margin-right: 6px; - display: block; - cursor: pointer; -} - -.expression-input { - cursor: pointer; - max-width: 50%; -} - -.expression-value { - overflow-x: scroll; - color: var(--theme-content-color2); - max-width: 50% !important; -} - -.expression-error { - color: var(--theme-highlight-red); -} diff --git a/src/components/Expressions.js b/src/components/Expressions.js deleted file mode 100644 index cb979f26a6..0000000000 --- a/src/components/Expressions.js +++ /dev/null @@ -1,145 +0,0 @@ -const React = require("react"); -const { connect } = require("react-redux"); -const { bindActionCreators } = require("redux"); -const ImPropTypes = require("react-immutable-proptypes"); -const actions = require("../actions"); -const { getExpressions, getPause } = require("../selectors"); -const Rep = React.createFactory(require("./Rep")); -const CloseButton = React.createFactory(require("./CloseButton")); -const { DOM: dom, PropTypes } = React; - -require("./Expressions.css"); - -const Expressions = React.createClass({ - propTypes: { - expressions: ImPropTypes.list, - addExpression: PropTypes.func, - updateExpression: PropTypes.func, - deleteExpression: PropTypes.func, - expressionInputVisibility: PropTypes.bool, - loadObjectProperties: PropTypes.func, - loadedObjects: ImPropTypes.map, - }, - - displayName: "Expressions", - - inputKeyPress(e, { id }) { - if (e.key !== "Enter") { - return; - } - const { addExpression } = this.props; - const expression = { - input: e.target.value - }; - if (id !== undefined) { - expression.id = id; - } - e.target.value = ""; - addExpression(expression); - }, - - updateExpression(e, { id }) { - e.stopPropagation(); - const { updateExpression } = this.props; - const expression = { - id, - input: e.target.textContent - }; - updateExpression(expression); - }, - - renderExpressionValue(value) { - if (!value) { - return dom.span( - { className: "expression-error" }, - "" - ); - } - if (value.exception) { - return Rep({ object: value.exception }); - } - return Rep({ object: value.result }); - }, - - deleteExpression(e, expression) { - e.stopPropagation(); - const { deleteExpression } = this.props; - deleteExpression(expression); - }, - - renderExpressionUpdating(expression) { - return dom.span( - { className: "expression-input-container" }, - dom.input( - { type: "text", - className: "input-expression", - onKeyPress: e => this.inputKeyPress(e, expression), - defaultValue: expression.input, - ref: (c) => { - this._input = c; - } - } - ) - ); - }, - - renderExpression(expression) { - return dom.span( - { className: "expression-output-container", - key: expression.id }, - dom.span( - { className: "expression-input", - onClick: e => this.updateExpression(e, expression) }, - expression.input - ), - dom.span( - { className: "expression-seperator" }, - ": " - ), - dom.span( - { className: "expression-value" }, - this.renderExpressionValue(expression.value) - ), - CloseButton({ handleClick: e => this.deleteExpression(e, expression) }), - ); - }, - - renderExpressionContainer(expression) { - return dom.div( - { className: "expression-container", - key: expression.id + expression.input }, - expression.updating ? - this.renderExpressionUpdating(expression) : - this.renderExpression(expression) - ); - }, - - componentDidUpdate() { - if (this._input) { - this._input.focus(); - } - }, - - render() { - const { expressions } = this.props; - return dom.span( - { className: "pane expressions-list" }, - this.props.expressionInputVisibility ? - dom.input( - { type: "text", - className: "input-expression", - placeholder: L10N.getStr("expressions.placeholder"), - onKeyPress: e => this.inputKeyPress(e, {}) } - ) : null, - expressions.toSeq().map(expression => - this.renderExpressionContainer(expression)) - ); - } -}); - -module.exports = connect( - state => ({ pauseInfo: getPause(state), - expressions: getExpressions(state), - }), - dispatch => bindActionCreators(actions, dispatch) -)(Expressions); diff --git a/src/components/Frames.css b/src/components/Frames.css deleted file mode 100644 index c18faaf349..0000000000 --- a/src/components/Frames.css +++ /dev/null @@ -1,58 +0,0 @@ -.frames ul { - list-style: none; - margin: 0; - padding: 0; -} - -.frames ul li { - cursor: pointer; - padding: 7px 10px 7px 21px; - clear: both; - overflow: hidden; -} - -/* Style the focused call frame like so: -.frames ul li:focus { - border: 3px solid red; -} -*/ - -.frames ul li * { - -moz-user-select: none; - user-select: none; -} - -.frames ul li:nth-of-type(2n) { - background-color: var(--theme-tab-toolbar-background); -} - -.frames .location { - float: right; - color: var(--theme-comment); - font-weight: lighter; -} - -.frames .title { - float: left; - text-overflow: ellipsis; - overflow: hidden; - margin-right: 1em; -} - -.frames ul li.selected, -.frames ul li.selected .location { - background-color: var(--theme-selection-background); - color: white; -} - -.show-more { - cursor: pointer; - text-align: center; - padding: 8px 0px; - border-top: 1px solid var(--theme-splitter-color); - background-color: var(--theme-tab-toolbar-background); -} - -.show-more:hover { - background-color: var(--theme-search-overlays-semitransparent); -} diff --git a/src/components/Frames.js b/src/components/Frames.js deleted file mode 100644 index 1150fc81b5..0000000000 --- a/src/components/Frames.js +++ /dev/null @@ -1,130 +0,0 @@ -// @flow -const React = require("react"); -const { DOM: dom, PropTypes } = React; -const { div } = dom; -const { bindActionCreators } = require("redux"); -const { connect } = require("react-redux"); -const ImPropTypes = require("react-immutable-proptypes"); -const actions = require("../actions"); -const { endTruncateStr } = require("../utils/utils"); -const { getFilename } = require("../utils/source"); -const { getFrames, getSelectedFrame, getSource } = require("../selectors"); -const classNames = require("classnames"); - -import type { List } from "immutable"; -import type { Frame } from "../types"; - -if (typeof window == "object") { - require("./Frames.css"); -} - -const NUM_FRAMES_SHOWN = 7; - -function renderFrameTitle({ displayName }: Frame) { - return div({ className: "title" }, endTruncateStr(displayName, 40)); -} - -function renderFrameLocation({ source, location }: Frame) { - const filename = getFilename(source); - return div( - { className: "location" }, - `${filename}: ${location.line}` - ); -} - -const Frames = React.createClass({ - propTypes: { - frames: ImPropTypes.list, - selectedFrame: PropTypes.object, - selectFrame: PropTypes.func.isRequired - }, - - displayName: "Frames", - - getInitialState() { - return { showAllFrames: false }; - }, - - toggleFramesDisplay() { - this.setState({ - showAllFrames: !this.state.showAllFrames - }); - }, - - renderFrame(frame: Frame) { - const { selectedFrame, selectFrame } = this.props; - - return dom.li( - { key: frame.id, - className: classNames("frame", { - "selected": selectedFrame && selectedFrame.id === frame.id - }), - onMouseDown: () => selectFrame(frame), - tabIndex: 0 - }, - renderFrameTitle(frame), - renderFrameLocation(frame) - ); - }, - - renderFrames(frames: List) { - const numFramesToShow = - this.state.showAllFrames ? frames.size : NUM_FRAMES_SHOWN; - const framesToShow = frames.slice(0, numFramesToShow); - - return dom.ul({}, framesToShow.map(this.renderFrame)); - }, - - renderToggleButton(frames: List) { - let buttonMessage = this.state.showAllFrames - ? L10N.getStr("callStack.collapse") : L10N.getStr("callStack.expand"); - - if (frames.size < NUM_FRAMES_SHOWN) { - return null; - } - - return dom.div( - { className: "show-more", onClick: this.toggleFramesDisplay }, - buttonMessage - ); - }, - - render() { - const { frames } = this.props; - - if (!frames) { - return div( - { className: "pane frames" }, - div( - { className: "pane-info empty" }, - L10N.getStr("callStack.notPaused") - ) - ); - } - - return div( - { className: "pane frames" }, - this.renderFrames(frames), - this.renderToggleButton(frames) - ); - } -}); - -function getAndProcessFrames(state) { - const frames = getFrames(state); - if (!frames) { - return null; - } - return frames.filter(frame => getSource(state, frame.location.sourceId)) - .map(frame => Object.assign({}, frame, { - source: getSource(state, frame.location.sourceId).toJS() - })); -} - -module.exports = connect( - state => ({ - frames: getAndProcessFrames(state), - selectedFrame: getSelectedFrame(state) - }), - dispatch => bindActionCreators(actions, dispatch) -)(Frames); diff --git a/src/components/ObjectInspector.css b/src/components/ObjectInspector.css deleted file mode 100644 index 5ba452a7d0..0000000000 --- a/src/components/ObjectInspector.css +++ /dev/null @@ -1,29 +0,0 @@ -.arrow svg { - fill: var(--theme-splitter-color); - margin-top: 3px; - transition: transform 0.25s ease; - width: 10px; -} - -html:not([dir="rtl"]) .arrow svg { - margin-right: 5px; - transform: rotate(-90deg); -} - -html[dir="rtl"] .arrow svg { - margin-left: 5px; - transform: rotate(90deg); -} - -/* TODO (Amit): html is just for specificity. keep it like this? */ -html .arrow.expanded svg { - transform: rotate(0deg); -} - -.arrow.hidden { - visibility: hidden; -} - -.object-node .unavailable { - color: var(--theme-body-color-inactive); -} diff --git a/src/components/ObjectInspector.js b/src/components/ObjectInspector.js deleted file mode 100644 index 3dd911419e..0000000000 --- a/src/components/ObjectInspector.js +++ /dev/null @@ -1,203 +0,0 @@ -const React = require("react"); -const classnames = require("classnames"); -const ManagedTree = React.createFactory(require("./utils/ManagedTree")); -const Svg = require("./utils/Svg"); -const Rep = require("./Rep"); -const { DOM: dom, PropTypes } = React; - -require("./ObjectInspector.css"); - -// This implements a component that renders an interactive inspector -// for looking at JavaScript objects. It expects descriptions of -// objects from the protocol, and will dynamically fetch child -// properties as objects are expanded. -// -// If you want to inspect a single object, pass the name and the -// protocol descriptor of it: -// -// ObjectInspector({ -// name: "foo", -// desc: { writable: true, ..., { value: { actor: "1", ... }}}, -// ... -// }) -// -// If you want multiple top-level objects (like scopes), you can pass -// an array of manually constructed nodes as `roots`: -// -// ObjectInspector({ -// roots: [{ name: ... }, ...], -// ... -// }); - -// There are 3 types of nodes: a simple node with a children array, an -// object that has properties that should be children when they are -// fetched, and a primitive value that should be displayed with no -// children. - -function nodeHasChildren(item) { - return Array.isArray(item.contents); -} - -function nodeIsOptimizedOut(item) { - return !nodeHasChildren(item) && item.contents.value.optimizedOut === true; -} - -function nodeIsMissingArguments(item) { - return !nodeHasChildren(item) && - item.contents.value.missingArguments === true; -} - -function nodeHasProperties(item) { - return !nodeHasChildren(item) && item.contents.value.type === "object"; -} - -function nodeIsPrimitive(item) { - return !nodeHasChildren(item) && !nodeHasProperties(item); -} - -function createNode(name, path, contents) { - // The path is important to uniquely identify the item in the entire - // tree. This helps debugging & optimizes React's rendering of large - // lists. The path will be separated by property name, - // i.e. `{ foo: { bar: { baz: 5 }}}` will have a path of `foo/bar/baz` - // for the inner object. - return { name, path, contents }; -} - -const ObjectInspector = React.createClass({ - propTypes: { - name: PropTypes.string, - desc: PropTypes.object, - roots: PropTypes.array, - getObjectProperties: PropTypes.func.isRequired, - loadObjectProperties: PropTypes.func.isRequired - }, - - displayName: "ObjectInspector", - - getInitialState() { - // Cache of dynamically built nodes. We shouldn't need to clear - // this out ever, since we don't ever "switch out" the object - // being inspected. - this.actorCache = {}; - return {}; - }, - - makeNodesForProperties(objProps, parentPath) { - const { ownProperties, prototype } = objProps; - - const nodes = Object.keys(ownProperties).filter(name => { - // Ignore non-concrete values like getters and setters - // for now by making sure we have a value. - return "value" in ownProperties[name]; - }).map(name => { - return createNode(name, `${parentPath}/${name}`, ownProperties[name]); - }); - - // Add the prototype if it exists and is not null - if (prototype && prototype.type !== "null") { - nodes.push(createNode( - "__proto__", - `${parentPath}/__proto__`, - { value: prototype } - )); - } - - return nodes; - }, - - getChildren(item) { - const { getObjectProperties } = this.props; - const obj = item.contents; - - // Nodes can either have children already, or be an object with - // properties that we need to go and fetch. - if (nodeHasChildren(item)) { - return item.contents; - } else if (nodeHasProperties(item)) { - const actor = obj.value.actor; - - // Because we are dynamically creating the tree as the user - // expands it (not precalcuated tree structure), we cache child - // arrays. This not only helps performance, but is necessary - // because the expanded state depends on instances of nodes - // being the same across renders. If we didn't do this, each - // node would be a new instance every render. - const key = item.path; - if (this.actorCache[key]) { - return this.actorCache[key]; - } - - const loadedProps = getObjectProperties(actor); - if (loadedProps) { - const children = this.makeNodesForProperties(loadedProps, item.path); - this.actorCache[actor] = children; - return children; - } - return []; - } - return []; - }, - - renderItem(item, depth, focused, _, expanded, { setExpanded }) { - let objectValue; - if (nodeIsOptimizedOut(item)) { - objectValue = dom.span({ className: "unavailable" }, "(optimized away)"); - } else if (nodeIsMissingArguments(item)) { - objectValue = dom.span({ className: "unavailable" }, "(unavailable)"); - } else if (nodeHasProperties(item) || nodeIsPrimitive(item)) { - const object = item.contents.value; - objectValue = Rep({ object, mode: "tiny" }); - } - - return dom.div( - { className: classnames("node object-node", { focused }), - style: { marginLeft: depth * 15 }, - onClick: e => { - e.stopPropagation(); - setExpanded(item, !expanded); - } - }, - Svg("arrow", { - className: classnames({ - expanded: expanded, - hidden: nodeIsPrimitive(item) - }) - }), - dom.span({ className: "object-label" }, item.name), - dom.span({ className: "object-delimiter" }, - objectValue ? ": " : ""), - dom.span({ className: "object-value" }, objectValue || "") - ); - }, - - render() { - const { name, desc, loadObjectProperties } = this.props; - - let roots = this.props.roots; - if (!roots) { - roots = [createNode(name, name, desc)]; - } - - return ManagedTree({ - itemHeight: 20, - getParent: item => null, - getChildren: this.getChildren, - getRoots: () => roots, - getKey: item => item.path, - autoExpand: 0, - autoExpandDepth: 1, - autoExpandAll: false, - disabledFocus: true, - onExpand: item => { - if (nodeHasProperties(item)) { - loadObjectProperties(item.contents.value); - } - }, - - renderItem: this.renderItem - }); - } -}); - -module.exports = ObjectInspector; diff --git a/src/components/Rep.js b/src/components/Rep.js deleted file mode 100644 index f9b0f00563..0000000000 --- a/src/components/Rep.js +++ /dev/null @@ -1,9 +0,0 @@ -const React = require("react"); -let { Rep, Grip } = require("devtools-modules"); -Rep = React.createFactory(Rep); - -function renderRep({ object, mode }) { - return Rep({ object, defaultRep: Grip, mode }); -} - -module.exports = renderRep; diff --git a/src/components/RightSidebar.css b/src/components/RightSidebar.css deleted file mode 100644 index c20aededda..0000000000 --- a/src/components/RightSidebar.css +++ /dev/null @@ -1,28 +0,0 @@ -.right-sidebar { - display: flex; - flex-direction: column; - flex: 1; - white-space: nowrap; -} - -.right-siderbar * { - -moz-user-select: none; - user-select: none; -} - -.right-sidebar .accordion { - overflow-y: auto; - overflow-x: hidden; -} - -.pane { - color: var(--theme-body-color); -} - -.pane .pane-info { - font-style: italic; - text-align: center; - padding: 0.5em; - -moz-user-select: none; - user-select: none; -} diff --git a/src/components/RightSidebar.js b/src/components/RightSidebar.js deleted file mode 100644 index 7b07cb69ec..0000000000 --- a/src/components/RightSidebar.js +++ /dev/null @@ -1,102 +0,0 @@ -const React = require("react"); -const { DOM: dom, PropTypes } = React; -const { connect } = require("react-redux"); -const { bindActionCreators } = require("redux"); -const { isEnabled } = require("devtools-config"); -const Svg = require("./utils/Svg"); - -const actions = require("../actions"); -const Breakpoints = React.createFactory(require("./Breakpoints")); -const Expressions = React.createFactory(require("./Expressions")); -const Scopes = React.createFactory(require("./Scopes")); -const Frames = React.createFactory(require("./Frames")); -const Accordion = React.createFactory(require("./Accordion")); -const CommandBar = React.createFactory(require("./CommandBar")); -require("./RightSidebar.css"); - -function debugBtn(onClick, type, className, tooltip) { - className = `${type} ${className}`; - return dom.button( - { onClick, className, key: type }, - Svg(type, { title: tooltip, "aria-label": tooltip }) - ); -} - -const RightSidebar = React.createClass({ - propTypes: { - evaluateExpressions: PropTypes.func, - }, - - contextTypes: { - shortcuts: PropTypes.object - }, - - displayName: "RightSidebar", - - getInitialState() { - return { - expressionInputVisibility: true - }; - }, - - watchExpressionHeaderButtons() { - const { expressionInputVisibility } = this.state; - return [ - debugBtn( - evt => { - evt.stopPropagation(); - this.props.evaluateExpressions(); - }, "domain", - "accordion-button", "Refresh"), - debugBtn( - evt => { - evt.stopPropagation(); - this.setState({ - expressionInputVisibility: !expressionInputVisibility - }); - }, "file", - "accordion-button", "Add Watch Expression") - ]; - }, - - getItems() { - const { expressionInputVisibility } = this.state; - - const items = [ - { header: L10N.getStr("breakpoints.header"), - component: Breakpoints, - opened: true }, - { header: L10N.getStr("callStack.header"), - component: Frames }, - { header: L10N.getStr("scopes.header"), - component: Scopes } - ]; - if (isEnabled("watchExpressions")) { - items.unshift({ header: L10N.getStr("watchExpressions.header"), - buttons: this.watchExpressionHeaderButtons(), - component: Expressions, - componentProps: { expressionInputVisibility }, - opened: true - }); - } - return items; - }, - - render() { - return ( - dom.div( - { className: "right-sidebar", - style: { overflowX: "hidden" }}, - CommandBar(), - Accordion({ - items: this.getItems() - }) - ) - ); - } -}); - -module.exports = connect( - () => ({}), - dispatch => bindActionCreators(actions, dispatch) -)(RightSidebar); diff --git a/src/components/Scopes.css b/src/components/Scopes.css deleted file mode 100644 index 034c723016..0000000000 --- a/src/components/Scopes.css +++ /dev/null @@ -1,23 +0,0 @@ - -.object-label { - color: var(--theme-highlight-blue); -} - -.objectBox-object, -.objectBox-string, -.objectBox-text, -.objectBox-table, -.objectLink-textNode, -.objectLink-event, -.objectLink-eventLog, -.objectLink-regexp, -.objectLink-object, -.objectLink-Date, -.theme-dark .objectBox-object, -.theme-light .objectBox-object { - white-space: nowrap; -} - -.scopes-list .tree-node { - overflow: hidden; -} diff --git a/src/components/Scopes.js b/src/components/Scopes.js deleted file mode 100644 index 280b6478c2..0000000000 --- a/src/components/Scopes.js +++ /dev/null @@ -1,193 +0,0 @@ -const React = require("react"); -const { bindActionCreators } = require("redux"); -const { connect } = require("react-redux"); -const ImPropTypes = require("react-immutable-proptypes"); -const actions = require("../actions"); -const { getSelectedFrame, getLoadedObjects, getPause } = require("../selectors"); -const ObjectInspector = React.createFactory(require("./ObjectInspector")); -const { DOM: dom, PropTypes } = React; -const toPairs = require("lodash/toPairs"); - -require("./Scopes.css"); - -function info(text) { - return dom.div({ className: "pane-info" }, text); -} - -// Create the tree nodes representing all the variables and arguments -// for the bindings from a scope. -function getBindingVariables(bindings, parentName) { - const args = bindings.arguments.map(arg => toPairs(arg)[0]); - const variables = toPairs(bindings.variables); - - return args.concat(variables) - .map(binding => ({ - name: binding[0], - path: `${parentName}/${binding[0]}`, - contents: binding[1] - })); -} - -function getSpecialVariables(pauseInfo, path) { - let thrown = pauseInfo.getIn(["why", "frameFinished", "throw"]); - const returned = pauseInfo.getIn(["why", "frameFinished", "return"]); - const vars = []; - - if (thrown) { - // handle dehydrating exception strings and errors. - thrown = thrown.toJS ? thrown.toJS() : thrown; - - vars.push({ - name: "", - path: `${path}/`, - contents: { value: thrown } - }); - } - - if (returned) { - vars.push({ - name: "", - path: `${path}/`, - contents: { value: returned.toJS() } - }); - } - - return vars; -} - -function getThisVariable(frame, path) { - const this_ = frame.this; - - if (!this_) { - return null; - } - - return { - name: "", - path: `${path}/`, - contents: { value: this_ } - }; -} - -function getScopes(pauseInfo, selectedFrame) { - if (!pauseInfo || !selectedFrame) { - return null; - } - - let selectedScope = selectedFrame.scope; - - if (!selectedScope) { - return null; - } - - const scopes = []; - - let scope = selectedScope; - let pausedScopeActor = pauseInfo.getIn(["frame", "scope"]).get("actor"); - - do { - const type = scope.type; - const key = scope.actor; - if (type === "function" || type === "block") { - const bindings = scope.bindings; - let title; - if (type === "function") { - title = scope.function.displayName || "(anonymous)"; - } else { - title = L10N.getStr("scopes.block"); - } - - let vars = getBindingVariables(bindings, title); - - // show exception, return, and this variables in innermost scope - if (scope.actor === pausedScopeActor) { - vars = vars.concat(getSpecialVariables(pauseInfo, key)); - } - - if (scope.actor === selectedScope.actor) { - let this_ = getThisVariable(selectedFrame, key); - - if (this_) { - vars.push(this_); - } - } - - if (vars && vars.length) { - vars.sort((a, b) => a.name.localeCompare(b.name)); - scopes.push({ name: title, path: key, contents: vars }); - } - } else if (type === "object") { - let value = scope.object; - // If this is the global window scope, mark it as such so that it will - // preview Window: Global instead of Window: Window - if (value.class === "Window") { - value = Object.assign({}, scope.object, { isGlobal: true }); - } - scopes.push({ - name: scope.object.class, - path: key, - contents: { value } - }); - } - } while (scope = scope.parent); // eslint-disable-line no-cond-assign - - return scopes; -} - -const Scopes = React.createClass({ - propTypes: { - pauseInfo: ImPropTypes.map, - loadedObjects: ImPropTypes.map, - loadObjectProperties: PropTypes.func, - selectedFrame: PropTypes.object - }, - - displayName: "Scopes", - - getInitialState() { - const { pauseInfo, selectedFrame } = this.props; - return { scopes: getScopes(pauseInfo, selectedFrame) }; - }, - - componentWillReceiveProps(nextProps) { - const { pauseInfo, selectedFrame } = this.props; - const pauseInfoChanged = pauseInfo !== nextProps.pauseInfo; - const selectedFrameChange = selectedFrame !== nextProps.selectedFrame; - - if (pauseInfoChanged || selectedFrameChange) { - this.setState({ - scopes: getScopes(nextProps.pauseInfo, nextProps.selectedFrame) - }); - } - }, - - render() { - const { pauseInfo, loadObjectProperties, loadedObjects } = this.props; - const { scopes } = this.state; - - let scopeInspector = info(L10N.getStr("scopes.notAvailable")); - if (scopes) { - scopeInspector = ObjectInspector({ - roots: scopes, - getObjectProperties: id => loadedObjects.get(id), - loadObjectProperties: loadObjectProperties - }); - } - - return dom.div( - { className: "pane scopes-list" }, - pauseInfo - ? scopeInspector - : info(L10N.getStr("scopes.notPaused")) - ); - } -}); - -module.exports = connect( - state => ({ - pauseInfo: getPause(state), - selectedFrame: getSelectedFrame(state), - loadedObjects: getLoadedObjects(state) - }), - dispatch => bindActionCreators(actions, dispatch) -)(Scopes); diff --git a/src/components/SourceFooter.css b/src/components/SourceFooter.css deleted file mode 100644 index 415464a28f..0000000000 --- a/src/components/SourceFooter.css +++ /dev/null @@ -1,46 +0,0 @@ - -.source-footer { - background: var(--theme-body-background); - border-top: 1px solid var(--theme-splitter-color); - position: absolute; - bottom: 0; - left: 0; - right: 1px; - opacity: 1; - z-index: 100; - -moz-user-select: none; - user-select: none; -} - -.source-footer .commands { - display: flex; - padding: 8px 0.7em; -} - -.source-footer .commands * { - -moz-user-select: none; - user-select: none; -} - -.source-footer > .commands > .action { - cursor: pointer; - display: flex; - justify-content: center; - align-items: center; - transition: opacity 200ms; - border: none; - background: transparent; -} - -:root.theme-dark .source-footer > .commands > .action { - fill: var(--theme-body-color); -} - -:root.theme-dark .source-footer > .commands > .action:hover { - fill: var(--theme-selection-color); -} - -.source-footer > .commands > .action svg { - height: 1em; - width: 1em; -} diff --git a/src/components/SourceFooter.js b/src/components/SourceFooter.js deleted file mode 100644 index a3a2282070..0000000000 --- a/src/components/SourceFooter.js +++ /dev/null @@ -1,84 +0,0 @@ -const React = require("react"); -const { DOM: dom, PropTypes } = React; -const { connect } = require("react-redux"); -const { bindActionCreators } = require("redux"); -const actions = require("../actions"); -const { getSelectedSource, getSourceText, getPrettySource } = require("../selectors"); -const Svg = require("./utils/Svg"); -const ImPropTypes = require("react-immutable-proptypes"); -const classnames = require("classnames"); -const { isPretty } = require("../utils/source"); -const { shouldShowFooter, shouldShowPrettyPrint } = require("../utils/editor"); - -require("./SourceFooter.css"); - -function debugBtn(onClick, type, className = "active", tooltip) { - className = `${type} ${className} action`; - return dom.button( - { onClick, className, key: type }, - Svg(type, { title: tooltip, "aria-label": tooltip }) - ); -} - -const SourceFooter = React.createClass({ - propTypes: { - selectedSource: ImPropTypes.map, - togglePrettyPrint: PropTypes.func, - sourceText: ImPropTypes.map, - selectSource: PropTypes.func, - prettySource: ImPropTypes.map, - editor: PropTypes.object, - }, - - displayName: "SourceFooter", - - onClickPrettyPrint() { - this.props.togglePrettyPrint(this.props.selectedSource.get("id")); - }, - - prettyPrintButton() { - const { selectedSource, sourceText } = this.props; - const sourceLoaded = selectedSource && !sourceText.get("loading"); - - if (!shouldShowPrettyPrint(selectedSource.toJS())) { - return; - } - - return debugBtn( - this.onClickPrettyPrint, - "prettyPrint", - classnames({ - active: sourceLoaded, - pretty: isPretty(selectedSource.toJS()) - }), - L10N.getStr("sourceFooter.debugBtnTooltip") - ); - }, - - render() { - const { selectedSource } = this.props; - - if (!selectedSource || !shouldShowFooter(selectedSource.toJS())) { - return null; - } - - return dom.div({ className: "source-footer" }, - dom.div({ className: "commands" }, - this.prettyPrintButton() - ) - ); - } -}); - -module.exports = connect( - state => { - const selectedSource = getSelectedSource(state); - const selectedId = selectedSource && selectedSource.get("id"); - return { - selectedSource, - sourceText: getSourceText(state, selectedId), - prettySource: getPrettySource(state, selectedId) - }; - }, - dispatch => bindActionCreators(actions, dispatch) -)(SourceFooter); diff --git a/src/components/SourceSearch.css b/src/components/SourceSearch.css deleted file mode 100644 index 88fe77f1a3..0000000000 --- a/src/components/SourceSearch.css +++ /dev/null @@ -1,28 +0,0 @@ -/* vim:set ts=2 sw=2 sts=2 et: */ - -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -.search-container { - position: absolute; - top: 30px; - left: 0; - width: calc(100% - 1px); - height: calc(100% - 31px); - display: flex; - z-index: 200; - background-color: var(--theme-body-background); -} - -.search-container .autocomplete { - flex: 1; -} - -.searchinput-container { - display: flex; -} - -.searchinput-container .close-btn-big { - border-bottom: 1px solid var(--theme-splitter-color); -} diff --git a/src/components/SourceSearch.js b/src/components/SourceSearch.js deleted file mode 100644 index a5d9fa687e..0000000000 --- a/src/components/SourceSearch.js +++ /dev/null @@ -1,112 +0,0 @@ -const React = require("react"); -const { DOM: dom, PropTypes, createFactory } = React; -const { connect } = require("react-redux"); -const { bindActionCreators } = require("redux"); -const actions = require("../actions"); -const { - getSources, - getSelectedSource, - getFileSearchState -} = require("../selectors"); -const { endTruncateStr } = require("../utils/utils"); -const { parse: parseURL } = require("url"); -const { isPretty } = require("../utils/source"); - -require("./SourceSearch.css"); - -const Autocomplete = createFactory(require("./Autocomplete")); - -function searchResults(sources) { - function getSourcePath(source) { - const { path, href } = parseURL(source.get("url")); - // for URLs like "about:home" the path is null so we pass the full href - return endTruncateStr((path || href), 50); - } - - return sources.valueSeq() - .filter(source => !isPretty(source.toJS()) && source.get("url")) - .map(source => ({ - value: getSourcePath(source), - title: getSourcePath(source).split("/").pop(), - subtitle: getSourcePath(source), - id: source.get("id") - })) - .toJS(); -} - -const Search = React.createClass({ - propTypes: { - sources: PropTypes.object, - selectSource: PropTypes.func, - selectedSource: PropTypes.object, - toggleFileSearch: PropTypes.func, - searchOn: PropTypes.bool - }, - - contextTypes: { - shortcuts: PropTypes.object - }, - - displayName: "Search", - - getInitialState() { - return { - inputValue: "" - }; - }, - - componentWillUnmount() { - const shortcuts = this.context.shortcuts; - shortcuts.off("CmdOrCtrl+P", this.toggle); - shortcuts.off("Escape", this.onEscape); - }, - - componentDidMount() { - const shortcuts = this.context.shortcuts; - shortcuts.on("CmdOrCtrl+P", this.toggle); - shortcuts.on("Escape", this.onEscape); - }, - - toggle(key, e) { - e.preventDefault(); - this.props.toggleFileSearch(!this.props.searchOn); - }, - - onEscape(shortcut, e) { - if (this.props.searchOn) { - e.preventDefault(); - this.setState({ inputValue: "" }); - this.props.toggleFileSearch(false); - } - }, - - close(inputValue = "") { - this.setState({ inputValue }); - this.props.toggleFileSearch(false); - }, - - render() { - return this.props.searchOn ? - dom.div({ className: "search-container" }, - Autocomplete({ - selectItem: result => { - this.props.selectSource(result.id); - this.setState({ inputValue: "" }); - this.props.toggleFileSearch(false); - }, - close: this.close, - items: searchResults(this.props.sources), - inputValue: this.state.inputValue - })) : null; - } - -}); - -module.exports = connect( - state => ({ - sources: getSources(state), - selectedSource: getSelectedSource(state), - searchOn: getFileSearchState(state) - }), - dispatch => bindActionCreators(actions, dispatch) -)(Search); diff --git a/src/components/SourceTabs.css b/src/components/SourceTabs.css deleted file mode 100644 index f0931e7e05..0000000000 --- a/src/components/SourceTabs.css +++ /dev/null @@ -1,104 +0,0 @@ -.source-header { - border-bottom: 1px solid var(--theme-splitter-color); - height: 30px; - flex: 1; -} - -.source-header * { - -moz-user-select: none; - user-select: none; -} - -.source-tabs { - min-width: 50px; - max-width: calc(100% - 60px); - overflow: hidden; - float: left; -} - -.source-header .new-tab-btn { - width: 16px; - display: inline-block; - position: relative; - top: 4px; - margin: 4px; - line-height: 0; -} - -.source-header .new-tab-btn path { - fill: var(--theme-splitter-color); -} - -.source-header .new-tab-btn:hover path { - fill: var(--theme-comment); -} - -.source-tab { - background-color: var(--theme-toolbar-background-alt); - color: var(--theme-faded-tab-color); - border: 1px solid var(--theme-splitter-color); - border-top-left-radius: 2px; - border-top-right-radius: 2px; - height: 23px; - line-height: 20px; - display: inline-block; - border-bottom: none; - position: relative; - transition: all 0.25s ease; - min-width: 40px; - overflow: hidden; -} - -html:not([dir="rtl"]) .source-tab { - padding: 2px 20px 2px 12px; - margin: 6px 0 0 8px; -} - -html[dir="rtl"] .source-tab { - padding: 2px 12px 2px 20px; - margin: 6px 8px 0 0; -} - -.source-tab:hover { - background: var(--theme-toolbar-background); - cursor: pointer; -} - -.source-tab.active { - color: var(--theme-body-color); - background-color: var(--theme-body-background); -} - -.source-tab path { - fill: var(--theme-faded-tab-color); -} - -.source-tab.active path { - fill: var(--theme-body-color); -} - -.source-tab .close-btn { - position: absolute; - top: 3px; -} - -.source-tab .filename { - text-overflow: ellipsis; - overflow: hidden; -} - -html:not([dir="rtl"]) .source-tab .close-btn { - right: 4px; -} - -html[dir="rtl"] .source-tab .close-btn { - left: 4px; -} - -.source-tab .close { - display: none; -} - -.source-tab:hover .close { - display: block; -} diff --git a/src/components/SourceTabs.js b/src/components/SourceTabs.js deleted file mode 100644 index 20a7e8ec5a..0000000000 --- a/src/components/SourceTabs.js +++ /dev/null @@ -1,230 +0,0 @@ -const React = require("react"); -const { DOM: dom, PropTypes } = React; -const ImPropTypes = require("react-immutable-proptypes"); -const { connect } = require("react-redux"); -const { bindActionCreators } = require("redux"); -const { - getSelectedSource, - getSourceTabs, - getFileSearchState -} = require("../selectors"); -const { getFilename } = require("../utils/source"); -const classnames = require("classnames"); -const actions = require("../actions"); -const CloseButton = require("./CloseButton"); -const Svg = require("./utils/Svg"); -const Dropdown = React.createFactory(require("./Dropdown")); -const { showMenu, buildMenu } = require("../utils/menu"); - -require("./SourceTabs.css"); -require("./Dropdown.css"); - -/* - * Finds the hidden tabs by comparing the tabs' top offset. - * hidden tabs will have a great top offset. - * - * @param sourceTabs Immutable.list - * @param sourceTabEls HTMLCollection - * - * @returns Immutable.list - */ -function getHiddenTabs(sourceTabs, sourceTabEls) { - sourceTabEls = [].slice.call(sourceTabEls); - function getTopOffset() { - const topOffsets = sourceTabEls.map(t => t.getBoundingClientRect().top); - return Math.min(...topOffsets); - } - - const tabTopOffset = getTopOffset(); - return sourceTabs.filter((tab, index) => { - return sourceTabEls[index].getBoundingClientRect().top > tabTopOffset; - }); -} - -const SourceTabs = React.createClass({ - propTypes: { - sourceTabs: ImPropTypes.list, - selectedSource: ImPropTypes.map, - selectSource: PropTypes.func.isRequired, - closeTab: PropTypes.func.isRequired, - closeTabs: PropTypes.func.isRequired, - toggleFileSearch: PropTypes.func.isRequired - }, - - displayName: "SourceTabs", - - getInitialState() { - return { - dropdownShown: false, - hiddenSourceTabs: null - }; - }, - - componentDidUpdate() { - this.updateHiddenSourceTabs(this.props.sourceTabs); - }, - - onTabContextMenu(event, tab) { - event.preventDefault(); - this.showContextMenu(event, tab); - }, - - showContextMenu(e, tab) { - const { closeTab, closeTabs, sourceTabs } = this.props; - - const closeTabLabel = L10N.getStr("sourceTabs.closeTab"); - const closeOtherTabsLabel = L10N.getStr("sourceTabs.closeOtherTabs"); - const closeTabsToRightLabel = L10N.getStr("sourceTabs.closeTabsToRight"); - const closeAllTabsLabel = L10N.getStr("sourceTabs.closeAllTabs"); - - const tabs = sourceTabs.map(t => t.get("id")); - - const closeTabMenuItem = { - id: "node-menu-close-tab", - label: closeTabLabel, - accesskey: "C", - disabled: false, - click: () => closeTab(tab) - }; - - const closeOtherTabsMenuItem = { - id: "node-menu-close-other-tabs", - label: closeOtherTabsLabel, - accesskey: "O", - disabled: false, - click: () => closeTabs(tabs.filter(t => t !== tab)) - }; - - const closeTabsToRightMenuItem = { - id: "node-menu-close-tabs-to-right", - label: closeTabsToRightLabel, - accesskey: "R", - disabled: false, - click: () => { - const tabIndex = tabs.findIndex(t => t == tab); - closeTabs(tabs.filter((t, i) => i > tabIndex)); - } - }; - - const closeAllTabsMenuItem = { - id: "node-menu-close-all-tabs", - label: closeAllTabsLabel, - accesskey: "A", - disabled: false, - click: () => closeTabs(tabs) - }; - - showMenu(e, buildMenu([ - { item: closeTabMenuItem }, - { item: closeOtherTabsMenuItem, hidden: () => tabs.size === 1 }, - { item: closeTabsToRightMenuItem, hidden: () => - tabs.some((t, i) => t === tab && (tabs.size - 1) === i) }, - { item: closeAllTabsMenuItem } - ])); - }, - - /* - * Updates the hiddenSourceTabs state, by - * finding the source tabs who have wrapped and are not on the top row. - */ - updateHiddenSourceTabs(sourceTabs) { - if (!this.refs.sourceTabs) { - return; - } - - const sourceTabEls = this.refs.sourceTabs.children; - const hiddenSourceTabs = getHiddenTabs(sourceTabs, sourceTabEls); - - if (!hiddenSourceTabs.equals(this.state.hiddenSourceTabs)) { - this.setState({ hiddenSourceTabs }); - } - }, - - toggleSourcesDropdown(e) { - this.setState({ - dropdownShown: !this.state.dropdownShown, - }); - }, - - renderDropdownSource(source) { - const { selectSource } = this.props; - const filename = getFilename(source.toJS()); - - return dom.li({ - key: source.get("id"), - onClick: () => { - // const tabIndex = getLastVisibleTabIndex(sourceTabs, sourceTabEls); - const tabIndex = 0; - selectSource(source.get("id"), { tabIndex }); - } - }, filename); - }, - - renderTabs() { - const sourceTabs = this.props.sourceTabs; - return dom.div( - { className: "source-tabs", ref: "sourceTabs" }, - sourceTabs.map(this.renderTab) - ); - }, - - renderTab(source) { - const { selectedSource, selectSource, closeTab } = this.props; - const filename = getFilename(source.toJS()); - const active = source.get("id") == selectedSource.get("id"); - - function onClickClose(ev) { - ev.stopPropagation(); - closeTab(source.get("id")); - } - - return dom.div( - { - className: classnames("source-tab", { active }), - key: source.get("id"), - onClick: () => selectSource(source.get("id")), - onContextMenu: (e) => this.onTabContextMenu(e, source.get("id")), - title: source.get("url") - }, - dom.div({ className: "filename" }, filename), - CloseButton({ handleClick: onClickClose })); - }, - - renderNewButton() { - return dom.div({ - className: "new-tab-btn", - onClick: () => this.props.toggleFileSearch(true) - }, Svg("plus")); - }, - - renderDropdown() { - const hiddenSourceTabs = this.state.hiddenSourceTabs; - if (!hiddenSourceTabs || hiddenSourceTabs.size == 0) { - return dom.div({}); - } - - return Dropdown({ - panel: dom.ul( - {}, - this.state.hiddenSourceTabs.map(this.renderDropdownSource) - ) - }); - }, - - render() { - return dom.div({ className: "source-header" }, - this.renderTabs(), - this.renderNewButton(), - this.renderDropdown() - ); - } -}); - -module.exports = connect( - state => ({ - selectedSource: getSelectedSource(state), - sourceTabs: getSourceTabs(state), - searchOn: getFileSearchState(state) - }), - dispatch => bindActionCreators(actions, dispatch) -)(SourceTabs); diff --git a/src/components/Sources.css b/src/components/Sources.css deleted file mode 100644 index b3147e8e63..0000000000 --- a/src/components/Sources.css +++ /dev/null @@ -1,144 +0,0 @@ -.sources-panel { - flex: 1; - display: flex; - flex-direction: column; - overflow: hidden; -} - -.sources-panel * { - -moz-user-select: none; - user-select: none; -} - -.sources-header { - height: 30px; - border-bottom: 1px solid var(--theme-splitter-color); - padding-top: 0px; - padding-bottom: 0px; - line-height: 30px; - font-size: 1.2em; - display: flex; - align-items: baseline; - justify-content: space-between; - -moz-user-select: none; - user-select: none; -} - -html:not([dir="rtl"]) .sources-header { - padding-left: 10px; -} - -html[dir="rtl"] .sources-header { - padding-right: 10px; -} - -.sources-header-info { - font-size: 12px; - color: var(--theme-comment-alt); - font-weight: lighter; - white-space: nowrap; -} - -html:not([dir="rtl"]) .sources-header-info { - padding-right: 10px; - float: right; -} - -html[dir="rtl"] .sources-header-info { - padding-left: 10px; - float: left; -} - -.sources-list { - flex: 1; - display: flex; - overflow: hidden; -} - -.arrow, -.folder, -.domain, -.file, -.worker { - fill: var(--theme-splitter-color); -} - -.domain, -.file, -.worker { - position: relative; - top: 1px; -} - -.worker, -.folder { - position: relative; - top: 2px; -} - -.domain svg, -.folder svg, -.worker svg { - width: 15px; -} - -.file svg { - width: 13px; -} - -html:not([dir="rtl"]) .file svg, -html:not([dir="rtl"]) .domain svg, -html:not([dir="rtl"]) .folder svg, -html:not([dir="rtl"]) .worker svg { - margin-right: 5px; -} - -html[dir="rtl"] .file svg, -html[dir="rtl"] .domain svg, -html[dir="rtl"] .folder svg, -html[dir="rtl"] .worker svg { - margin-left: 5px; -} - -.tree { - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - -o-user-select: none; - user-select: none; - - flex: 1; - white-space: nowrap; - overflow: auto; -} - -.tree button { - display: block; -} - -.tree .node { - padding: 2px 5px; - position: relative; - cursor: pointer; -} - -.tree .node:hover { - background: var(--theme-tab-toolbar-background); -} - -.tree .node.focused { - color: white; - background-color: var(--theme-selection-background); -} - -.tree .node > div { - margin-left: 10px; -} - -.tree .node.focused svg { - fill: white; -} - -.sources-list .tree-node button { - position: fixed; -} diff --git a/src/components/Sources.js b/src/components/Sources.js deleted file mode 100644 index 518ebf75d2..0000000000 --- a/src/components/Sources.js +++ /dev/null @@ -1,43 +0,0 @@ -const React = require("react"); -const { DOM: dom, PropTypes } = React; -const ImPropTypes = require("react-immutable-proptypes"); -const { bindActionCreators } = require("redux"); -const { connect } = require("react-redux"); -const { cmdString } = require("../utils/text"); -const SourcesTree = React.createFactory(require("./SourcesTree")); -const actions = require("../actions"); -const { getSelectedSource, getSources } = require("../selectors"); - -require("./Sources.css"); - -const cmd = `${cmdString()}+P`; - -const Sources = React.createClass({ - propTypes: { - sources: ImPropTypes.map.isRequired, - selectSource: PropTypes.func.isRequired - }, - - displayName: "Sources", - - render() { - const { sources, selectSource } = this.props; - - return dom.div( - { className: "sources-panel" }, - dom.div({ className: "sources-header" }, - L10N.getStr("sources.header"), - dom.span({ className: "sources-header-info" }, - L10N.getFormatStr("sources.search", cmd) - ) - ), - SourcesTree({ sources, selectSource }) - ); - } -}); - -module.exports = connect( - state => ({ selectedSource: getSelectedSource(state), - sources: getSources(state) }), - dispatch => bindActionCreators(actions, dispatch) -)(Sources); diff --git a/src/components/SourcesTree.js b/src/components/SourcesTree.js deleted file mode 100644 index fe5ce950cf..0000000000 --- a/src/components/SourcesTree.js +++ /dev/null @@ -1,154 +0,0 @@ -const React = require("react"); -const { DOM: dom, PropTypes } = React; -const classnames = require("classnames"); -const ImPropTypes = require("react-immutable-proptypes"); -const { Set } = require("immutable"); - -const { - nodeHasChildren, createParentMap, addToTree, - collapseTree, createTree -} = require("../utils/sources-tree.js"); -const ManagedTree = React.createFactory(require("./utils/ManagedTree")); -const Svg = require("./utils/Svg"); -const { throttle } = require("../utils/utils"); - -let SourcesTree = React.createClass({ - propTypes: { - sources: ImPropTypes.map.isRequired, - selectSource: PropTypes.func.isRequired - }, - - displayName: "SourcesTree", - - getInitialState() { - return createTree(this.props.sources); - }, - - queueUpdate: throttle(function() { - if (!this.isMounted()) { - return; - } - - this.forceUpdate(); - }, 50), - - shouldComponentUpdate() { - this.queueUpdate(); - return false; - }, - - componentWillReceiveProps(nextProps) { - if (nextProps.sources === this.props.sources) { - return; - } - - if (nextProps.sources.size === 0) { - this.setState(createTree(nextProps.sources)); - return; - } - - const next = Set(nextProps.sources.valueSeq()); - const prev = Set(this.props.sources.valueSeq()); - const newSet = next.subtract(prev); - - const uncollapsedTree = this.state.uncollapsedTree; - for (let source of newSet) { - addToTree(uncollapsedTree, source); - } - - // TODO: recreating the tree every time messes with the expanded - // state of ManagedTree, because it depends on item instances - // being the same. The result is that if a source is added at a - // later time, all expanded state is lost. - const sourceTree = newSet.size > 0 - ? collapseTree(uncollapsedTree) - : this.state.sourceTree; - - this.setState({ uncollapsedTree, - sourceTree, - parentMap: createParentMap(sourceTree) }); - }, - - focusItem(item) { - this.setState({ focusedItem: item }); - }, - - selectItem(item) { - if (!nodeHasChildren(item)) { - this.props.selectSource(item.contents.get("id")); - } - }, - - getIcon(item, depth) { - if (depth === 0) { - return Svg("domain"); - } - - if (!nodeHasChildren(item)) { - return Svg("file"); - } - - return Svg("folder"); - }, - - renderItem(item, depth, focused, _, expanded, { setExpanded }) { - const arrow = Svg("arrow", - { - className: classnames( - { expanded: expanded, - hidden: !nodeHasChildren(item) } - ), - onClick: e => { - e.stopPropagation(); - setExpanded(item, !expanded); - } - } - ); - - const icon = this.getIcon(item, depth); - - return dom.div( - { - className: classnames("node", { focused }), - style: { paddingLeft: `${depth * 15}px` }, - key: item.path, - onClick: () => this.selectItem(item), - onDoubleClick: e => setExpanded(item, !expanded) - }, - dom.div(null, arrow, icon, item.name) - ); - }, - - render: function() { - const { focusedItem, sourceTree, parentMap } = this.state; - - const tree = ManagedTree({ - getParent: item => { - return parentMap.get(item); - }, - getChildren: item => { - if (nodeHasChildren(item)) { - return item.contents; - } - return []; - }, - getRoots: () => sourceTree.contents, - getKey: (item, i) => item.path, - itemHeight: 30, - autoExpandDepth: 1, - onFocus: this.focusItem, - renderItem: this.renderItem - }); - - return dom.div({ - className: "sources-list", - onKeyDown: e => { - if (e.keyCode === 13 && focusedItem) { - this.selectItem(focusedItem); - } - } - }, tree); - } -}); - -module.exports = SourcesTree; diff --git a/src/components/SplitBox.css b/src/components/SplitBox.css deleted file mode 100644 index 5a91c6fbcc..0000000000 --- a/src/components/SplitBox.css +++ /dev/null @@ -1,88 +0,0 @@ -/* vim:set ts=2 sw=2 sts=2 et: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -.split-box { - display: flex; - flex: 1; - min-width: 0; - height: 100%; - width: 100%; -} - -.split-box.vert { - flex-direction: row; -} - -.split-box.horz { - flex-direction: column; -} - -.split-box > .uncontrolled { - display: flex; - flex: 1; - min-width: 0; - overflow: auto; -} - -.split-box > .controlled { - display: flex; - overflow: auto; -} - -.split-box > .splitter { - background-image: none; - border: 0; - border-style: solid; - border-color: transparent; - background-color: var(--theme-splitter-color); - background-clip: content-box; - position: relative; - - box-sizing: border-box; - - /* Positive z-index positions the splitter on top of its siblings and makes - it clickable on both sides. */ - z-index: 1; -} - -.split-box.vert > .splitter { - min-width: calc(var(--devtools-splitter-inline-start-width) + - var(--devtools-splitter-inline-end-width) + 1px); - - border-left-width: var(--devtools-splitter-inline-start-width); - border-right-width: var(--devtools-splitter-inline-end-width); - - margin-left: calc(-1 * var(--devtools-splitter-inline-start-width) - 1px); - margin-right: calc(-1 * var(--devtools-splitter-inline-end-width)); - - cursor: ew-resize; -} - -.split-box.horz > .splitter { - min-height: calc(var(--devtools-splitter-top-width) + - var(--devtools-splitter-bottom-width) + 1px); - - border-top-width: var(--devtools-splitter-top-width); - border-bottom-width: var(--devtools-splitter-bottom-width); - - margin-top: calc(-1 * var(--devtools-splitter-top-width) - 1px); - margin-bottom: calc(-1 * var(--devtools-splitter-bottom-width)); - - cursor: ns-resize; -} - -.split-box.disabled { - pointer-events: none; -} - -/** - * Make sure splitter panels are not processing any mouse - * events. This is good for performance during splitter - * bar dragging. - */ -.split-box.dragging > .controlled, -.split-box.dragging > .uncontrolled { - pointer-events: none; -} diff --git a/src/components/menu.css b/src/components/menu.css deleted file mode 100644 index 7233c2f799..0000000000 --- a/src/components/menu.css +++ /dev/null @@ -1,43 +0,0 @@ -menupopup { - position: fixed; - z-index: 10000; - background: white; - border: 1px solid #cccccc; - padding: 5px 0; - background: #f2f2f2; - border-radius: 5px; - color: #585858; - box-shadow: 0 0 4px 0 rgba(190, 190, 190, 0.8); - min-width: 130px; -} - -menuitem { - display: block; - padding: 0 20px; - line-height: 20px; - font-weight: 500; - font-size: 13px; -} - -menuitem:hover { - background: #3780fb; - color: white; - cursor: pointer; -} - -menuseparator { - border-bottom: 1px solid #cacdd3; - width: 100%; - height: 5px; - display: block; - margin-bottom: 5px; -} - -#contextmenu-mask.show { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - z-index: 999; -} diff --git a/src/components/reps.css b/src/components/reps.css deleted file mode 100644 index 2cfc80c69a..0000000000 --- a/src/components/reps.css +++ /dev/null @@ -1,181 +0,0 @@ -/* vim:set ts=2 sw=2 sts=2 et: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -.theme-dark, -.theme-light { - --number-color: var(--theme-highlight-green); - --string-color: var(--theme-highlight-orange); - --null-color: var(--theme-comment); - --object-color: var(--theme-body-color); - --caption-color: var(--theme-highlight-blue); - --location-color: var(--theme-content-color1); - --source-link-color: var(--theme-highlight-blue); - --node-color: var(--theme-highlight-bluegrey); - --reference-color: var(--theme-highlight-purple); -} - -.theme-firebug { - --number-color: #000088; - --string-color: #FF0000; - --null-color: #787878; - --object-color: DarkGreen; - --caption-color: #444444; - --location-color: #555555; - --source-link-color: blue; - --node-color: rgb(0, 0, 136); - --reference-color: rgb(102, 102, 255); -} - -/******************************************************************************/ - -.objectLink:hover { - cursor: pointer; - text-decoration: underline; -} - -.inline { - display: inline; - white-space: normal; -} - -.objectBox-object { - font-weight: bold; - color: var(--object-color); - white-space: pre-wrap; -} - -.objectBox-string, -.objectBox-text, -.objectLink-textNode, -.objectBox-table { - white-space: pre-wrap; -} - -.objectBox-number, -.objectLink-styleRule, -.objectLink-element, -.objectLink-textNode, -.objectBox-array > .length { - color: var(--number-color); -} - -.objectBox-string { - color: var(--string-color); -} - -.objectLink-function, -.objectBox-stackTrace, -.objectLink-profile { - color: var(--object-color); -} - -.objectLink-Location { - font-style: italic; - color: var(--location-color); -} - -.objectBox-null, -.objectBox-undefined, -.objectBox-hint, -.logRowHint { - font-style: italic; - color: var(--null-color); -} - -.objectLink-sourceLink { - position: absolute; - right: 4px; - top: 2px; - padding-left: 8px; - font-weight: bold; - color: var(--source-link-color); -} - -/******************************************************************************/ - -.objectLink-event, -.objectLink-eventLog, -.objectLink-regexp, -.objectLink-object, -.objectLink-Date { - font-weight: bold; - color: var(--object-color); - white-space: pre-wrap; -} - -/******************************************************************************/ - -.objectLink-object .nodeName, -.objectLink-NamedNodeMap .nodeName, -.objectLink-NamedNodeMap .objectEqual, -.objectLink-NamedNodeMap .arrayLeftBracket, -.objectLink-NamedNodeMap .arrayRightBracket, -.objectLink-Attr .attrEqual, -.objectLink-Attr .attrTitle { - color: var(--node-color); -} - -.objectLink-object .nodeName { - font-weight: normal; -} - -/******************************************************************************/ - -.objectLeftBrace, -.objectRightBrace, -.arrayLeftBracket, -.arrayRightBracket { - cursor: pointer; - font-weight: bold; -} - -.objectLeftBrace, -.arrayLeftBracket { - margin-right: 4px; -} - -.objectRightBrace, -.arrayRightBracket { - margin-left: 4px; -} - -/******************************************************************************/ -/* Cycle reference*/ - -.objectLink-Reference { - font-weight: bold; - color: var(--reference-color); -} - -.objectBox-array > .objectTitle { - font-weight: bold; - color: var(--object-color); -} - -.caption { - font-weight: bold; - color: var(--caption-color); -} - -/******************************************************************************/ -/* Themes */ - -.theme-dark .objectBox-null, -.theme-dark .objectBox-undefined, -.theme-light .objectBox-null, -.theme-light .objectBox-undefined { - font-style: normal; -} - -.theme-dark .objectBox-object, -.theme-light .objectBox-object { - font-weight: normal; - white-space: pre-wrap; -} - -.theme-dark .caption, -.theme-light .caption { - font-weight: normal; -} diff --git a/src/components/test-utils.js b/src/components/test-utils.js deleted file mode 100644 index 8a6ad5e816..0000000000 --- a/src/components/test-utils.js +++ /dev/null @@ -1,46 +0,0 @@ -const { createElement, createFactory } = require("react"); -const ReactDOM = require("react-dom"); - -const renderComponentFromFixture = require("../test/utils/renderComponentFromFixture"); - -function createElementWithAttributes(tag, attrs) { - const $el = document.createElement(tag); - Object.keys(attrs).forEach(key => { - const attr = document.createAttribute(key); - attr.value = attrs[key]; - $el.setAttributeNode(attr); - }); - - return $el; -} - -function getSandbox() { - let $el = document.querySelector("#sandbox"); - if ($el) { - $el.remove(); - } - - $el = createElementWithAttributes("div", { - id: "sandbox", - style: "top: 0; position: relative; height: 500px;" - }); - - document.body.appendChild($el); - return $el; -} - -function renderComponent(Component, fixtureName, options = {}) { - const $el = getSandbox(); - - const component = renderComponentFromFixture( - createElement(createFactory(Component)), - fixtureName, - options - ); - - return ReactDOM.render(component, $el); -} - -module.exports = { - renderComponent -}; diff --git a/src/components/tests/Breakpoints.js b/src/components/tests/Breakpoints.js deleted file mode 100644 index 83f40646e8..0000000000 --- a/src/components/tests/Breakpoints.js +++ /dev/null @@ -1,42 +0,0 @@ -const Breakpoints = require("../Breakpoints"); -const { renderComponent } = require("../test-utils"); - -function getBreakpoints($el) { - return $el.querySelector(".breakpoints-list").children; -} - -function getBreakpointLabel($breakpoint) { - return $breakpoint.querySelector(".breakpoint-label").innerText; -} - -function getBreakpointClasses($breakpoint) { - return Array.from($breakpoint.classList); -} - -describe("Breakpoint Component", function() { - it("Not Paused", function() { - if (typeof window != "object") { - return; - } - - const $el = renderComponent(Breakpoints, "todomvc"); - expect($el.innerText).to.equal("No Breakpoints"); - }); - - it("3 Breakpoints", function() { - if (typeof window != "object") { - return; - } - - const $el = renderComponent(Breakpoints, "todomvcUpdateOnEnter"); - const breakpoints = getBreakpoints($el); - expect(breakpoints.length).to.equal(3); - expect(getBreakpointLabel(breakpoints[0])).to.equal("113 this.close();"); - expect(getBreakpointClasses(breakpoints[0])).to.contain("paused"); - expect(getBreakpointLabel(breakpoints[1])).to - .equal("119 revertOnEscape: function (e) {"); - expect(getBreakpointLabel(breakpoints[2])).to - .equal("121 this.$el.removeClass('editing'..."); - expect(getBreakpointClasses(breakpoints[2])).to.contain("disabled"); - }); -}); diff --git a/src/components/tests/Editor.js b/src/components/tests/Editor.js deleted file mode 100644 index afeb8a3f92..0000000000 --- a/src/components/tests/Editor.js +++ /dev/null @@ -1,18 +0,0 @@ -if (typeof window == "object") { - const Editor = require("../Editor"); - const { renderComponent } = require("../test-utils"); - - function getEditorLines($el) { - return $el.querySelectorAll(".codemirror-line"); - } - - describe("Editor", function() { - // The editor fails to load in the unit tests - xit("todomvc", function() { - const $el = renderComponent(Editor, "todomvc"); - const lines = getEditorLines($el); - expect(lines.length).to.equal(46); - expect(lines[2].innerText).to.equal("var app = app || {};"); - }); - }); -} diff --git a/src/components/tests/Frames.js b/src/components/tests/Frames.js deleted file mode 100644 index 423907253c..0000000000 --- a/src/components/tests/Frames.js +++ /dev/null @@ -1,52 +0,0 @@ -const Frames = require("../Frames"); -const { renderComponent } = require("../test-utils"); - -function getFrames($el) { - return $el.querySelectorAll(".frame"); -} - -function getFrameTitle($frame) { - return $frame.firstChild.innerText.trim(); -} - -function getFrameLocation($frame) { - return $frame.lastChild.innerText.trim(); -} - -describe("Frames", function() { - it("Not Paused", function() { - if (typeof window != "object") { - return; - } - - const $el = renderComponent(Frames, "todomvc"); - expect($el.innerText).to.equal("Not Paused"); - }); - - it("Event Handler", function() { - if (typeof window != "object") { - return; - } - - const $el = renderComponent(Frames, "todomvcUpdateOnEnter"); - const frames = getFrames($el); - expect(frames.length).to.equal(13); - expect(getFrameTitle(frames[0])).to.equal("app.TodoView<.updateOnEnter"); - expect(getFrameLocation(frames[0])).to.equal("todo-view.js: 113"); - expect(getFrameTitle(frames[3])).to.equal(".save"); - // lastChild is the firstChild, there is no empty div present - expect(getFrameLocation(frames[5])).to.equal("backbone.localStorage.js: 1"); - }); - - it("Nested Closure", function() { - if (typeof window != "object") { - return; - } - - const $el = renderComponent(Frames, "pythagorean"); - const frames = getFrames($el); - expect(frames.length).to.equal(3); - expect(getFrameTitle(frames[0])).to.equal("pythagorean"); - expect(getFrameLocation(frames[0])).to.equal("pythagorean.js: 11"); - }); -}); diff --git a/src/components/tests/Scopes.js b/src/components/tests/Scopes.js deleted file mode 100644 index 2c124cb873..0000000000 --- a/src/components/tests/Scopes.js +++ /dev/null @@ -1,28 +0,0 @@ -const Scopes = require("../Scopes"); -const { renderComponent } = require("../test-utils"); - -function getScopes($el) { - return $el.querySelectorAll(".tree-node"); -} - -describe("Scopes", function() { - it("Not Paused", function() { - if (typeof window != "object") { - return; - } - - const $el = renderComponent(Scopes, "todomvc"); - expect($el.innerText).to.equal("Scopes Unavailable"); - }); - - it("TodoMVC Event Handler", function() { - if (typeof window != "object") { - return; - } - - const $el = renderComponent(Scopes, "todomvcUpdateOnEnter"); - const scopes = getScopes($el); - expect(scopes.length).to.equal(2); - expect(scopes[0].innerText.trim()).to.match(/app.TodoView<.updateOnEnter/); - }); -}); diff --git a/src/components/tests/SourceTabs.js b/src/components/tests/SourceTabs.js deleted file mode 100644 index c2db705350..0000000000 --- a/src/components/tests/SourceTabs.js +++ /dev/null @@ -1,37 +0,0 @@ -const SourceTabs = require("../SourceTabs"); -const { renderComponent } = require("../test-utils"); -const { setConfig } = require("devtools-config"); - -function getSourceTabs($el) { - return $el.querySelectorAll(".source-tab"); -} - -function getTitle($el) { - return $el.querySelector(".filename").innerText; -} - -describe("SourceTabs", function() { - it("Many Tabs", function() { - if (typeof window != "object") { - return; - } - - const $el = renderComponent(SourceTabs, "todomvc"); - const tabs = getSourceTabs($el); - expect(tabs.length).to.equal(3); - expect(getTitle(tabs[0])).to.equal("todo-view.js"); - }); - - it("Disabled", function() { - if (typeof window != "object") { - return; - } - - const prevConfig = setConfig({ features: { tabs: false }}); - const $el = renderComponent(SourceTabs, "todomvc"); - setConfig(prevConfig); - - const tabs = getSourceTabs($el); - expect(tabs.length).to.equal(0); - }); -}); diff --git a/src/components/utils/ManagedTree.css b/src/components/utils/ManagedTree.css deleted file mode 100644 index 0ed4110959..0000000000 --- a/src/components/utils/ManagedTree.css +++ /dev/null @@ -1,41 +0,0 @@ -.tree { - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - -o-user-select: none; - user-select: none; - - flex: 1; - white-space: nowrap; - overflow: auto; -} - -.tree button { - display: block; -} - -.tree .node { - padding: 2px 5px; - position: relative; -} - -.tree .node.focused { - color: white; - background-color: var(--theme-selection-background); -} - -html:not([dir="rtl"]) .tree .node > div { - margin-left: 10px; -} - -html[dir="rtl"] .tree .node > div { - margin-right: 10px; -} - -.tree .node.focused svg { - fill: white; -} - -.tree-node button { - position: fixed; -} diff --git a/src/components/utils/ManagedTree.js b/src/components/utils/ManagedTree.js deleted file mode 100644 index 289dc2bf1b..0000000000 --- a/src/components/utils/ManagedTree.js +++ /dev/null @@ -1,64 +0,0 @@ -const React = require("react"); -const Tree = React.createFactory(require("devtools-sham-modules").Tree); -require("./ManagedTree.css"); - -let ManagedTree = React.createClass({ - propTypes: Tree.propTypes, - - displayName: "ManagedTree", - - getInitialState() { - return { expanded: new Set(), - focusedItem: null }; - }, - - setExpanded(item, isExpanded) { - const expanded = this.state.expanded; - const key = this.props.getKey(item); - if (isExpanded) { - expanded.add(key); - } else { - expanded.delete(key); - } - this.setState({ expanded }); - - if (isExpanded && this.props.onExpand) { - this.props.onExpand(item); - } else if (!expanded && this.props.onCollapse) { - this.props.onCollapse(item); - } - }, - - focusItem(item) { - if (!this.props.disabledFocus && this.state.focusedItem !== item) { - this.setState({ focusedItem: item }); - - if (this.props.onFocus) { - this.props.onFocus(item); - } - } - }, - - render() { - const { expanded, focusedItem } = this.state; - - const props = Object.assign({}, this.props, { - isExpanded: item => expanded.has(this.props.getKey(item)), - focused: focusedItem, - - onExpand: item => this.setExpanded(item, true), - onCollapse: item => this.setExpanded(item, false), - onFocus: this.focusItem, - - renderItem: (...args) => { - return this.props.renderItem(...args, { - setExpanded: this.setExpanded - }); - } - }); - - return Tree(props); - } -}); - -module.exports = ManagedTree; diff --git a/src/components/utils/Svg.js b/src/components/utils/Svg.js deleted file mode 100644 index 1293cb3aec..0000000000 --- a/src/components/utils/Svg.js +++ /dev/null @@ -1,5 +0,0 @@ -/** - * This file maps the SVG React Components in the assets/images directory. - */ -const Svg = require("../../../assets/images/Svg"); -module.exports = Svg; diff --git a/src/constants.js b/src/constants.js deleted file mode 100644 index 2b4e1daa41..0000000000 --- a/src/constants.js +++ /dev/null @@ -1,47 +0,0 @@ -// @flow - -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -exports.UPDATE_EVENT_BREAKPOINTS = "UPDATE_EVENT_BREAKPOINTS"; -exports.FETCH_EVENT_LISTENERS = "FETCH_EVENT_LISTENERS"; - -exports.TOGGLE_PRETTY_PRINT = "TOGGLE_PRETTY_PRINT"; -exports.BLACKBOX = "BLACKBOX"; - -exports.ADD_BREAKPOINT = "ADD_BREAKPOINT"; -exports.REMOVE_BREAKPOINT = "REMOVE_BREAKPOINT"; -exports.ENABLE_BREAKPOINT = "ENABLE_BREAKPOINT"; -exports.DISABLE_BREAKPOINT = "DISABLE_BREAKPOINT"; -exports.SET_BREAKPOINT_CONDITION = "SET_BREAKPOINT_CONDITION"; -exports.TOGGLE_BREAKPOINTS = "TOGGLE_BREAKPOINTS"; - -exports.ADD_SOURCE = "ADD_SOURCE"; -exports.ADD_SOURCES = "ADD_SOURCES"; -exports.LOAD_SOURCE_TEXT = "LOAD_SOURCE_TEXT"; -exports.SELECT_SOURCE = "SELECT_SOURCE"; -exports.SELECT_SOURCE_URL = "SELECT_SOURCE_URL"; -exports.CLOSE_TAB = "CLOSE_TAB"; -exports.CLOSE_TABS = "CLOSE_TABS"; -exports.NAVIGATE = "NAVIGATE"; -exports.RELOAD = "RELOAD"; - -exports.ADD_TABS = "ADD_TABS"; -exports.SELECT_TAB = "SELECT_TAB"; - -exports.BREAK_ON_NEXT = "BREAK_ON_NEXT"; -exports.RESUME = "RESUME"; -exports.PAUSED = "PAUSED"; -exports.PAUSE_ON_EXCEPTIONS = "PAUSE_ON_EXCEPTIONS"; -exports.COMMAND = "COMMAND"; -exports.SELECT_FRAME = "SELECT_FRAME"; -exports.LOAD_OBJECT_PROPERTIES = "LOAD_OBJECT_PROPERTIES"; -exports.ADD_EXPRESSION = "ADD_EXPRESSION"; -exports.EVALUATE_EXPRESSION = "EVALUATE_EXPRESSION"; -exports.UPDATE_EXPRESSION = "UPDATE_EXPRESSION"; -exports.DELETE_EXPRESSION = "DELETE_EXPRESSION"; - -exports.TOGGLE_FILE_SEARCH = "TOGGLE_FILE_SEARCH"; diff --git a/src/feature.js b/src/feature.js deleted file mode 100644 index 21a1ca105a..0000000000 --- a/src/feature.js +++ /dev/null @@ -1,7 +0,0 @@ -/** - * This module maps to the config/feature.js to enable - * feature checking within the context of the debugger - */ -const { feature } = require("devtools-config"); - -module.exports = feature; diff --git a/src/global-types.js b/src/global-types.js deleted file mode 100644 index 9d4ee2e3a6..0000000000 --- a/src/global-types.js +++ /dev/null @@ -1 +0,0 @@ -declare var L10N: any; diff --git a/src/lib/codemirror-mozilla.css b/src/lib/codemirror-mozilla.css deleted file mode 100644 index 303ff40b3a..0000000000 --- a/src/lib/codemirror-mozilla.css +++ /dev/null @@ -1,271 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -:root { - /* --breakpoint-background: url("chrome://devtools/skin/images/breakpoint.svg#light"); */ - /* --breakpoint-hover-background: url("chrome://devtools/skin/images/breakpoint.svg#light-hover"); */ - --breakpoint-active-color: rgba(44,187,15,.2); - --breakpoint-active-color-hover: rgba(44,187,15,.5); - /* --breakpoint-conditional-background: url("chrome://devtools/skin/images/breakpoint.svg#light-conditional"); */ -} - -.theme-dark:root { - /* --breakpoint-background: url("chrome://devtools/skin/images/breakpoint.svg#dark"); */ - /* --breakpoint-hover-background: url("chrome://devtools/skin/images/breakpoint.svg#dark-hover"); */ - --breakpoint-active-color: rgba(0,255,175,.4); - --breakpoint-active-color-hover: rgba(0,255,175,.7); - /* --breakpoint-conditional-background: url("chrome://devtools/skin/images/breakpoint.svg#dark-conditional"); */ -} - -.CodeMirror .errors { - width: 16px; -} - -.CodeMirror .error { - display: inline-block; - margin-left: 5px; - width: 12px; - height: 12px; - background-repeat: no-repeat; - background-position: center; - background-size: contain; - /* background-image: url("chrome://devtools/skin/images/editor-error.png"); */ - opacity: 0.75; -} - -.CodeMirror .hit-counts { - width: 6px; -} - -.CodeMirror .hit-count { - display: inline-block; - height: 12px; - border: solid rgba(0,0,0,0.2); - border-width: 1px 1px 1px 0; - border-radius: 0 3px 3px 0; - padding: 0 3px; - font-size: 10px; - pointer-events: none; -} - -.CodeMirror-linenumber:before { - content: " "; - display: block; - width: calc(100% - 3px); - position: absolute; - top: 1px; - left: 0; - height: 12px; - z-index: -1; - background-size: calc(100% - 2px) 12px; - background-repeat: no-repeat; - background-position: right center; - padding-inline-end: 9px; -} - -.breakpoint .CodeMirror-linenumber { - color: var(--theme-body-background); -} - -.breakpoint .CodeMirror-linenumber:before { - background-image: var(--breakpoint-background) !important; -} - -.conditional .CodeMirror-linenumber:before { - background-image: var(--breakpoint-conditional-background) !important; -} - -.debug-line .CodeMirror-linenumber { - background-color: var(--breakpoint-active-color); -} - -.theme-dark .debug-line .CodeMirror-linenumber { - color: #c0c0c0; -} - -.debug-line .CodeMirror-line { - background-color: var(--breakpoint-active-color) !important; -} - -/* Don't display the highlight color since the debug line - is already highlighted */ -.debug-line .CodeMirror-activeline-background { - display: none; -} - -.CodeMirror { - cursor: text; -} - -.CodeMirror-gutters { - cursor: default; -} - -/* This is to avoid the fake horizontal scrollbar div of codemirror to go 0 -height when floating scrollbars are active. Make sure that this value is equal -to the maximum of `min-height` specific to the `scrollbar[orient="horizontal"]` -selector in floating-scrollbar-light.css across all platforms. */ -.CodeMirror-hscrollbar { - min-height: 10px; -} - -/* This is to avoid the fake vertical scrollbar div of codemirror to go 0 -width when floating scrollbars are active. Make sure that this value is equal -to the maximum of `min-width` specific to the `scrollbar[orient="vertical"]` -selector in floating-scrollbar-light.css across all platforms. */ -.CodeMirror-vscrollbar { - min-width: 10px; -} - -.cm-trailingspace { - background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAACCAYAAAB/qH1jAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QUXCToH00Y1UgAAACFJREFUCNdjPMDBUc/AwNDAAAFMTAwMDA0OP34wQgX/AQBYgwYEx4f9lQAAAABJRU5ErkJggg=="); - opacity: 0.75; - background-position: left bottom; - background-repeat: repeat-x; -} - -.cm-selecting { - background: none; - outline-width: 1px; - outline-style: solid; - outline-color: var(--theme-comment-alt); -} - -/* CodeMirror dialogs styling */ - -.CodeMirror-dialog { - padding: 4px 3px; -} - -.CodeMirror-dialog, -.CodeMirror-dialog input { - font: message-box; -} - -/* Fold addon */ - -.CodeMirror-foldmarker { - color: blue; - text-shadow: #b9f 1px 1px 2px, #b9f -1px -1px 2px, #b9f 1px -1px 2px, #b9f -1px 1px 2px; - font-family: sans-serif; - line-height: .3; - cursor: pointer; -} - -.CodeMirror-foldgutter { - width: 16px; /* Same as breakpoints gutter above */ -} - -.CodeMirror-foldgutter-open, -.CodeMirror-foldgutter-folded { - color: #555; - cursor: pointer; -} - -.CodeMirror-foldgutter-open:after { - font-size: 120%; - content: "\25BE"; -} - -.CodeMirror-foldgutter-folded:after { - font-size: 120%; - content: "\25B8"; -} - -.CodeMirror-hints { - position: absolute; - z-index: 10; - overflow: hidden; - list-style: none; - margin: 0; - padding: 2px; - border-radius: 3px; - font-size: 90%; - max-height: 20em; - overflow-y: auto; -} - -.CodeMirror-hint { - margin: 0; - padding: 0 4px; - border-radius: 2px; - max-width: 19em; - overflow: hidden; - white-space: pre; - cursor: pointer; -} - -.CodeMirror-Tern-completion { - padding-inline-start: 22px; - position: relative; - line-height: 18px; -} - -.CodeMirror-Tern-completion:before { - position: absolute; - left: 2px; - bottom: 2px; - border-radius: 50%; - font-size: 12px; - font-weight: bold; - height: 15px; - width: 15px; - line-height: 16px; - text-align: center; - color: #ffffff; - box-sizing: border-box; -} - -.CodeMirror-Tern-completion-unknown:before { - content: "?"; -} - -.CodeMirror-Tern-completion-object:before { - content: "O"; -} - -.CodeMirror-Tern-completion-fn:before { - content: "F"; -} - -.CodeMirror-Tern-completion-array:before { - content: "A"; -} - -.CodeMirror-Tern-completion-number:before { - content: "N"; -} - -.CodeMirror-Tern-completion-string:before { - content: "S"; -} - -.CodeMirror-Tern-completion-bool:before { - content: "B"; -} - -.CodeMirror-Tern-completion-guess { - color: #999; -} - -.CodeMirror-Tern-tooltip { - border-radius: 3px; - padding: 2px 5px; - white-space: pre-wrap; - max-width: 40em; - position: absolute; - z-index: 10; -} - -.CodeMirror-Tern-hint-doc { - max-width: 25em; -} - -.CodeMirror-Tern-farg-current { - text-decoration: underline; -} - -.CodeMirror-Tern-fhint-guess { - opacity: .7; -} diff --git a/src/main.js b/src/main.js deleted file mode 100644 index 44cb9ec050..0000000000 --- a/src/main.js +++ /dev/null @@ -1,81 +0,0 @@ -// @flow - -const React = require("react"); -const { bindActionCreators, combineReducers } = require("redux"); -const ReactDOM = require("react-dom"); - -const { getClient, firefox } = require("devtools-client-adapters"); -const { renderRoot, bootstrap, L10N } = require("devtools-local-toolbox"); -const { getValue, isFirefoxPanel } = require("devtools-config"); - -const configureStore = require("./utils/create-store"); -const { onConnect, onFirefoxConnect } = require("./utils/client"); - -const reducers = require("./reducers"); -const selectors = require("./selectors"); - -const App = require("./components/App"); - -const createStore = configureStore({ - log: getValue("logging.actions"), - makeThunkArgs: (args, state) => { - return Object.assign({}, args, { client: getClient(state) }); - } -}); - -const store = createStore(combineReducers(reducers)); -const actions = bindActionCreators(require("./actions"), store.dispatch); - -if (!isFirefoxPanel()) { - window.L10N = L10N; - window.L10N.setBundle(require("./strings.json")); -} - -window.appStore = store; - -// Expose the bound actions so external things can do things like -// selecting a source. -window.actions = { - selectSource: actions.selectSource, - selectSourceURL: actions.selectSourceURL -}; - -function unmountRoot() { - const mount = document.querySelector("#mount"); - ReactDOM.unmountComponentAtNode(mount); -} - -if (isFirefoxPanel()) { - const sourceMap = require("./utils/source-map"); - const prettyPrint = require("./utils/pretty-print"); - - module.exports = { - bootstrap: ({ threadClient, tabTarget, toolbox, L10N }: any) => { - // TODO (jlast) remove when the panel has L10N - if (L10N) { - window.L10N = L10N; - } else { - window.L10N = require("../packages/devtools-local-toolbox/src/utils/L10N"); - window.L10N.setBundle(require("./strings.json")); - } - - firefox.setThreadClient(threadClient); - firefox.setTabTarget(tabTarget); - renderRoot(React, ReactDOM, App, store); - firefox.initPage(actions); - onFirefoxConnect(actions, firefox); - }, - destroy: () => { - unmountRoot(); - sourceMap.destroyWorker(); - prettyPrint.destroyWorker(); - }, - store: store, - actions: actions, - selectors: selectors, - client: firefox.clientCommands - }; -} else { - bootstrap(React, ReactDOM, App, actions, store) - .then(conn => onConnect(conn, actions)); -} diff --git a/src/panel.js b/src/panel.js deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/reducers/async-requests.js b/src/reducers/async-requests.js deleted file mode 100644 index 337976562c..0000000000 --- a/src/reducers/async-requests.js +++ /dev/null @@ -1,27 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -const constants = require("../constants"); -const initialState = []; - -function update(state = initialState, action) { - const { seqId } = action; - - if (action.type === constants.NAVIGATE) { - return initialState; - } else if (seqId) { - let newState; - if (action.status === "start") { - newState = [...state, seqId]; - } else if (action.status === "error" || action.status === "done") { - newState = state.filter(id => id !== seqId); - } - - return newState; - } - - return state; -} - -module.exports = update; diff --git a/src/reducers/breakpoints.js b/src/reducers/breakpoints.js deleted file mode 100644 index bff371edb3..0000000000 --- a/src/reducers/breakpoints.js +++ /dev/null @@ -1,188 +0,0 @@ -// @flow -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/** - * Breakpoints reducer - * @module reducers/breakpoints - */ - -const fromJS = require("../utils/fromJS"); -const { updateObj } = require("../utils/utils"); -const I = require("immutable"); -const makeRecord = require("../utils/makeRecord"); - -import type { Breakpoint, Location } from "../types"; -import type { Action } from "../actions/types"; -import type { Record } from "../utils/makeRecord"; - -export type BreakpointsState = { - breakpoints: I.Map, - breakpointsDisabled: false -} - -const State = makeRecord(({ - breakpoints: I.Map(), - breakpointsDisabled: false -} : BreakpointsState)); - -// Return the first argument that is a string, or null if nothing is a -// string. -function firstString(...args) { - for (let arg of args) { - if (typeof arg === "string") { - return arg; - } - } - return null; -} - -function locationMoved(location, newLocation) { - return location.line !== newLocation.line || - (location.column != null && - location.column !== newLocation.column); -} - -function makeLocationId(location: Location) { - return `${location.sourceId}:${location.line.toString()}`; -} - -function update(state = State(), action: Action) { - switch (action.type) { - case "ADD_BREAKPOINT": { - const id = makeLocationId(action.breakpoint.location); - - if (action.status === "start") { - let bp = state.breakpoints.get(id) || action.breakpoint; - - return state.setIn(["breakpoints", id], updateObj(bp, { - disabled: false, - loading: true, - // We want to do an OR here, but we can't because we need - // empty strings to be truthy, i.e. an empty string is a valid - // condition. - condition: firstString(action.condition, bp.condition) - })); - } else if (action.status === "done") { - const { id: breakpointId, text } = action.value; - let location = action.breakpoint.location; - let { actualLocation } = action.value; - - // If the breakpoint moved, update the map - if (locationMoved(location, actualLocation)) { - state = state.deleteIn(["breakpoints", id]); - - const movedId = makeLocationId(actualLocation); - const currentBp = (state.breakpoints.get(movedId) || - fromJS(action.breakpoint)); - const newBp = updateObj(currentBp, { location: actualLocation }); - state = state.setIn(["breakpoints", movedId], newBp); - location = actualLocation; - } - - const locationId = makeLocationId(location); - const bp = state.breakpoints.get(locationId); - return state.setIn(["breakpoints", locationId], updateObj(bp, { - id: breakpointId, - disabled: false, - loading: false, - text: text - })); - } else if (action.status === "error") { - // Remove the optimistic update - return state.deleteIn(["breakpoints", id]); - } - break; - } - - case "REMOVE_BREAKPOINT": { - if (action.status === "done") { - const id = makeLocationId(action.breakpoint.location); - - if (action.disabled) { - const bp = state.breakpoints.get(id); - return state.setIn(["breakpoints", id], updateObj(bp, { - loading: false, disabled: true - })); - } - - return state.deleteIn(["breakpoints", id]); - } - break; - } - - case "TOGGLE_BREAKPOINTS": { - if (action.status === "start") { - return state.set( - "breakpointsDisabled", action.shouldDisableBreakpoints); - } - break; - } - - case "SET_BREAKPOINT_CONDITION": { - const id = makeLocationId(action.breakpoint.location); - - if (action.status === "start") { - const bp = state.breakpoints.get(id); - return state.setIn(["breakpoints", id], updateObj(bp, { - loading: true, - condition: action.condition - })); - } else if (action.status === "done") { - const bp = state.breakpoints.get(id); - return state.setIn(["breakpoints", id], updateObj(bp, { - id: action.value.id, - loading: false - })); - } else if (action.status === "error") { - return state.deleteIn(["breakpoints", id]); - } - - break; - }} - - return state; -} - -// Selectors - -type OuterState = { breakpoints: Record }; - -function getBreakpoint(state: OuterState, location: Location) { - return state.breakpoints.breakpoints.get(makeLocationId(location)); -} - -function getBreakpoints(state: OuterState) { - return state.breakpoints.breakpoints; -} - -function getBreakpointsForSource(state: OuterState, sourceId: string) { - return state.breakpoints.breakpoints.filter(bp => { - return bp.location.sourceId === sourceId; - }); -} - -function getBreakpointsDisabled(state: OuterState): boolean { - return state.breakpoints.get("breakpointsDisabled"); -} - -function getBreakpointsLoading(state: OuterState) { - const breakpoints = getBreakpoints(state); - const isLoading = !!breakpoints.valueSeq() - .filter(bp => bp.loading) - .first(); - - return breakpoints.size > 0 && isLoading; -} - -module.exports = { - State, - update, - makeLocationId, - getBreakpoint, - getBreakpoints, - getBreakpointsForSource, - getBreakpointsDisabled, - getBreakpointsLoading -}; diff --git a/src/reducers/event-listeners.js b/src/reducers/event-listeners.js deleted file mode 100644 index c9f06e3cda..0000000000 --- a/src/reducers/event-listeners.js +++ /dev/null @@ -1,35 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -const constants = require("../constants"); - -const initialState = { - activeEventNames: [], - listeners: [], - fetchingListeners: false, -}; - -function update(state = initialState, action, emit) { - switch (action.type) { - case constants.UPDATE_EVENT_BREAKPOINTS: - state.activeEventNames = action.eventNames; - emit("activeEventNames", state.activeEventNames); - break; - case constants.FETCH_EVENT_LISTENERS: - if (action.status === "begin") { - state.fetchingListeners = true; - } else if (action.status === "done") { - state.fetchingListeners = false; - state.listeners = action.listeners; - emit("event-listeners", state.listeners); - } - break; - case constants.NAVIGATE: - return initialState; - } - - return state; -} - -module.exports = update; diff --git a/src/reducers/index.js b/src/reducers/index.js deleted file mode 100644 index 69103a8851..0000000000 --- a/src/reducers/index.js +++ /dev/null @@ -1,19 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -const eventListeners = require("./event-listeners"); -const sources = require("./sources"); -const breakpoints = require("./breakpoints"); -const asyncRequests = require("./async-requests"); -const pause = require("./pause"); -const ui = require("./ui"); - -module.exports = { - eventListeners, - sources: sources.update, - breakpoints: breakpoints.update, - pause: pause.update, - asyncRequests, - ui: ui.update -}; diff --git a/src/reducers/pause.js b/src/reducers/pause.js deleted file mode 100644 index ba19302100..0000000000 --- a/src/reducers/pause.js +++ /dev/null @@ -1,183 +0,0 @@ -// @flow -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -const constants = require("../constants"); -const fromJS = require("../utils/fromJS"); -const makeRecord = require("../utils/makeRecord"); -const I = require("immutable"); - -import type { Frame, Pause, Expression } from "../types"; -import type { Action } from "../actions/types"; -import type { Record } from "../utils/makeRecord"; - -type PauseState = { - pause: ?Pause, - isWaitingOnBreak: boolean, - frames: ?Frame[], - selectedFrameId: ?string, - loadedObjects: Object, - shouldPauseOnExceptions: boolean, - shouldIgnoreCaughtExceptions: boolean, - expressions: I.List -} - -const State = makeRecord(({ - pause: undefined, - isWaitingOnBreak: false, - frames: undefined, - selectedFrameId: undefined, - loadedObjects: I.Map(), - shouldPauseOnExceptions: false, - shouldIgnoreCaughtExceptions: false, - expressions: I.List() -} : PauseState)); - -function update(state = State(), action: Action): Record { - switch (action.type) { - case constants.PAUSED: { - const { selectedFrameId, frames, pauseInfo } = action; - pauseInfo.isInterrupted = pauseInfo.why.type === "interrupted"; - - return state.merge({ - isWaitingOnBreak: false, - pause: fromJS(pauseInfo), - selectedFrameId, - frames - }); - } - - case constants.RESUME: - return state.merge({ - pause: null, - frames: null, - selectedFrameId: null, - loadedObjects: {} - }); - - case constants.TOGGLE_PRETTY_PRINT: - if (action.status == "done") { - const frames = action.value.frames; - let pause = state.get("pause"); - if (pause) { - pause = pause.set("frame", fromJS(frames[0])); - } - - return state.merge({ pause, frames }); - } - - break; - case constants.BREAK_ON_NEXT: - return state.set("isWaitingOnBreak", true); - - case constants.SELECT_FRAME: - return state.set("selectedFrameId", action.frame.id); - - case constants.LOAD_OBJECT_PROPERTIES: - if (action.status === "done") { - const ownProperties = action.value.ownProperties; - const prototype = action.value.prototype; - - return state.setIn(["loadedObjects", action.objectId], - { ownProperties, prototype }); - } - break; - - case constants.NAVIGATE: - return State(); - - case constants.PAUSE_ON_EXCEPTIONS: - const { shouldPauseOnExceptions, shouldIgnoreCaughtExceptions } = action; - return state.merge({ - shouldPauseOnExceptions, - shouldIgnoreCaughtExceptions - }); - - case constants.ADD_EXPRESSION: - return state.setIn(["expressions", action.id], - { id: action.id, - input: action.input, - value: action.value, - updating: false }); - - case constants.EVALUATE_EXPRESSION: - if (action.status === "done") { - return state.mergeIn(["expressions", action.id], - { id: action.id, - input: action.input, - value: action.value, - updating: false }); - } - break; - - case constants.UPDATE_EXPRESSION: - return state.mergeIn(["expressions", action.id], - { id: action.id, - input: action.input, - updating: true }); - - case constants.DELETE_EXPRESSION: - return state.deleteIn(["expressions", action.id]); - } - - return state; -} - -// Selectors - -// Unfortunately, it's really hard to make these functions accept just -// the state that we care about and still type it with Flow. The -// problem is that we want to re-export all selectors from a single -// module for the UI, and all of those selectors should take the -// top-level app state, so we'd have to "wrap" them to automatically -// pick off the piece of state we're interested in. It's impossible -// (right now) to type those wrapped functions. -type OuterState = { pause: Record }; - -function getPause(state: OuterState) { - return state.pause.get("pause"); -} - -function getLoadedObjects(state: OuterState) { - return state.pause.get("loadedObjects"); -} - -function getExpressions(state: OuterState) { - return state.pause.get("expressions"); -} - -function getIsWaitingOnBreak(state: OuterState) { - return state.pause.get("isWaitingOnBreak"); -} - -function getShouldPauseOnExceptions(state: OuterState) { - return state.pause.get("shouldPauseOnExceptions"); -} - -function getShouldIgnoreCaughtExceptions(state: OuterState) { - return state.pause.get("shouldIgnoreCaughtExceptions"); -} - -function getFrames(state: OuterState) { - return state.pause.get("frames"); -} - -function getSelectedFrame(state: OuterState) { - const selectedFrameId = state.pause.get("selectedFrameId"); - const frames = state.pause.get("frames"); - return frames && frames.find(frame => frame.id == selectedFrameId); -} - -module.exports = { - State, - update, - getPause, - getLoadedObjects, - getExpressions, - getIsWaitingOnBreak, - getShouldPauseOnExceptions, - getShouldIgnoreCaughtExceptions, - getFrames, - getSelectedFrame -}; diff --git a/src/reducers/sources.js b/src/reducers/sources.js deleted file mode 100644 index af650a043f..0000000000 --- a/src/reducers/sources.js +++ /dev/null @@ -1,271 +0,0 @@ -// @flow -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/** - * Sources reducer - * @module reducers/sources - */ - -const fromJS = require("../utils/fromJS"); -const I = require("immutable"); -const makeRecord = require("../utils/makeRecord"); -const { getPrettySourceURL } = require("../utils/source"); - -import type { Source, Location } from "../types"; -import type { Action } from "../actions/types"; -import type { Record } from "../utils/makeRecord"; - -export type SourcesState = { - sources: I.Map, - selectedLocation?: { - sourceId: string, - line?: number, - column?: number - }, - pendingSelectedLocation?: { - url: string, - line?: number, - column?: number - }, - selectedLocation?: Location, - sourcesText: I.Map, - tabs: I.List -}; - -const State = makeRecord(({ - sources: I.Map(), - selectedLocation: undefined, - pendingSelectedLocation: undefined, - sourcesText: I.Map(), - tabs: I.List([]) -} : SourcesState)); - -function update(state = State(), action: Action) : Record { - let availableTabs = null; - - switch (action.type) { - case "ADD_SOURCE": { - const source: Source = action.source; - return state.mergeIn(["sources", action.source.id], source); - } - - case "SELECT_SOURCE": - return state - .set("selectedLocation", { - sourceId: action.source.id, - line: action.line - }) - .set("pendingSelectedLocation", null) - .merge({ - tabs: updateTabList(state, fromJS(action.source), action.tabIndex) - }); - - case "SELECT_SOURCE_URL": - return state.set("pendingSelectedLocation", { - url: action.url, - line: action.line - }); - - case "CLOSE_TAB": - availableTabs = removeSourceFromTabList(state.tabs, action.id); - return state.merge({ tabs: availableTabs }) - .set("selectedLocation", { - sourceId: getNewSelectedSourceId(state, availableTabs) - }); - - case "CLOSE_TABS": - availableTabs = removeSourcesFromTabList(state.tabs, action.ids); - return state.merge({ tabs: availableTabs }) - .set("selectedLocation", { - sourceId: getNewSelectedSourceId(state, availableTabs) - }); - - case "LOAD_SOURCE_TEXT": - return _updateText(state, action); - - case "BLACKBOX": - if (action.status === "done") { - return state.setIn( - ["sources", action.source.id, "isBlackBoxed"], - action.value.isBlackBoxed - ); - } - break; - - case "TOGGLE_PRETTY_PRINT": - return _updateText(state, action); - - case "NAVIGATE": - const source = getSelectedSource({ sources: state }); - const url = source && source.get("url"); - return State() - .set("pendingSelectedLocation", { url }); - } - - return state; -} - -// TODO: Action is coerced to `any` unfortunately because how we type -// asynchronous actions is wrong. The `value` may be null for the -// "start" and "error" states but we don't type it like that. We need -// to rethink how we type async actions. -function _updateText(state, action : any) : Record { - const source = action.source; - const sourceText = action.value; - - if (action.status === "start") { - // Merge this in, don't set it. That way the previous value is - // still stored here, and we can retrieve it if whatever we're - // doing fails. - return state.mergeIn(["sourcesText", source.id], { - loading: true - }); - } - - if (action.status === "error") { - return state.setIn(["sourcesText", source.id], I.Map({ - error: action.error - })); - } - - return state.setIn(["sourcesText", source.id], I.Map({ - text: sourceText.text, - contentType: sourceText.contentType - })); -} - -function removeSourceFromTabList(tabs, id) { - return tabs.filter(tab => tab.get("id") != id); -} - -function removeSourcesFromTabList(tabs, ids) { - return ids.reduce((t, id) => removeSourceFromTabList(t, id), tabs); -} - -/** - * Adds the new source to the tab list if it is not already there - * @memberof reducers/sources - * @static - */ -function updateTabList(state, source, tabIndex) { - const tabs = state.get("tabs"); - const sourceIndex = tabs.indexOf(source); - const includesSource = !!tabs.find((t) => t.get("id") == source.get("id")); - - if (includesSource) { - if (tabIndex != undefined) { - return tabs - .delete(sourceIndex) - .insert(tabIndex, source); - } - - return tabs; - } - - return tabs.insert(0, source); -} - -/** - * Gets the next tab to select when a tab closes. Heuristics: - * 1. if the selected tab is available, it remains selected - * 2. if it is gone, the next available tab to the left should be active - * 3. if the first tab is active and closed, select the second tab - * - * @memberof reducers/sources - * @static - */ -function getNewSelectedSourceId(state: SourcesState, availableTabs) : string { - if (!state.selectedLocation) { - return ""; - } - - const selectedTabId = state.selectedLocation.sourceId; - const availableTabIds = availableTabs.map(s => s.get("id")).toJS(); - const tabIds = state.tabs.map(s => s.get("id")).toJS(); - - if (availableTabIds.includes(selectedTabId)) { - return selectedTabId; - } - - const leftNeighborIndex = Math.max(tabIds.indexOf(selectedTabId) - 1, 0); - const lastAvailbleTabIndex = availableTabIds.length - 1; - const newSelectedTabIndex = Math.min(leftNeighborIndex, lastAvailbleTabIndex); - - return availableTabIds[newSelectedTabIndex]; -} - -// Selectors - -// Unfortunately, it's really hard to make these functions accept just -// the state that we care about and still type it with Flow. The -// problem is that we want to re-export all selectors from a single -// module for the UI, and all of those selectors should take the -// top-level app state, so we'd have to "wrap" them to automatically -// pick off the piece of state we're interested in. It's impossible -// (right now) to type those wrapped functions. -type OuterState = { sources: Record }; - -function getSource(state: OuterState, id: string) { - return state.sources.sources.get(id); -} - -function getSourceByURL(state: OuterState, url: string) { - return state.sources.sources.find(source => source.get("url") == url); -} - -function getSourceById(state: OuterState, id: string) { - return state.sources.sources.find(source => source.get("id") == id); -} - -function getSources(state: OuterState) { - return state.sources.sources; -} - -function getSourceText(state: OuterState, id: string) { - return state.sources.sourcesText.get(id); -} - -function getSourceTabs(state: OuterState) { - return state.sources.tabs; -} - -function getSelectedSource(state: OuterState) { - if (state.sources.selectedLocation) { - return getSource(state, state.sources.selectedLocation.sourceId); - } - return undefined; -} - -function getSelectedLocation(state: OuterState) { - return state.sources.selectedLocation; -} - -function getPendingSelectedLocation(state: OuterState) { - return state.sources.pendingSelectedLocation; -} - -function getPrettySource(state: OuterState, id: string) { - const source = getSource(state, id); - if (!source) { - return; - } - - return getSourceByURL(state, getPrettySourceURL(source.get("url"))); -} - -module.exports = { - State, - update, - getSource, - getSourceByURL, - getSourceById, - getSources, - getSourceText, - getSourceTabs, - getSelectedSource, - getSelectedLocation, - getPendingSelectedLocation, - getPrettySource -}; diff --git a/src/reducers/tests/sources.js b/src/reducers/tests/sources.js deleted file mode 100644 index dc5757653a..0000000000 --- a/src/reducers/tests/sources.js +++ /dev/null @@ -1,19 +0,0 @@ -// @flow -declare var describe: (name: string, func: () => void) => void; -declare var it: (desc: string, func: () => void) => void; - -const { State, update } = require("../sources"); -const fixtures = require("../../test/fixtures/foobar.json"); -const fakeSources = fixtures.sources.sources; -const expect = require("expect.js"); - -describe("sources reducer", () => { - it("should work", () => { - let state = State(); - state = update(state, { - type: "ADD_SOURCE", - source: fakeSources.fooSourceActor - }); - expect(state.sources.size).to.be(1); - }); -}); diff --git a/src/reducers/ui.js b/src/reducers/ui.js deleted file mode 100644 index 8999df9de6..0000000000 --- a/src/reducers/ui.js +++ /dev/null @@ -1,45 +0,0 @@ -// @flow - -/** - * UI reducer - * @module reducers/ui - */ - -const constants = require("../constants"); -const makeRecord = require("../utils/makeRecord"); - -import type { Action } from "../actions/types"; -import type { Record } from "../utils/makeRecord"; - -export type UIState = { - searchOn: boolean -}; - -const State = makeRecord(({ - searchOn: false -} : UIState)); - -function update(state = State(), action: Action): Record { - switch (action.type) { - case constants.TOGGLE_FILE_SEARCH: { - return state.set("searchOn", action.searchOn); - } - default: { - return state; - } - } -} - -// NOTE: we'd like to have the app state fully typed -// https://github.com/devtools-html/debugger.html/blob/master/src/reducers/sources.js#L179-L185 -type OuterState = { ui: Record }; - -function getFileSearchState(state: OuterState): boolean { - return state.ui.get("searchOn"); -} - -module.exports = { - State, - update, - getFileSearchState -}; diff --git a/src/selectors.js b/src/selectors.js deleted file mode 100644 index 277dbd54b9..0000000000 --- a/src/selectors.js +++ /dev/null @@ -1,40 +0,0 @@ -// @flow - -const sources = require("./reducers/sources"); -const pause = require("./reducers/pause"); -const breakpoints = require("./reducers/breakpoints"); -const ui = require("./reducers/ui"); - -/** - * @param object - location - */ - -module.exports = { - getSource: sources.getSource, - getSourceByURL: sources.getSourceByURL, - getSourceById: sources.getSourceById, - getSources: sources.getSources, - getSourceText: sources.getSourceText, - getSourceTabs: sources.getSourceTabs, - getSelectedSource: sources.getSelectedSource, - getSelectedLocation: sources.getSelectedLocation, - getPendingSelectedLocation: sources.getPendingSelectedLocation, - getPrettySource: sources.getPrettySource, - - getBreakpoint: breakpoints.getBreakpoint, - getBreakpoints: breakpoints.getBreakpoints, - getBreakpointsForSource: breakpoints.getBreakpointsForSource, - getBreakpointsDisabled: breakpoints.getBreakpointsDisabled, - getBreakpointsLoading: breakpoints.getBreakpointsLoading, - - getPause: pause.getPause, - getLoadedObjects: pause.getLoadedObjects, - getExpressions: pause.getExpressions, - getIsWaitingOnBreak: pause.getIsWaitingOnBreak, - getShouldPauseOnExceptions: pause.getShouldPauseOnExceptions, - getShouldIgnoreCaughtExceptions: pause.getShouldIgnoreCaughtExceptions, - getFrames: pause.getFrames, - getSelectedFrame: pause.getSelectedFrame, - - getFileSearchState: ui.getFileSearchState -}; diff --git a/src/strings.json b/src/strings.json deleted file mode 100644 index a77308c155..0000000000 --- a/src/strings.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "breakpoints.header": "Breakpoints", - "breakpoints.none": "No Breakpoints", - "callStack.header": "Call Stack", - "callStack.notPaused": "Not Paused", - "callStack.collapse": "Collapse Rows", - "callStack.expand": "Expand Rows", - "editor.searchResults": "%d of %d results", - "editor.noResults": "no results", - "editor.addBreakpoint": "Add Breakpoint", - "editor.disableBreakpoint": "Disable Breakpoint", - "editor.enableBreakpoint": "Enable Breakpoint", - "editor.removeBreakpoint": "Remove Breakpoint", - "editor.editBreakpoint": "Edit Breakpoint", - "editor.addConditionalBreakpoint": "Add Conditional Breakpoint", - "editor.conditionalPanel.placeholder": "This breakpoint will pause when the expression is true", - "expressions.placeholder": "Add Watch Expression", - "scopes.header": "Scopes", - "scopes.notAvailable": "Scopes Unavailable", - "scopes.block":"Block", - "scopes.notPaused": "Not Paused", - "sources.header": "Sources", - "sources.search": "%S to search", - "watchExpressions.header": "Watch Expressions", - "welcome.search": "%S to search for files", - "sourceSearch.search": "Search...", - "sourceSearch.resultsSummary": "%d instances of \"%S\"", - "sourceSearch.noResults": "No files matching %S found", - "sourceFooter.debugBtnTooltip": "Prettify Source", - "ignoreExceptions": "Ignore exceptions. Click to pause on uncaught exceptions", - "pauseOnUncaughtExceptions": "Pause on uncaught exceptions. Click to pause on all exceptions", - "pauseOnExceptions": "Pause on all exceptions. Click to ignore exceptions", - "stepOutTooltip": "Step Out (%SF11)", - "stepInTooltip": "Step In (%SF11)", - "stepOverTooltip": "Step Over (F10)", - "resumeButtonTooltip": "Click to resume (F8)", - "pausePendingButtonTooltip": "Waiting for next execution", - "pauseButtonTooltip": "Click to pause (F8)", - "sourceTabs.closeTab": "Close tab", - "sourceTabs.closeOtherTabs": "Close others", - "sourceTabs.closeTabsToRight": "Close tabs to the right", - "sourceTabs.closeAllTabs": "Close all tabs", - "loadingText": "Loading\u2026" -} diff --git a/src/tcomb-types.js b/src/tcomb-types.js deleted file mode 100644 index 4c0f91d86d..0000000000 --- a/src/tcomb-types.js +++ /dev/null @@ -1,19 +0,0 @@ -const t = require("tcomb"); - -const Location = t.struct({ - sourceId: t.String, - line: t.Number, - column: t.union([t.Number, t.Nil]) -}, "Location"); - -const Frame = t.struct({ - id: t.String, - displayName: t.String, - location: Location, - this: t.union([t.Object, t.Nil]), - scope: t.union([t.Object, t.Nil]) -}, "Frame"); - -module.exports = { - Frame -}; diff --git a/src/test/examples/debugger-statements.html b/src/test/examples/debugger-statements.html deleted file mode 100644 index 967619d31a..0000000000 --- a/src/test/examples/debugger-statements.html +++ /dev/null @@ -1,27 +0,0 @@ - - - Debugger Statements - - - - - - - diff --git a/src/test/examples/evals.html b/src/test/examples/evals.html deleted file mode 100644 index bc63008d30..0000000000 --- a/src/test/examples/evals.html +++ /dev/null @@ -1,27 +0,0 @@ - - - evals - - - - - - - - - - diff --git a/src/test/examples/exceptions.html b/src/test/examples/exceptions.html deleted file mode 100644 index add7571e00..0000000000 --- a/src/test/examples/exceptions.html +++ /dev/null @@ -1,38 +0,0 @@ - - - Debugger test page - - - - - - - diff --git a/src/test/examples/iframe.html b/src/test/examples/iframe.html deleted file mode 100644 index 8e1c8a2c01..0000000000 --- a/src/test/examples/iframe.html +++ /dev/null @@ -1,13 +0,0 @@ - - - Iframe - - - - - - - - diff --git a/src/test/examples/increment/build.js b/src/test/examples/increment/build.js deleted file mode 100644 index 41c29c9d16..0000000000 --- a/src/test/examples/increment/build.js +++ /dev/null @@ -1 +0,0 @@ -require("../build-common"); \ No newline at end of file diff --git a/src/test/examples/increment/bundle.js b/src/test/examples/increment/bundle.js deleted file mode 100644 index 7b9c296105..0000000000 --- a/src/test/examples/increment/bundle.js +++ /dev/null @@ -1,73 +0,0 @@ -/******/ (function(modules) { // webpackBootstrap -/******/ // The module cache -/******/ var installedModules = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ -/******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) -/******/ return installedModules[moduleId].exports; -/******/ -/******/ // Create a new module (and put it into the cache) -/******/ var module = installedModules[moduleId] = { -/******/ exports: {}, -/******/ id: moduleId, -/******/ loaded: false -/******/ }; -/******/ -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); -/******/ -/******/ // Flag the module as loaded -/******/ module.loaded = true; -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/******/ -/******/ // expose the modules object (__webpack_modules__) -/******/ __webpack_require__.m = modules; -/******/ -/******/ // expose the module cache -/******/ __webpack_require__.c = installedModules; -/******/ -/******/ // __webpack_public_path__ -/******/ __webpack_require__.p = ""; -/******/ -/******/ // Load entry module and return exports -/******/ return __webpack_require__(0); -/******/ }) -/************************************************************************/ -/******/ ([ -/* 0 */ -/***/ function(module, exports, __webpack_require__) { - - window.inc = __webpack_require__(1).increment; - - -/***/ }, -/* 1 */ -/***/ function(module, exports, __webpack_require__) { - - var add = __webpack_require__(2).add; - exports.increment = function(val) { - return add(val, 1); - }; - -/***/ }, -/* 2 */ -/***/ function(module, exports) { - - exports.add = function() { - var sum = 0, i = 0, args = arguments, l = args.length; - while (i < l) { - sum += args[i++]; - } - return sum; - }; - -/***/ } -/******/ ]); -//# sourceMappingURL=bundle.js.map \ No newline at end of file diff --git a/src/test/examples/increment/bundle.js.map b/src/test/examples/increment/bundle.js.map deleted file mode 100644 index 748e0be952..0000000000 --- a/src/test/examples/increment/bundle.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["webpack:///webpack/bootstrap 4f282b30eeca6ec69a5d","webpack:///./increment/example.js","webpack:///./increment/increment.js","webpack:///./increment/math.js"],"names":[],"mappings":";AAAA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,uBAAe;AACf;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;;;;;;ACtCA;;;;;;;ACAA;AACA;AACA;AACA,G;;;;;;ACHA;AACA;AACA;AACA;AACA;AACA;AACA,G","file":"bundle.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n/** WEBPACK FOOTER **\n ** webpack/bootstrap 4f282b30eeca6ec69a5d\n **/","window.inc = require('./increment').increment;\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./increment/example.js\n ** module id = 0\n ** module chunks = 0\n **/","var add = require('./math').add;\nexports.increment = function(val) {\n return add(val, 1);\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./increment/increment.js\n ** module id = 1\n ** module chunks = 0\n **/","exports.add = function() {\n var sum = 0, i = 0, args = arguments, l = args.length;\n while (i < l) {\n sum += args[i++];\n }\n return sum;\n};\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./increment/math.js\n ** module id = 2\n ** module chunks = 0\n **/"],"sourceRoot":""} \ No newline at end of file diff --git a/src/test/examples/increment/example.js b/src/test/examples/increment/example.js deleted file mode 100644 index 747eb93877..0000000000 --- a/src/test/examples/increment/example.js +++ /dev/null @@ -1 +0,0 @@ -window.inc = require('./increment').increment; diff --git a/src/test/examples/increment/increment.js b/src/test/examples/increment/increment.js deleted file mode 100644 index df19980e68..0000000000 --- a/src/test/examples/increment/increment.js +++ /dev/null @@ -1,4 +0,0 @@ -var add = require('./math').add; -exports.increment = function(val) { - return add(val, 1); -}; \ No newline at end of file diff --git a/src/test/examples/increment/index.html b/src/test/examples/increment/index.html deleted file mode 100644 index 6d003e6394..0000000000 --- a/src/test/examples/increment/index.html +++ /dev/null @@ -1,20 +0,0 @@ - - - increment - - - - - - - - -

yo

- - diff --git a/src/test/examples/increment/math.js b/src/test/examples/increment/math.js deleted file mode 100644 index 7c5979e95f..0000000000 --- a/src/test/examples/increment/math.js +++ /dev/null @@ -1,7 +0,0 @@ -exports.add = function() { - var sum = 0, i = 0, args = arguments, l = args.length; - while (i < l) { - sum += args[i++]; - } - return sum; -}; \ No newline at end of file diff --git a/src/test/examples/increment/webpack.config.js b/src/test/examples/increment/webpack.config.js deleted file mode 100644 index 44247a9a8e..0000000000 --- a/src/test/examples/increment/webpack.config.js +++ /dev/null @@ -1,10 +0,0 @@ -const path = require("path"); - -module.exports = { - entry: path.join(__dirname, "./example.js"), - devtool: "source-map", - output: { - path: path.join(__dirname), - filename: "bundle.js", - } -} diff --git a/src/test/examples/pythagorean/index.html b/src/test/examples/pythagorean/index.html deleted file mode 100644 index b8bf0443d3..0000000000 --- a/src/test/examples/pythagorean/index.html +++ /dev/null @@ -1,8 +0,0 @@ - - - Pythagorean - - - - - diff --git a/src/test/examples/pythagorean/pythagorean.js b/src/test/examples/pythagorean/pythagorean.js deleted file mode 100644 index 21bb2b4cab..0000000000 --- a/src/test/examples/pythagorean/pythagorean.js +++ /dev/null @@ -1,15 +0,0 @@ -"use strict"; - -function math(a, b) { - var bar = 4; - function pythagorean(a, b) { - var foo = 3; - function exponential(num) { - foo, bar; - return num * num; - } - return exponential(a) + exponential(b); - } - - pythagorean(a,b); -} diff --git a/src/test/examples/todomvc/bower.json b/src/test/examples/todomvc/bower.json deleted file mode 100644 index b5a67c516b..0000000000 --- a/src/test/examples/todomvc/bower.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "todomvc-backbone", - "version": "0.0.0", - "dependencies": { - "backbone": "~1.1.1", - "underscore": "~1.6.0", - "jquery": "~2.0.0", - "todomvc-common": "~0.3.0", - "backbone.localStorage": "~1.1.0" - } -} diff --git a/src/test/examples/todomvc/bower_components/backbone.localStorage/backbone.localStorage.js b/src/test/examples/todomvc/bower_components/backbone.localStorage/backbone.localStorage.js deleted file mode 100644 index 1957d15847..0000000000 --- a/src/test/examples/todomvc/bower_components/backbone.localStorage/backbone.localStorage.js +++ /dev/null @@ -1 +0,0 @@ -!function(e,t){"object"==typeof exports&&"function"==typeof require?module.exports=t(require("underscore"),require("backbone")):"function"==typeof define&&define.amd?define(["underscore","backbone"],function(r,o){return t(r||e._,o||e.Backbone)}):t(_,Backbone)}(this,function(e,t){function r(){return(65536*(1+Math.random())|0).toString(16).substring(1)}function o(){return r()+r()+"-"+r()+"-"+r()+"-"+r()+"-"+r()+r()+r()}return t.LocalStorage=window.Store=function(e){if(!this.localStorage)throw"Backbone.localStorage: Environment does not support localStorage.";this.name=e;var t=this.localStorage().getItem(this.name);this.records=t&&t.split(",")||[]},e.extend(t.LocalStorage.prototype,{save:function(){this.localStorage().setItem(this.name,this.records.join(","))},create:function(e){return e.id||(e.id=o(),e.set(e.idAttribute,e.id)),this.localStorage().setItem(this.name+"-"+e.id,JSON.stringify(e)),this.records.push(e.id.toString()),this.save(),this.find(e)},update:function(t){return this.localStorage().setItem(this.name+"-"+t.id,JSON.stringify(t)),e.include(this.records,t.id.toString())||this.records.push(t.id.toString()),this.save(),this.find(t)},find:function(e){return this.jsonData(this.localStorage().getItem(this.name+"-"+e.id))},findAll:function(){return(e.chain||e)(this.records).map(function(e){return this.jsonData(this.localStorage().getItem(this.name+"-"+e))},this).compact().value()},destroy:function(t){return t.isNew()?!1:(this.localStorage().removeItem(this.name+"-"+t.id),this.records=e.reject(this.records,function(e){return e===t.id.toString()}),this.save(),t)},localStorage:function(){return localStorage},jsonData:function(e){return e&&JSON.parse(e)},_clear:function(){var t=this.localStorage(),r=new RegExp("^"+this.name+"-");t.removeItem(this.name),(e.chain||e)(t).keys().filter(function(e){return r.test(e)}).each(function(e){t.removeItem(e)}),this.records.length=0},_storageSize:function(){return this.localStorage().length}}),t.LocalStorage.sync=window.Store.sync=t.localSync=function(e,r,o){var n,i,c=r.localStorage||r.collection.localStorage,a=t.$.Deferred&&t.$.Deferred();try{switch(e){case"read":n=void 0!=r.id?c.find(r):c.findAll();break;case"create":n=c.create(r);break;case"update":n=c.update(r);break;case"delete":n=c.destroy(r)}}catch(s){i=22===s.code&&0===c._storageSize()?"Private browsing is unsupported":s.message}return n?(o&&o.success&&("0.9.10"===t.VERSION?o.success(r,n,o):o.success(n)),a&&a.resolve(n)):(i=i?i:"Record Not Found",o&&o.error&&("0.9.10"===t.VERSION?o.error(r,i,o):o.error(i)),a&&a.reject(i)),o&&o.complete&&o.complete(n),a&&a.promise()},t.ajaxSync=t.sync,t.getSyncMethod=function(e){return e.localStorage||e.collection&&e.collection.localStorage?t.localSync:t.ajaxSync},t.sync=function(e,r,o){return t.getSyncMethod(r).apply(this,[e,r,o])},t.LocalStorage}); diff --git a/src/test/examples/todomvc/bower_components/backbone/backbone.js b/src/test/examples/todomvc/bower_components/backbone/backbone.js deleted file mode 100644 index 24a550a0ad..0000000000 --- a/src/test/examples/todomvc/bower_components/backbone/backbone.js +++ /dev/null @@ -1,1608 +0,0 @@ -// Backbone.js 1.1.2 - -// (c) 2010-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors -// Backbone may be freely distributed under the MIT license. -// For all details and documentation: -// http://backbonejs.org - -(function(root, factory) { - - // Set up Backbone appropriately for the environment. Start with AMD. - if (typeof define === 'function' && define.amd) { - define(['underscore', 'jquery', 'exports'], function(_, $, exports) { - // Export global even in AMD case in case this script is loaded with - // others that may still expect a global Backbone. - root.Backbone = factory(root, exports, _, $); - }); - - // Next for Node.js or CommonJS. jQuery may not be needed as a module. - } else if (typeof exports !== 'undefined') { - var _ = require('underscore'); - factory(root, exports, _); - - // Finally, as a browser global. - } else { - root.Backbone = factory(root, {}, root._, (root.jQuery || root.Zepto || root.ender || root.$)); - } - -}(this, function(root, Backbone, _, $) { - - // Initial Setup - // ------------- - - // Save the previous value of the `Backbone` variable, so that it can be - // restored later on, if `noConflict` is used. - var previousBackbone = root.Backbone; - - // Create local references to array methods we'll want to use later. - var array = []; - var push = array.push; - var slice = array.slice; - var splice = array.splice; - - // Current version of the library. Keep in sync with `package.json`. - Backbone.VERSION = '1.1.2'; - - // For Backbone's purposes, jQuery, Zepto, Ender, or My Library (kidding) owns - // the `$` variable. - Backbone.$ = $; - - // Runs Backbone.js in *noConflict* mode, returning the `Backbone` variable - // to its previous owner. Returns a reference to this Backbone object. - Backbone.noConflict = function() { - root.Backbone = previousBackbone; - return this; - }; - - // Turn on `emulateHTTP` to support legacy HTTP servers. Setting this option - // will fake `"PATCH"`, `"PUT"` and `"DELETE"` requests via the `_method` parameter and - // set a `X-Http-Method-Override` header. - Backbone.emulateHTTP = false; - - // Turn on `emulateJSON` to support legacy servers that can't deal with direct - // `application/json` requests ... will encode the body as - // `application/x-www-form-urlencoded` instead and will send the model in a - // form param named `model`. - Backbone.emulateJSON = false; - - // Backbone.Events - // --------------- - - // A module that can be mixed in to *any object* in order to provide it with - // custom events. You may bind with `on` or remove with `off` callback - // functions to an event; `trigger`-ing an event fires all callbacks in - // succession. - // - // var object = {}; - // _.extend(object, Backbone.Events); - // object.on('expand', function(){ alert('expanded'); }); - // object.trigger('expand'); - // - var Events = Backbone.Events = { - - // Bind an event to a `callback` function. Passing `"all"` will bind - // the callback to all events fired. - on: function(name, callback, context) { - if (!eventsApi(this, 'on', name, [callback, context]) || !callback) return this; - this._events || (this._events = {}); - var events = this._events[name] || (this._events[name] = []); - events.push({callback: callback, context: context, ctx: context || this}); - return this; - }, - - // Bind an event to only be triggered a single time. After the first time - // the callback is invoked, it will be removed. - once: function(name, callback, context) { - if (!eventsApi(this, 'once', name, [callback, context]) || !callback) return this; - var self = this; - var once = _.once(function() { - self.off(name, once); - callback.apply(this, arguments); - }); - once._callback = callback; - return this.on(name, once, context); - }, - - // Remove one or many callbacks. If `context` is null, removes all - // callbacks with that function. If `callback` is null, removes all - // callbacks for the event. If `name` is null, removes all bound - // callbacks for all events. - off: function(name, callback, context) { - var retain, ev, events, names, i, l, j, k; - if (!this._events || !eventsApi(this, 'off', name, [callback, context])) return this; - if (!name && !callback && !context) { - this._events = void 0; - return this; - } - names = name ? [name] : _.keys(this._events); - for (i = 0, l = names.length; i < l; i++) { - name = names[i]; - if (events = this._events[name]) { - this._events[name] = retain = []; - if (callback || context) { - for (j = 0, k = events.length; j < k; j++) { - ev = events[j]; - if ((callback && callback !== ev.callback && callback !== ev.callback._callback) || - (context && context !== ev.context)) { - retain.push(ev); - } - } - } - if (!retain.length) delete this._events[name]; - } - } - - return this; - }, - - // Trigger one or many events, firing all bound callbacks. Callbacks are - // passed the same arguments as `trigger` is, apart from the event name - // (unless you're listening on `"all"`, which will cause your callback to - // receive the true name of the event as the first argument). - trigger: function(name) { - if (!this._events) return this; - var args = slice.call(arguments, 1); - if (!eventsApi(this, 'trigger', name, args)) return this; - var events = this._events[name]; - var allEvents = this._events.all; - if (events) triggerEvents(events, args); - if (allEvents) triggerEvents(allEvents, arguments); - return this; - }, - - // Tell this object to stop listening to either specific events ... or - // to every object it's currently listening to. - stopListening: function(obj, name, callback) { - var listeningTo = this._listeningTo; - if (!listeningTo) return this; - var remove = !name && !callback; - if (!callback && typeof name === 'object') callback = this; - if (obj) (listeningTo = {})[obj._listenId] = obj; - for (var id in listeningTo) { - obj = listeningTo[id]; - obj.off(name, callback, this); - if (remove || _.isEmpty(obj._events)) delete this._listeningTo[id]; - } - return this; - } - - }; - - // Regular expression used to split event strings. - var eventSplitter = /\s+/; - - // Implement fancy features of the Events API such as multiple event - // names `"change blur"` and jQuery-style event maps `{change: action}` - // in terms of the existing API. - var eventsApi = function(obj, action, name, rest) { - if (!name) return true; - - // Handle event maps. - if (typeof name === 'object') { - for (var key in name) { - obj[action].apply(obj, [key, name[key]].concat(rest)); - } - return false; - } - - // Handle space separated event names. - if (eventSplitter.test(name)) { - var names = name.split(eventSplitter); - for (var i = 0, l = names.length; i < l; i++) { - obj[action].apply(obj, [names[i]].concat(rest)); - } - return false; - } - - return true; - }; - - // A difficult-to-believe, but optimized internal dispatch function for - // triggering events. Tries to keep the usual cases speedy (most internal - // Backbone events have 3 arguments). - var triggerEvents = function(events, args) { - var ev, i = -1, l = events.length, a1 = args[0], a2 = args[1], a3 = args[2]; - switch (args.length) { - case 0: while (++i < l) (ev = events[i]).callback.call(ev.ctx); return; - case 1: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1); return; - case 2: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2); return; - case 3: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2, a3); return; - default: while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args); return; - } - }; - - var listenMethods = {listenTo: 'on', listenToOnce: 'once'}; - - // Inversion-of-control versions of `on` and `once`. Tell *this* object to - // listen to an event in another object ... keeping track of what it's - // listening to. - _.each(listenMethods, function(implementation, method) { - Events[method] = function(obj, name, callback) { - var listeningTo = this._listeningTo || (this._listeningTo = {}); - var id = obj._listenId || (obj._listenId = _.uniqueId('l')); - listeningTo[id] = obj; - if (!callback && typeof name === 'object') callback = this; - obj[implementation](name, callback, this); - return this; - }; - }); - - // Aliases for backwards compatibility. - Events.bind = Events.on; - Events.unbind = Events.off; - - // Allow the `Backbone` object to serve as a global event bus, for folks who - // want global "pubsub" in a convenient place. - _.extend(Backbone, Events); - - // Backbone.Model - // -------------- - - // Backbone **Models** are the basic data object in the framework -- - // frequently representing a row in a table in a database on your server. - // A discrete chunk of data and a bunch of useful, related methods for - // performing computations and transformations on that data. - - // Create a new model with the specified attributes. A client id (`cid`) - // is automatically generated and assigned for you. - var Model = Backbone.Model = function(attributes, options) { - var attrs = attributes || {}; - options || (options = {}); - this.cid = _.uniqueId('c'); - this.attributes = {}; - if (options.collection) this.collection = options.collection; - if (options.parse) attrs = this.parse(attrs, options) || {}; - attrs = _.defaults({}, attrs, _.result(this, 'defaults')); - this.set(attrs, options); - this.changed = {}; - this.initialize.apply(this, arguments); - }; - - // Attach all inheritable methods to the Model prototype. - _.extend(Model.prototype, Events, { - - // A hash of attributes whose current and previous value differ. - changed: null, - - // The value returned during the last failed validation. - validationError: null, - - // The default name for the JSON `id` attribute is `"id"`. MongoDB and - // CouchDB users may want to set this to `"_id"`. - idAttribute: 'id', - - // Initialize is an empty function by default. Override it with your own - // initialization logic. - initialize: function(){}, - - // Return a copy of the model's `attributes` object. - toJSON: function(options) { - return _.clone(this.attributes); - }, - - // Proxy `Backbone.sync` by default -- but override this if you need - // custom syncing semantics for *this* particular model. - sync: function() { - return Backbone.sync.apply(this, arguments); - }, - - // Get the value of an attribute. - get: function(attr) { - return this.attributes[attr]; - }, - - // Get the HTML-escaped value of an attribute. - escape: function(attr) { - return _.escape(this.get(attr)); - }, - - // Returns `true` if the attribute contains a value that is not null - // or undefined. - has: function(attr) { - return this.get(attr) != null; - }, - - // Set a hash of model attributes on the object, firing `"change"`. This is - // the core primitive operation of a model, updating the data and notifying - // anyone who needs to know about the change in state. The heart of the beast. - set: function(key, val, options) { - var attr, attrs, unset, changes, silent, changing, prev, current; - if (key == null) return this; - - // Handle both `"key", value` and `{key: value}` -style arguments. - if (typeof key === 'object') { - attrs = key; - options = val; - } else { - (attrs = {})[key] = val; - } - - options || (options = {}); - - // Run validation. - if (!this._validate(attrs, options)) return false; - - // Extract attributes and options. - unset = options.unset; - silent = options.silent; - changes = []; - changing = this._changing; - this._changing = true; - - if (!changing) { - this._previousAttributes = _.clone(this.attributes); - this.changed = {}; - } - current = this.attributes, prev = this._previousAttributes; - - // Check for changes of `id`. - if (this.idAttribute in attrs) this.id = attrs[this.idAttribute]; - - // For each `set` attribute, update or delete the current value. - for (attr in attrs) { - val = attrs[attr]; - if (!_.isEqual(current[attr], val)) changes.push(attr); - if (!_.isEqual(prev[attr], val)) { - this.changed[attr] = val; - } else { - delete this.changed[attr]; - } - unset ? delete current[attr] : current[attr] = val; - } - - // Trigger all relevant attribute changes. - if (!silent) { - if (changes.length) this._pending = options; - for (var i = 0, l = changes.length; i < l; i++) { - this.trigger('change:' + changes[i], this, current[changes[i]], options); - } - } - - // You might be wondering why there's a `while` loop here. Changes can - // be recursively nested within `"change"` events. - if (changing) return this; - if (!silent) { - while (this._pending) { - options = this._pending; - this._pending = false; - this.trigger('change', this, options); - } - } - this._pending = false; - this._changing = false; - return this; - }, - - // Remove an attribute from the model, firing `"change"`. `unset` is a noop - // if the attribute doesn't exist. - unset: function(attr, options) { - return this.set(attr, void 0, _.extend({}, options, {unset: true})); - }, - - // Clear all attributes on the model, firing `"change"`. - clear: function(options) { - var attrs = {}; - for (var key in this.attributes) attrs[key] = void 0; - return this.set(attrs, _.extend({}, options, {unset: true})); - }, - - // Determine if the model has changed since the last `"change"` event. - // If you specify an attribute name, determine if that attribute has changed. - hasChanged: function(attr) { - if (attr == null) return !_.isEmpty(this.changed); - return _.has(this.changed, attr); - }, - - // Return an object containing all the attributes that have changed, or - // false if there are no changed attributes. Useful for determining what - // parts of a view need to be updated and/or what attributes need to be - // persisted to the server. Unset attributes will be set to undefined. - // You can also pass an attributes object to diff against the model, - // determining if there *would be* a change. - changedAttributes: function(diff) { - if (!diff) return this.hasChanged() ? _.clone(this.changed) : false; - var val, changed = false; - var old = this._changing ? this._previousAttributes : this.attributes; - for (var attr in diff) { - if (_.isEqual(old[attr], (val = diff[attr]))) continue; - (changed || (changed = {}))[attr] = val; - } - return changed; - }, - - // Get the previous value of an attribute, recorded at the time the last - // `"change"` event was fired. - previous: function(attr) { - if (attr == null || !this._previousAttributes) return null; - return this._previousAttributes[attr]; - }, - - // Get all of the attributes of the model at the time of the previous - // `"change"` event. - previousAttributes: function() { - return _.clone(this._previousAttributes); - }, - - // Fetch the model from the server. If the server's representation of the - // model differs from its current attributes, they will be overridden, - // triggering a `"change"` event. - fetch: function(options) { - options = options ? _.clone(options) : {}; - if (options.parse === void 0) options.parse = true; - var model = this; - var success = options.success; - options.success = function(resp) { - if (!model.set(model.parse(resp, options), options)) return false; - if (success) success(model, resp, options); - model.trigger('sync', model, resp, options); - }; - wrapError(this, options); - return this.sync('read', this, options); - }, - - // Set a hash of model attributes, and sync the model to the server. - // If the server returns an attributes hash that differs, the model's - // state will be `set` again. - save: function(key, val, options) { - var attrs, method, xhr, attributes = this.attributes; - - // Handle both `"key", value` and `{key: value}` -style arguments. - if (key == null || typeof key === 'object') { - attrs = key; - options = val; - } else { - (attrs = {})[key] = val; - } - - options = _.extend({validate: true}, options); - - // If we're not waiting and attributes exist, save acts as - // `set(attr).save(null, opts)` with validation. Otherwise, check if - // the model will be valid when the attributes, if any, are set. - if (attrs && !options.wait) { - if (!this.set(attrs, options)) return false; - } else { - if (!this._validate(attrs, options)) return false; - } - - // Set temporary attributes if `{wait: true}`. - if (attrs && options.wait) { - this.attributes = _.extend({}, attributes, attrs); - } - - // After a successful server-side save, the client is (optionally) - // updated with the server-side state. - if (options.parse === void 0) options.parse = true; - var model = this; - var success = options.success; - options.success = function(resp) { - // Ensure attributes are restored during synchronous saves. - model.attributes = attributes; - var serverAttrs = model.parse(resp, options); - if (options.wait) serverAttrs = _.extend(attrs || {}, serverAttrs); - if (_.isObject(serverAttrs) && !model.set(serverAttrs, options)) { - return false; - } - if (success) success(model, resp, options); - model.trigger('sync', model, resp, options); - }; - wrapError(this, options); - - method = this.isNew() ? 'create' : (options.patch ? 'patch' : 'update'); - if (method === 'patch') options.attrs = attrs; - xhr = this.sync(method, this, options); - - // Restore attributes. - if (attrs && options.wait) this.attributes = attributes; - - return xhr; - }, - - // Destroy this model on the server if it was already persisted. - // Optimistically removes the model from its collection, if it has one. - // If `wait: true` is passed, waits for the server to respond before removal. - destroy: function(options) { - options = options ? _.clone(options) : {}; - var model = this; - var success = options.success; - - var destroy = function() { - model.trigger('destroy', model, model.collection, options); - }; - - options.success = function(resp) { - if (options.wait || model.isNew()) destroy(); - if (success) success(model, resp, options); - if (!model.isNew()) model.trigger('sync', model, resp, options); - }; - - if (this.isNew()) { - options.success(); - return false; - } - wrapError(this, options); - - var xhr = this.sync('delete', this, options); - if (!options.wait) destroy(); - return xhr; - }, - - // Default URL for the model's representation on the server -- if you're - // using Backbone's restful methods, override this to change the endpoint - // that will be called. - url: function() { - var base = - _.result(this, 'urlRoot') || - _.result(this.collection, 'url') || - urlError(); - if (this.isNew()) return base; - return base.replace(/([^\/])$/, '$1/') + encodeURIComponent(this.id); - }, - - // **parse** converts a response into the hash of attributes to be `set` on - // the model. The default implementation is just to pass the response along. - parse: function(resp, options) { - return resp; - }, - - // Create a new model with identical attributes to this one. - clone: function() { - return new this.constructor(this.attributes); - }, - - // A model is new if it has never been saved to the server, and lacks an id. - isNew: function() { - return !this.has(this.idAttribute); - }, - - // Check if the model is currently in a valid state. - isValid: function(options) { - return this._validate({}, _.extend(options || {}, { validate: true })); - }, - - // Run validation against the next complete set of model attributes, - // returning `true` if all is well. Otherwise, fire an `"invalid"` event. - _validate: function(attrs, options) { - if (!options.validate || !this.validate) return true; - attrs = _.extend({}, this.attributes, attrs); - var error = this.validationError = this.validate(attrs, options) || null; - if (!error) return true; - this.trigger('invalid', this, error, _.extend(options, {validationError: error})); - return false; - } - - }); - - // Underscore methods that we want to implement on the Model. - var modelMethods = ['keys', 'values', 'pairs', 'invert', 'pick', 'omit']; - - // Mix in each Underscore method as a proxy to `Model#attributes`. - _.each(modelMethods, function(method) { - Model.prototype[method] = function() { - var args = slice.call(arguments); - args.unshift(this.attributes); - return _[method].apply(_, args); - }; - }); - - // Backbone.Collection - // ------------------- - - // If models tend to represent a single row of data, a Backbone Collection is - // more analagous to a table full of data ... or a small slice or page of that - // table, or a collection of rows that belong together for a particular reason - // -- all of the messages in this particular folder, all of the documents - // belonging to this particular author, and so on. Collections maintain - // indexes of their models, both in order, and for lookup by `id`. - - // Create a new **Collection**, perhaps to contain a specific type of `model`. - // If a `comparator` is specified, the Collection will maintain - // its models in sort order, as they're added and removed. - var Collection = Backbone.Collection = function(models, options) { - options || (options = {}); - if (options.model) this.model = options.model; - if (options.comparator !== void 0) this.comparator = options.comparator; - this._reset(); - this.initialize.apply(this, arguments); - if (models) this.reset(models, _.extend({silent: true}, options)); - }; - - // Default options for `Collection#set`. - var setOptions = {add: true, remove: true, merge: true}; - var addOptions = {add: true, remove: false}; - - // Define the Collection's inheritable methods. - _.extend(Collection.prototype, Events, { - - // The default model for a collection is just a **Backbone.Model**. - // This should be overridden in most cases. - model: Model, - - // Initialize is an empty function by default. Override it with your own - // initialization logic. - initialize: function(){}, - - // The JSON representation of a Collection is an array of the - // models' attributes. - toJSON: function(options) { - return this.map(function(model){ return model.toJSON(options); }); - }, - - // Proxy `Backbone.sync` by default. - sync: function() { - return Backbone.sync.apply(this, arguments); - }, - - // Add a model, or list of models to the set. - add: function(models, options) { - return this.set(models, _.extend({merge: false}, options, addOptions)); - }, - - // Remove a model, or a list of models from the set. - remove: function(models, options) { - var singular = !_.isArray(models); - models = singular ? [models] : _.clone(models); - options || (options = {}); - var i, l, index, model; - for (i = 0, l = models.length; i < l; i++) { - model = models[i] = this.get(models[i]); - if (!model) continue; - delete this._byId[model.id]; - delete this._byId[model.cid]; - index = this.indexOf(model); - this.models.splice(index, 1); - this.length--; - if (!options.silent) { - options.index = index; - model.trigger('remove', model, this, options); - } - this._removeReference(model, options); - } - return singular ? models[0] : models; - }, - - // Update a collection by `set`-ing a new list of models, adding new ones, - // removing models that are no longer present, and merging models that - // already exist in the collection, as necessary. Similar to **Model#set**, - // the core operation for updating the data contained by the collection. - set: function(models, options) { - options = _.defaults({}, options, setOptions); - if (options.parse) models = this.parse(models, options); - var singular = !_.isArray(models); - models = singular ? (models ? [models] : []) : _.clone(models); - var i, l, id, model, attrs, existing, sort; - var at = options.at; - var targetModel = this.model; - var sortable = this.comparator && (at == null) && options.sort !== false; - var sortAttr = _.isString(this.comparator) ? this.comparator : null; - var toAdd = [], toRemove = [], modelMap = {}; - var add = options.add, merge = options.merge, remove = options.remove; - var order = !sortable && add && remove ? [] : false; - - // Turn bare objects into model references, and prevent invalid models - // from being added. - for (i = 0, l = models.length; i < l; i++) { - attrs = models[i] || {}; - if (attrs instanceof Model) { - id = model = attrs; - } else { - id = attrs[targetModel.prototype.idAttribute || 'id']; - } - - // If a duplicate is found, prevent it from being added and - // optionally merge it into the existing model. - if (existing = this.get(id)) { - if (remove) modelMap[existing.cid] = true; - if (merge) { - attrs = attrs === model ? model.attributes : attrs; - if (options.parse) attrs = existing.parse(attrs, options); - existing.set(attrs, options); - if (sortable && !sort && existing.hasChanged(sortAttr)) sort = true; - } - models[i] = existing; - - // If this is a new, valid model, push it to the `toAdd` list. - } else if (add) { - model = models[i] = this._prepareModel(attrs, options); - if (!model) continue; - toAdd.push(model); - this._addReference(model, options); - } - - // Do not add multiple models with the same `id`. - model = existing || model; - if (order && (model.isNew() || !modelMap[model.id])) order.push(model); - modelMap[model.id] = true; - } - - // Remove nonexistent models if appropriate. - if (remove) { - for (i = 0, l = this.length; i < l; ++i) { - if (!modelMap[(model = this.models[i]).cid]) toRemove.push(model); - } - if (toRemove.length) this.remove(toRemove, options); - } - - // See if sorting is needed, update `length` and splice in new models. - if (toAdd.length || (order && order.length)) { - if (sortable) sort = true; - this.length += toAdd.length; - if (at != null) { - for (i = 0, l = toAdd.length; i < l; i++) { - this.models.splice(at + i, 0, toAdd[i]); - } - } else { - if (order) this.models.length = 0; - var orderedModels = order || toAdd; - for (i = 0, l = orderedModels.length; i < l; i++) { - this.models.push(orderedModels[i]); - } - } - } - - // Silently sort the collection if appropriate. - if (sort) this.sort({silent: true}); - - // Unless silenced, it's time to fire all appropriate add/sort events. - if (!options.silent) { - for (i = 0, l = toAdd.length; i < l; i++) { - (model = toAdd[i]).trigger('add', model, this, options); - } - if (sort || (order && order.length)) this.trigger('sort', this, options); - } - - // Return the added (or merged) model (or models). - return singular ? models[0] : models; - }, - - // When you have more items than you want to add or remove individually, - // you can reset the entire set with a new list of models, without firing - // any granular `add` or `remove` events. Fires `reset` when finished. - // Useful for bulk operations and optimizations. - reset: function(models, options) { - options || (options = {}); - for (var i = 0, l = this.models.length; i < l; i++) { - this._removeReference(this.models[i], options); - } - options.previousModels = this.models; - this._reset(); - models = this.add(models, _.extend({silent: true}, options)); - if (!options.silent) this.trigger('reset', this, options); - return models; - }, - - // Add a model to the end of the collection. - push: function(model, options) { - return this.add(model, _.extend({at: this.length}, options)); - }, - - // Remove a model from the end of the collection. - pop: function(options) { - var model = this.at(this.length - 1); - this.remove(model, options); - return model; - }, - - // Add a model to the beginning of the collection. - unshift: function(model, options) { - return this.add(model, _.extend({at: 0}, options)); - }, - - // Remove a model from the beginning of the collection. - shift: function(options) { - var model = this.at(0); - this.remove(model, options); - return model; - }, - - // Slice out a sub-array of models from the collection. - slice: function() { - return slice.apply(this.models, arguments); - }, - - // Get a model from the set by id. - get: function(obj) { - if (obj == null) return void 0; - return this._byId[obj] || this._byId[obj.id] || this._byId[obj.cid]; - }, - - // Get the model at the given index. - at: function(index) { - return this.models[index]; - }, - - // Return models with matching attributes. Useful for simple cases of - // `filter`. - where: function(attrs, first) { - if (_.isEmpty(attrs)) return first ? void 0 : []; - return this[first ? 'find' : 'filter'](function(model) { - for (var key in attrs) { - if (attrs[key] !== model.get(key)) return false; - } - return true; - }); - }, - - // Return the first model with matching attributes. Useful for simple cases - // of `find`. - findWhere: function(attrs) { - return this.where(attrs, true); - }, - - // Force the collection to re-sort itself. You don't need to call this under - // normal circumstances, as the set will maintain sort order as each item - // is added. - sort: function(options) { - if (!this.comparator) throw new Error('Cannot sort a set without a comparator'); - options || (options = {}); - - // Run sort based on type of `comparator`. - if (_.isString(this.comparator) || this.comparator.length === 1) { - this.models = this.sortBy(this.comparator, this); - } else { - this.models.sort(_.bind(this.comparator, this)); - } - - if (!options.silent) this.trigger('sort', this, options); - return this; - }, - - // Pluck an attribute from each model in the collection. - pluck: function(attr) { - return _.invoke(this.models, 'get', attr); - }, - - // Fetch the default set of models for this collection, resetting the - // collection when they arrive. If `reset: true` is passed, the response - // data will be passed through the `reset` method instead of `set`. - fetch: function(options) { - options = options ? _.clone(options) : {}; - if (options.parse === void 0) options.parse = true; - var success = options.success; - var collection = this; - options.success = function(resp) { - var method = options.reset ? 'reset' : 'set'; - collection[method](resp, options); - if (success) success(collection, resp, options); - collection.trigger('sync', collection, resp, options); - }; - wrapError(this, options); - return this.sync('read', this, options); - }, - - // Create a new instance of a model in this collection. Add the model to the - // collection immediately, unless `wait: true` is passed, in which case we - // wait for the server to agree. - create: function(model, options) { - options = options ? _.clone(options) : {}; - if (!(model = this._prepareModel(model, options))) return false; - if (!options.wait) this.add(model, options); - var collection = this; - var success = options.success; - options.success = function(model, resp) { - if (options.wait) collection.add(model, options); - if (success) success(model, resp, options); - }; - model.save(null, options); - return model; - }, - - // **parse** converts a response into a list of models to be added to the - // collection. The default implementation is just to pass it through. - parse: function(resp, options) { - return resp; - }, - - // Create a new collection with an identical list of models as this one. - clone: function() { - return new this.constructor(this.models); - }, - - // Private method to reset all internal state. Called when the collection - // is first initialized or reset. - _reset: function() { - this.length = 0; - this.models = []; - this._byId = {}; - }, - - // Prepare a hash of attributes (or other model) to be added to this - // collection. - _prepareModel: function(attrs, options) { - if (attrs instanceof Model) return attrs; - options = options ? _.clone(options) : {}; - options.collection = this; - var model = new this.model(attrs, options); - if (!model.validationError) return model; - this.trigger('invalid', this, model.validationError, options); - return false; - }, - - // Internal method to create a model's ties to a collection. - _addReference: function(model, options) { - this._byId[model.cid] = model; - if (model.id != null) this._byId[model.id] = model; - if (!model.collection) model.collection = this; - model.on('all', this._onModelEvent, this); - }, - - // Internal method to sever a model's ties to a collection. - _removeReference: function(model, options) { - if (this === model.collection) delete model.collection; - model.off('all', this._onModelEvent, this); - }, - - // Internal method called every time a model in the set fires an event. - // Sets need to update their indexes when models change ids. All other - // events simply proxy through. "add" and "remove" events that originate - // in other collections are ignored. - _onModelEvent: function(event, model, collection, options) { - if ((event === 'add' || event === 'remove') && collection !== this) return; - if (event === 'destroy') this.remove(model, options); - if (model && event === 'change:' + model.idAttribute) { - delete this._byId[model.previous(model.idAttribute)]; - if (model.id != null) this._byId[model.id] = model; - } - this.trigger.apply(this, arguments); - } - - }); - - // Underscore methods that we want to implement on the Collection. - // 90% of the core usefulness of Backbone Collections is actually implemented - // right here: - var methods = ['forEach', 'each', 'map', 'collect', 'reduce', 'foldl', - 'inject', 'reduceRight', 'foldr', 'find', 'detect', 'filter', 'select', - 'reject', 'every', 'all', 'some', 'any', 'include', 'contains', 'invoke', - 'max', 'min', 'toArray', 'size', 'first', 'head', 'take', 'initial', 'rest', - 'tail', 'drop', 'last', 'without', 'difference', 'indexOf', 'shuffle', - 'lastIndexOf', 'isEmpty', 'chain', 'sample']; - - // Mix in each Underscore method as a proxy to `Collection#models`. - _.each(methods, function(method) { - Collection.prototype[method] = function() { - var args = slice.call(arguments); - args.unshift(this.models); - return _[method].apply(_, args); - }; - }); - - // Underscore methods that take a property name as an argument. - var attributeMethods = ['groupBy', 'countBy', 'sortBy', 'indexBy']; - - // Use attributes instead of properties. - _.each(attributeMethods, function(method) { - Collection.prototype[method] = function(value, context) { - var iterator = _.isFunction(value) ? value : function(model) { - return model.get(value); - }; - return _[method](this.models, iterator, context); - }; - }); - - // Backbone.View - // ------------- - - // Backbone Views are almost more convention than they are actual code. A View - // is simply a JavaScript object that represents a logical chunk of UI in the - // DOM. This might be a single item, an entire list, a sidebar or panel, or - // even the surrounding frame which wraps your whole app. Defining a chunk of - // UI as a **View** allows you to define your DOM events declaratively, without - // having to worry about render order ... and makes it easy for the view to - // react to specific changes in the state of your models. - - // Creating a Backbone.View creates its initial element outside of the DOM, - // if an existing element is not provided... - var View = Backbone.View = function(options) { - this.cid = _.uniqueId('view'); - options || (options = {}); - _.extend(this, _.pick(options, viewOptions)); - this._ensureElement(); - this.initialize.apply(this, arguments); - this.delegateEvents(); - }; - - // Cached regex to split keys for `delegate`. - var delegateEventSplitter = /^(\S+)\s*(.*)$/; - - // List of view options to be merged as properties. - var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName', 'events']; - - // Set up all inheritable **Backbone.View** properties and methods. - _.extend(View.prototype, Events, { - - // The default `tagName` of a View's element is `"div"`. - tagName: 'div', - - // jQuery delegate for element lookup, scoped to DOM elements within the - // current view. This should be preferred to global lookups where possible. - $: function(selector) { - return this.$el.find(selector); - }, - - // Initialize is an empty function by default. Override it with your own - // initialization logic. - initialize: function(){}, - - // **render** is the core function that your view should override, in order - // to populate its element (`this.el`), with the appropriate HTML. The - // convention is for **render** to always return `this`. - render: function() { - return this; - }, - - // Remove this view by taking the element out of the DOM, and removing any - // applicable Backbone.Events listeners. - remove: function() { - this.$el.remove(); - this.stopListening(); - return this; - }, - - // Change the view's element (`this.el` property), including event - // re-delegation. - setElement: function(element, delegate) { - if (this.$el) this.undelegateEvents(); - this.$el = element instanceof Backbone.$ ? element : Backbone.$(element); - this.el = this.$el[0]; - if (delegate !== false) this.delegateEvents(); - return this; - }, - - // Set callbacks, where `this.events` is a hash of - // - // *{"event selector": "callback"}* - // - // { - // 'mousedown .title': 'edit', - // 'click .button': 'save', - // 'click .open': function(e) { ... } - // } - // - // pairs. Callbacks will be bound to the view, with `this` set properly. - // Uses event delegation for efficiency. - // Omitting the selector binds the event to `this.el`. - // This only works for delegate-able events: not `focus`, `blur`, and - // not `change`, `submit`, and `reset` in Internet Explorer. - delegateEvents: function(events) { - if (!(events || (events = _.result(this, 'events')))) return this; - this.undelegateEvents(); - for (var key in events) { - var method = events[key]; - if (!_.isFunction(method)) method = this[events[key]]; - if (!method) continue; - - var match = key.match(delegateEventSplitter); - var eventName = match[1], selector = match[2]; - method = _.bind(method, this); - eventName += '.delegateEvents' + this.cid; - if (selector === '') { - this.$el.on(eventName, method); - } else { - this.$el.on(eventName, selector, method); - } - } - return this; - }, - - // Clears all callbacks previously bound to the view with `delegateEvents`. - // You usually don't need to use this, but may wish to if you have multiple - // Backbone views attached to the same DOM element. - undelegateEvents: function() { - this.$el.off('.delegateEvents' + this.cid); - return this; - }, - - // Ensure that the View has a DOM element to render into. - // If `this.el` is a string, pass it through `$()`, take the first - // matching element, and re-assign it to `el`. Otherwise, create - // an element from the `id`, `className` and `tagName` properties. - _ensureElement: function() { - if (!this.el) { - var attrs = _.extend({}, _.result(this, 'attributes')); - if (this.id) attrs.id = _.result(this, 'id'); - if (this.className) attrs['class'] = _.result(this, 'className'); - var $el = Backbone.$('<' + _.result(this, 'tagName') + '>').attr(attrs); - this.setElement($el, false); - } else { - this.setElement(_.result(this, 'el'), false); - } - } - - }); - - // Backbone.sync - // ------------- - - // Override this function to change the manner in which Backbone persists - // models to the server. You will be passed the type of request, and the - // model in question. By default, makes a RESTful Ajax request - // to the model's `url()`. Some possible customizations could be: - // - // * Use `setTimeout` to batch rapid-fire updates into a single request. - // * Send up the models as XML instead of JSON. - // * Persist models via WebSockets instead of Ajax. - // - // Turn on `Backbone.emulateHTTP` in order to send `PUT` and `DELETE` requests - // as `POST`, with a `_method` parameter containing the true HTTP method, - // as well as all requests with the body as `application/x-www-form-urlencoded` - // instead of `application/json` with the model in a param named `model`. - // Useful when interfacing with server-side languages like **PHP** that make - // it difficult to read the body of `PUT` requests. - Backbone.sync = function(method, model, options) { - var type = methodMap[method]; - - // Default options, unless specified. - _.defaults(options || (options = {}), { - emulateHTTP: Backbone.emulateHTTP, - emulateJSON: Backbone.emulateJSON - }); - - // Default JSON-request options. - var params = {type: type, dataType: 'json'}; - - // Ensure that we have a URL. - if (!options.url) { - params.url = _.result(model, 'url') || urlError(); - } - - // Ensure that we have the appropriate request data. - if (options.data == null && model && (method === 'create' || method === 'update' || method === 'patch')) { - params.contentType = 'application/json'; - params.data = JSON.stringify(options.attrs || model.toJSON(options)); - } - - // For older servers, emulate JSON by encoding the request into an HTML-form. - if (options.emulateJSON) { - params.contentType = 'application/x-www-form-urlencoded'; - params.data = params.data ? {model: params.data} : {}; - } - - // For older servers, emulate HTTP by mimicking the HTTP method with `_method` - // And an `X-HTTP-Method-Override` header. - if (options.emulateHTTP && (type === 'PUT' || type === 'DELETE' || type === 'PATCH')) { - params.type = 'POST'; - if (options.emulateJSON) params.data._method = type; - var beforeSend = options.beforeSend; - options.beforeSend = function(xhr) { - xhr.setRequestHeader('X-HTTP-Method-Override', type); - if (beforeSend) return beforeSend.apply(this, arguments); - }; - } - - // Don't process data on a non-GET request. - if (params.type !== 'GET' && !options.emulateJSON) { - params.processData = false; - } - - // If we're sending a `PATCH` request, and we're in an old Internet Explorer - // that still has ActiveX enabled by default, override jQuery to use that - // for XHR instead. Remove this line when jQuery supports `PATCH` on IE8. - if (params.type === 'PATCH' && noXhrPatch) { - params.xhr = function() { - return new ActiveXObject("Microsoft.XMLHTTP"); - }; - } - - // Make the request, allowing the user to override any Ajax options. - var xhr = options.xhr = Backbone.ajax(_.extend(params, options)); - model.trigger('request', model, xhr, options); - return xhr; - }; - - var noXhrPatch = - typeof window !== 'undefined' && !!window.ActiveXObject && - !(window.XMLHttpRequest && (new XMLHttpRequest).dispatchEvent); - - // Map from CRUD to HTTP for our default `Backbone.sync` implementation. - var methodMap = { - 'create': 'POST', - 'update': 'PUT', - 'patch': 'PATCH', - 'delete': 'DELETE', - 'read': 'GET' - }; - - // Set the default implementation of `Backbone.ajax` to proxy through to `$`. - // Override this if you'd like to use a different library. - Backbone.ajax = function() { - return Backbone.$.ajax.apply(Backbone.$, arguments); - }; - - // Backbone.Router - // --------------- - - // Routers map faux-URLs to actions, and fire events when routes are - // matched. Creating a new one sets its `routes` hash, if not set statically. - var Router = Backbone.Router = function(options) { - options || (options = {}); - if (options.routes) this.routes = options.routes; - this._bindRoutes(); - this.initialize.apply(this, arguments); - }; - - // Cached regular expressions for matching named param parts and splatted - // parts of route strings. - var optionalParam = /\((.*?)\)/g; - var namedParam = /(\(\?)?:\w+/g; - var splatParam = /\*\w+/g; - var escapeRegExp = /[\-{}\[\]+?.,\\\^$|#\s]/g; - - // Set up all inheritable **Backbone.Router** properties and methods. - _.extend(Router.prototype, Events, { - - // Initialize is an empty function by default. Override it with your own - // initialization logic. - initialize: function(){}, - - // Manually bind a single named route to a callback. For example: - // - // this.route('search/:query/p:num', 'search', function(query, num) { - // ... - // }); - // - route: function(route, name, callback) { - if (!_.isRegExp(route)) route = this._routeToRegExp(route); - if (_.isFunction(name)) { - callback = name; - name = ''; - } - if (!callback) callback = this[name]; - var router = this; - Backbone.history.route(route, function(fragment) { - var args = router._extractParameters(route, fragment); - router.execute(callback, args); - router.trigger.apply(router, ['route:' + name].concat(args)); - router.trigger('route', name, args); - Backbone.history.trigger('route', router, name, args); - }); - return this; - }, - - // Execute a route handler with the provided parameters. This is an - // excellent place to do pre-route setup or post-route cleanup. - execute: function(callback, args) { - if (callback) callback.apply(this, args); - }, - - // Simple proxy to `Backbone.history` to save a fragment into the history. - navigate: function(fragment, options) { - Backbone.history.navigate(fragment, options); - return this; - }, - - // Bind all defined routes to `Backbone.history`. We have to reverse the - // order of the routes here to support behavior where the most general - // routes can be defined at the bottom of the route map. - _bindRoutes: function() { - if (!this.routes) return; - this.routes = _.result(this, 'routes'); - var route, routes = _.keys(this.routes); - while ((route = routes.pop()) != null) { - this.route(route, this.routes[route]); - } - }, - - // Convert a route string into a regular expression, suitable for matching - // against the current location hash. - _routeToRegExp: function(route) { - route = route.replace(escapeRegExp, '\\$&') - .replace(optionalParam, '(?:$1)?') - .replace(namedParam, function(match, optional) { - return optional ? match : '([^/?]+)'; - }) - .replace(splatParam, '([^?]*?)'); - return new RegExp('^' + route + '(?:\\?([\\s\\S]*))?$'); - }, - - // Given a route, and a URL fragment that it matches, return the array of - // extracted decoded parameters. Empty or unmatched parameters will be - // treated as `null` to normalize cross-browser behavior. - _extractParameters: function(route, fragment) { - var params = route.exec(fragment).slice(1); - return _.map(params, function(param, i) { - // Don't decode the search params. - if (i === params.length - 1) return param || null; - return param ? decodeURIComponent(param) : null; - }); - } - - }); - - // Backbone.History - // ---------------- - - // Handles cross-browser history management, based on either - // [pushState](http://diveintohtml5.info/history.html) and real URLs, or - // [onhashchange](https://developer.mozilla.org/en-US/docs/DOM/window.onhashchange) - // and URL fragments. If the browser supports neither (old IE, natch), - // falls back to polling. - var History = Backbone.History = function() { - this.handlers = []; - _.bindAll(this, 'checkUrl'); - - // Ensure that `History` can be used outside of the browser. - if (typeof window !== 'undefined') { - this.location = window.location; - this.history = window.history; - } - }; - - // Cached regex for stripping a leading hash/slash and trailing space. - var routeStripper = /^[#\/]|\s+$/g; - - // Cached regex for stripping leading and trailing slashes. - var rootStripper = /^\/+|\/+$/g; - - // Cached regex for detecting MSIE. - var isExplorer = /msie [\w.]+/; - - // Cached regex for removing a trailing slash. - var trailingSlash = /\/$/; - - // Cached regex for stripping urls of hash. - var pathStripper = /#.*$/; - - // Has the history handling already been started? - History.started = false; - - // Set up all inheritable **Backbone.History** properties and methods. - _.extend(History.prototype, Events, { - - // The default interval to poll for hash changes, if necessary, is - // twenty times a second. - interval: 50, - - // Are we at the app root? - atRoot: function() { - return this.location.pathname.replace(/[^\/]$/, '$&/') === this.root; - }, - - // Gets the true hash value. Cannot use location.hash directly due to bug - // in Firefox where location.hash will always be decoded. - getHash: function(window) { - var match = (window || this).location.href.match(/#(.*)$/); - return match ? match[1] : ''; - }, - - // Get the cross-browser normalized URL fragment, either from the URL, - // the hash, or the override. - getFragment: function(fragment, forcePushState) { - if (fragment == null) { - if (this._hasPushState || !this._wantsHashChange || forcePushState) { - fragment = decodeURI(this.location.pathname + this.location.search); - var root = this.root.replace(trailingSlash, ''); - if (!fragment.indexOf(root)) fragment = fragment.slice(root.length); - } else { - fragment = this.getHash(); - } - } - return fragment.replace(routeStripper, ''); - }, - - // Start the hash change handling, returning `true` if the current URL matches - // an existing route, and `false` otherwise. - start: function(options) { - if (History.started) throw new Error("Backbone.history has already been started"); - History.started = true; - - // Figure out the initial configuration. Do we need an iframe? - // Is pushState desired ... is it available? - this.options = _.extend({root: '/'}, this.options, options); - this.root = this.options.root; - this._wantsHashChange = this.options.hashChange !== false; - this._wantsPushState = !!this.options.pushState; - this._hasPushState = !!(this.options.pushState && this.history && this.history.pushState); - var fragment = this.getFragment(); - var docMode = document.documentMode; - var oldIE = (isExplorer.exec(navigator.userAgent.toLowerCase()) && (!docMode || docMode <= 7)); - - // Normalize root to always include a leading and trailing slash. - this.root = ('/' + this.root + '/').replace(rootStripper, '/'); - - if (oldIE && this._wantsHashChange) { - var frame = Backbone.$(' - - - diff --git a/src/test/mochitest/examples/doc-minified.html b/src/test/mochitest/examples/doc-minified.html deleted file mode 100644 index 4c95a9b4ae..0000000000 --- a/src/test/mochitest/examples/doc-minified.html +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - Debugger test page - - - - - - diff --git a/src/test/mochitest/examples/doc-script-switching.html b/src/test/mochitest/examples/doc-script-switching.html deleted file mode 100644 index 3c71497c25..0000000000 --- a/src/test/mochitest/examples/doc-script-switching.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - Debugger test page - - - - - - - - - - diff --git a/src/test/mochitest/examples/doc-scripts.html b/src/test/mochitest/examples/doc-scripts.html deleted file mode 100644 index 212b4802ff..0000000000 --- a/src/test/mochitest/examples/doc-scripts.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - Debugger test page - - - - - - - - - diff --git a/src/test/mochitest/examples/doc-sourcemap-bogus.html b/src/test/mochitest/examples/doc-sourcemap-bogus.html deleted file mode 100644 index da448a2cdc..0000000000 --- a/src/test/mochitest/examples/doc-sourcemap-bogus.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - Debugger test page - - - - - - diff --git a/src/test/mochitest/examples/doc-sourcemaps.html b/src/test/mochitest/examples/doc-sourcemaps.html deleted file mode 100644 index 10f5da0479..0000000000 --- a/src/test/mochitest/examples/doc-sourcemaps.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - Debugger test page - - - - - - diff --git a/src/test/mochitest/examples/doc-sources.html b/src/test/mochitest/examples/doc-sources.html deleted file mode 100644 index 14cc86701a..0000000000 --- a/src/test/mochitest/examples/doc-sources.html +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - Debugger test page - - - - - - - - - - - diff --git a/src/test/mochitest/examples/entry.js b/src/test/mochitest/examples/entry.js deleted file mode 100644 index d397a966ba..0000000000 --- a/src/test/mochitest/examples/entry.js +++ /dev/null @@ -1,16 +0,0 @@ -const times2 = require("./times2"); -const { output } = require("./output"); -const opts = require("./opts"); - -output(times2(1)); -output(times2(2)); - -if(opts.extra) { - output(times2(3)); -} - -window.keepMeAlive = function() { - // This function exists to make sure this script is never garbage - // collected. It is also callable from tests. - return times2(4); -} diff --git a/src/test/mochitest/examples/exceptions.js b/src/test/mochitest/examples/exceptions.js deleted file mode 100644 index 9523f00caf..0000000000 --- a/src/test/mochitest/examples/exceptions.js +++ /dev/null @@ -1,19 +0,0 @@ -function uncaughtException() { - throw "unreachable" -} - -function caughtError() { - try { - throw new Error("error"); - } catch (e) { - debugger; - } -} - -function caughtException() { - try { - throw "reachable"; - } catch (e) { - debugger; - } -} diff --git a/src/test/mochitest/examples/frames.js b/src/test/mochitest/examples/frames.js deleted file mode 100644 index 0f031582e4..0000000000 --- a/src/test/mochitest/examples/frames.js +++ /dev/null @@ -1,24 +0,0 @@ -function recurseA(i) { - if (i == 20) { - debugger; - return; - } - - // down into the rabbit hole we go - return (i % 2) ? recurseA(++i) : recurseB(++i); -} - -function recurseB(i) { - if (i == 20) { - debugger; - return; - } - - // down into the rabbit hole we go - return (i % 2) ? recurseA(++i) : recurseB(++i); -} - - -window.startRecursion = function() { - return recurseA(0); -} diff --git a/src/test/mochitest/examples/long.js b/src/test/mochitest/examples/long.js deleted file mode 100644 index 58d605b36b..0000000000 --- a/src/test/mochitest/examples/long.js +++ /dev/null @@ -1,76 +0,0 @@ -var app = {}; - -// Generic "model" object. You can use whatever -// framework you want. For this application it -// may not even be worth separating this logic -// out, but we do this to demonstrate one way to -// separate out parts of your application. -app.TodoModel = function (key) { - this.key = key; - this.todos = []; - this.onChanges = []; -}; - -app.TodoModel.prototype.addTodo = function (title) { - this.todos = this.todos.concat([{ - id: Utils.uuid(), - title: title, - completed: false - }]); -}; - -app.TodoModel.prototype.inform = function() { - // Something changed, but we do nothing - return null; -}; - -app.TodoModel.prototype.toggleAll = function (checked) { - // Note: it's usually better to use immutable data structures since they're - // easier to reason about and React works very well with them. That's why - // we use map() and filter() everywhere instead of mutating the array or - // todo items themselves. - this.todos = this.todos.map(function (todo) { - return Object.assign({}, todo, {completed: checked}); - }); - - this.inform(); -}; - -app.TodoModel.prototype.toggle = function (todoToToggle) { - this.todos = this.todos.map(function (todo) { - return todo !== todoToToggle ? - todo : - Object.assign({}, todo, {completed: !todo.completed}); - }); - - this.inform(); -}; - -app.TodoModel.prototype.destroy = function (todo) { - this.todos = this.todos.filter(function (candidate) { - return candidate !== todo; - }); - - this.inform(); -}; - -app.TodoModel.prototype.save = function (todoToSave, text) { - this.todos = this.todos.map(function (todo) { - return todo !== todoToSave ? todo : Object.assign({}, todo, {title: text}); - }); - - this.inform(); -}; - -app.TodoModel.prototype.clearCompleted = function () { - this.todos = this.todos.filter(function (todo) { - return !todo.completed; - }); - - this.inform(); -}; - -function testModel() { - const model = new app.TodoModel(); - model.clearCompleted(); -} diff --git a/src/test/mochitest/examples/math.min.js b/src/test/mochitest/examples/math.min.js deleted file mode 100644 index 5a8593345a..0000000000 --- a/src/test/mochitest/examples/math.min.js +++ /dev/null @@ -1,3 +0,0 @@ -function add(a,b,k){var result=a+b;return k(result)}function sub(a,b,k){var result=a-b;return k(result)}function mul(a,b,k){var result=a*b;return k(result)}function div(a,b,k){var result=a/b;return k(result)}function arithmetic(){ - add(4,4,function(a){ - sub(a,2,function(b){mul(b,3,function(c){div(c,2,function(d){console.log(d)})})})})}; diff --git a/src/test/mochitest/examples/nested/nested-source.js b/src/test/mochitest/examples/nested/nested-source.js deleted file mode 100644 index a7b20f015a..0000000000 --- a/src/test/mochitest/examples/nested/nested-source.js +++ /dev/null @@ -1,3 +0,0 @@ -function computeSomething() { - return 1; -} diff --git a/src/test/mochitest/examples/opts.js b/src/test/mochitest/examples/opts.js deleted file mode 100644 index 20988fa4a5..0000000000 --- a/src/test/mochitest/examples/opts.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - extra: true -}; diff --git a/src/test/mochitest/examples/output.js b/src/test/mochitest/examples/output.js deleted file mode 100644 index 14281fdbfd..0000000000 --- a/src/test/mochitest/examples/output.js +++ /dev/null @@ -1,5 +0,0 @@ -function output(str) { - console.log(str); -} - -module.exports = { output }; diff --git a/src/test/mochitest/examples/script-switching-01.js b/src/test/mochitest/examples/script-switching-01.js deleted file mode 100644 index 4ba2772deb..0000000000 --- a/src/test/mochitest/examples/script-switching-01.js +++ /dev/null @@ -1,6 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -function firstCall() { - secondCall(); -} diff --git a/src/test/mochitest/examples/script-switching-02.js b/src/test/mochitest/examples/script-switching-02.js deleted file mode 100644 index feb74315fc..0000000000 --- a/src/test/mochitest/examples/script-switching-02.js +++ /dev/null @@ -1,13 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -function secondCall() { - // This comment is useful: ☺ - debugger; - function foo() {} - if (x) { - foo(); - } -} - -var x = true; diff --git a/src/test/mochitest/examples/simple1.js b/src/test/mochitest/examples/simple1.js deleted file mode 100644 index 87cc50f442..0000000000 --- a/src/test/mochitest/examples/simple1.js +++ /dev/null @@ -1,31 +0,0 @@ -function main() { - // A comment so we can test that breakpoint sliding works across - // multiple lines - const func = foo(1, 2); - const result = func(); - return result; -} - -function doEval() { - eval("(" + function() { - debugger; - - window.evaledFunc = function() { - var foo = 1; - var bar = 2; - return foo + bar; - }; - }.toString() + ")()"); -} - -function doNamedEval() { - eval("(" + function() { - debugger; - - window.evaledFunc = function() { - var foo = 1; - var bar = 2; - return foo + bar; - }; - }.toString() + ")();\n //# sourceURL=evaled.js"); -} diff --git a/src/test/mochitest/examples/simple2.js b/src/test/mochitest/examples/simple2.js deleted file mode 100644 index 40c280edfe..0000000000 --- a/src/test/mochitest/examples/simple2.js +++ /dev/null @@ -1,6 +0,0 @@ -function foo(x, y) { - function bar() { - return x + y; - } - return bar; -} diff --git a/src/test/mochitest/examples/times2.js b/src/test/mochitest/examples/times2.js deleted file mode 100644 index 2d51ed87a8..0000000000 --- a/src/test/mochitest/examples/times2.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = function(x) { - return x * 2; -} diff --git a/src/test/mochitest/examples/webpack.config.js b/src/test/mochitest/examples/webpack.config.js deleted file mode 100644 index ff22342ce1..0000000000 --- a/src/test/mochitest/examples/webpack.config.js +++ /dev/null @@ -1,8 +0,0 @@ - -module.exports = { - entry: "./entry.js", - output: { - filename: "bundle.js" - }, - devtool: "sourcemap" -} diff --git a/src/test/mochitest/head.js b/src/test/mochitest/head.js deleted file mode 100644 index b0964d8906..0000000000 --- a/src/test/mochitest/head.js +++ /dev/null @@ -1,684 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -/** - * The Mochitest API documentation - * @module mochitest - */ - -/** - * The mochitest API to wait for certain events. - * @module mochitest/waits - * @parent mochitest - */ - -/** - * The mochitest API predefined asserts. - * @module mochitest/asserts - * @parent mochitest - */ - -/** - * The mochitest API for interacting with the debugger. - * @module mochitest/actions - * @parent mochitest - */ - -/** - * Helper methods for the mochitest API. - * @module mochitest/helpers - * @parent mochitest - */ - -// shared-head.js handles imports, constants, and utility functions -Services.scriptloader.loadSubScript("chrome://mochitests/content/browser/devtools/client/framework/test/shared-head.js", this); -var { Toolbox } = require("devtools/client/framework/toolbox"); -const EXAMPLE_URL = "http://example.com/browser/devtools/client/debugger/new/test/mochitest/examples/"; - -Services.prefs.setBoolPref("devtools.debugger.new-debugger-frontend", true); -registerCleanupFunction(() => { - Services.prefs.clearUserPref("devtools.debugger.new-debugger-frontend"); - delete window.resumeTest; -}); - -// Wait until an action of `type` is dispatched. This is different -// then `_afterDispatchDone` because it doesn't wait for async actions -// to be done/errored. Use this if you want to listen for the "start" -// action of an async operation (somewhat rare). -function waitForNextDispatch(store, type) { - return new Promise(resolve => { - store.dispatch({ - // Normally we would use `services.WAIT_UNTIL`, but use the - // internal name here so tests aren't forced to always pass it - // in - type: "@@service/waitUntil", - predicate: action => action.type === type, - run: (dispatch, getState, action) => { - resolve(action); - } - }); - }); -} - -// Wait until an action of `type` is dispatched. If it's part of an -// async operation, wait until the `status` field is "done" or "error" -function _afterDispatchDone(store, type) { - return new Promise(resolve => { - store.dispatch({ - // Normally we would use `services.WAIT_UNTIL`, but use the - // internal name here so tests aren't forced to always pass it - // in - type: "@@service/waitUntil", - predicate: action => { - if (action.type === type) { - return action.status ? - (action.status === "done" || action.status === "error") : - true; - } - }, - run: (dispatch, getState, action) => { - resolve(action); - } - }); - }); -} - -/** - * Wait for a specific action type to be dispatch. - * If an async action, will wait for it to be done. - * - * @memberof mochitest/waits - * @param {Object} dbg - * @param {String} type - * @param {Number} eventRepeat - * @return {Promise} - * @static - */ -function waitForDispatch(dbg, type, eventRepeat = 1) { - let count = 0; - - return Task.spawn(function* () { - info("Waiting for " + type + " to dispatch " + eventRepeat + " time(s)"); - while (count < eventRepeat) { - yield _afterDispatchDone(dbg.store, type); - count++; - info(type + " dispatched " + count + " time(s)"); - } - }); -} - -/** - * Waits for specific thread events. - * - * @memberof mochitest/waits - * @param {Object} dbg - * @param {String} eventName - * @return {Promise} - * @static - */ -function waitForThreadEvents(dbg, eventName) { - info("Waiting for thread event '" + eventName + "' to fire."); - const thread = dbg.toolbox.threadClient; - - return new Promise(function(resolve, reject) { - thread.addListener(eventName, function onEvent(eventName, ...args) { - info("Thread event '" + eventName + "' fired."); - thread.removeListener(eventName, onEvent); - resolve.apply(resolve, args); - }); - }); -} - -/** - * Waits for `predicate(state)` to be true. `state` is the redux app state. - * - * @memberof mochitest/waits - * @param {Object} dbg - * @param {Function} predicate - * @return {Promise} - * @static - */ -function waitForState(dbg, predicate) { - return new Promise(resolve => { - const unsubscribe = dbg.store.subscribe(() => { - if (predicate(dbg.store.getState())) { - unsubscribe(); - resolve(); - } - }); - }); -} - -/** - * Waits for sources to be loaded. - * - * @memberof mochitest/waits - * @param {Object} dbg - * @param {Array} sources - * @return {Promise} - * @static - */ -function waitForSources(dbg, ...sources) { - if (sources.length === 0) { - return Promise.resolve(); - } - - info("Waiting on sources: " + sources.join(", ")); - const { selectors: { getSources }, store } = dbg; - return Promise.all(sources.map(url => { - function sourceExists(state) { - return getSources(state).some(s => { - return s.get("url").includes(url); - }); - } - - if (!sourceExists(store.getState())) { - return waitForState(dbg, sourceExists); - } - })); -} - -function waitForElement(dbg, selector) { - return waitUntil(() => findElementWithSelector(dbg, selector)) -} - -/** - * Assert that the debugger is paused at the correct location. - * - * @memberof mochitest/asserts - * @param {Object} dbg - * @param {String} source - * @param {Number} line - * @static - */ -function assertPausedLocation(dbg, source, line) { - const { selectors: { getSelectedSource, getPause }, getState } = dbg; - source = findSource(dbg, source); - - // Check the selected source - is(getSelectedSource(getState()).get("id"), source.id); - - // Check the pause location - const location = getPause(getState()).getIn(["frame", "location"]); - is(location.get("sourceId"), source.id); - is(location.get("line"), line); - - // Check the debug line - ok(dbg.win.cm.lineInfo(line - 1).wrapClass.includes("debug-line"), - "Line is highlighted as paused"); -} - -/** - * Assert that the debugger is highlighting the correct location. - * - * @memberof mochitest/asserts - * @param {Object} dbg - * @param {String} source - * @param {Number} line - * @static - */ -function assertHighlightLocation(dbg, source, line) { - const { selectors: { getSelectedSource, getPause }, getState } = dbg; - source = findSource(dbg, source); - - // Check the selected source - is(getSelectedSource(getState()).get("url"), source.url); - - // Check the highlight line - const lineEl = findElement(dbg, "highlightLine"); - ok(lineEl, "Line is highlighted"); - ok(isVisibleWithin(findElement(dbg, "codeMirror"), lineEl), - "Highlighted line is visible"); - ok(dbg.win.cm.lineInfo(line - 1).wrapClass.includes("highlight-line"), - "Line is highlighted"); -} - -/** - * Returns boolean for whether the debugger is paused. - * - * @memberof mochitest/asserts - * @param {Object} dbg - * @static - */ -function isPaused(dbg) { - const { selectors: { getPause }, getState } = dbg; - return !!getPause(getState()); -} - -/** - * Waits for the debugger to be fully paused. - * - * @memberof mochitest/waits - * @param {Object} dbg - * @static - */ -function waitForPaused(dbg) { - return Task.spawn(function* () { - // We want to make sure that we get both a real paused event and - // that the state is fully populated. The client may do some more - // work (call other client methods) before populating the state. - yield waitForThreadEvents(dbg, "paused"), - yield waitForState(dbg, state => { - const pause = dbg.selectors.getPause(state); - // Make sure we have the paused state. - if (!pause) { - return false; - } - // Make sure the source text is completely loaded for the - // source we are paused in. - const sourceId = pause.getIn(["frame", "location", "sourceId"]); - const sourceText = dbg.selectors.getSourceText(dbg.getState(), sourceId); - return sourceText && !sourceText.get("loading"); - }); - }); -} - -function createDebuggerContext(toolbox) { - const win = toolbox.getPanel("jsdebugger").panelWin; - const store = win.Debugger.store; - - return { - actions: win.Debugger.actions, - selectors: win.Debugger.selectors, - getState: store.getState, - store: store, - client: win.Debugger.client, - toolbox: toolbox, - win: win - }; -} - -/** - * Intilializes the debugger. - * - * @memberof mochitest - * @param {String} url - * @param {Array} sources - * @return {Promise} dbg - * @static - */ -function initDebugger(url, ...sources) { - return Task.spawn(function* () { - const toolbox = yield openNewTabAndToolbox(EXAMPLE_URL + url, "jsdebugger"); - return createDebuggerContext(toolbox); - }); -} - -window.resumeTest = undefined; -/** - * Pause the test and let you interact with the debugger. - * The test can be resumed by invoking `resumeTest` in the console. - * - * @memberof mochitest - * @static - */ -function pauseTest() { - info("Test paused. Invoke resumeTest to continue."); - return new Promise(resolve => resumeTest = resolve); -} - -// Actions -/** - * Returns a source that matches the URL. - * - * @memberof mochitest/actions - * @param {Object} dbg - * @param {String} url - * @return {Object} source - * @static - */ -function findSource(dbg, url) { - if (typeof url !== "string") { - // Support passing in a source object itelf all APIs that use this - // function support both styles - const source = url; - return source; - } - - const sources = dbg.selectors.getSources(dbg.getState()); - const source = sources.find(s => s.get("url").includes(url)); - - if (!source) { - throw new Error("Unable to find source: " + url); - } - - return source.toJS(); -} - -/** - * Selects the source. - * - * @memberof mochitest/actions - * @param {Object} dbg - * @param {String} url - * @param {Number} line - * @return {Promise} - * @static - */ -function selectSource(dbg, url, line) { - info("Selecting source: " + url); - const source = findSource(dbg, url); - const hasText = !!dbg.selectors.getSourceText(dbg.getState(), source.id); - dbg.actions.selectSource(source.id, { line }); - - if (!hasText) { - return waitForDispatch(dbg, "LOAD_SOURCE_TEXT"); - } -} - -/** - * Steps over. - * - * @memberof mochitest/actions - * @param {Object} dbg - * @return {Promise} - * @static - */ -function stepOver(dbg) { - info("Stepping over"); - dbg.actions.stepOver(); - return waitForPaused(dbg); -} - -/** - * Steps in. - * - * @memberof mochitest/actions - * @param {Object} dbg - * @return {Promise} - * @static - */ -function stepIn(dbg) { - info("Stepping in"); - dbg.actions.stepIn(); - return waitForPaused(dbg); -} - -/** - * Steps out. - * - * @memberof mochitest/actions - * @param {Object} dbg - * @return {Promise} - * @static - */ -function stepOut(dbg) { - info("Stepping out"); - dbg.actions.stepOut(); - return waitForPaused(dbg); -} - -/** - * Resumes. - * - * @memberof mochitest/actions - * @param {Object} dbg - * @return {Promise} - * @static - */ -function resume(dbg) { - info("Resuming"); - dbg.actions.resume(); - return waitForThreadEvents(dbg, "resumed"); -} - -/** - * Reloads the debuggee. - * - * @memberof mochitest/actions - * @param {Object} dbg - * @param {Array} sources - * @return {Promise} - * @static - */ -function reload(dbg, ...sources) { - return dbg.client.reload().then(() => waitForSources(...sources)); -} - -/** - * Navigates the debuggee to another url. - * - * @memberof mochitest/actions - * @param {Object} dbg - * @param {String} url - * @param {Array} sources - * @return {Promise} - * @static - */ -function navigate(dbg, url, ...sources) { - dbg.client.navigate(url); - return waitForSources(dbg, ...sources); -} - -/** - * Adds a breakpoint to a source at line/col. - * - * @memberof mochitest/actions - * @param {Object} dbg - * @param {String} source - * @param {Number} line - * @param {Number} col - * @return {Promise} - * @static - */ -function addBreakpoint(dbg, source, line, col) { - source = findSource(dbg, source); - const sourceId = source.id; - dbg.actions.addBreakpoint({ sourceId, line, col }); - return waitForDispatch(dbg, "ADD_BREAKPOINT"); -} - -/** - * Removes a breakpoint from a source at line/col. - * - * @memberof mochitest/actions - * @param {Object} dbg - * @param {String} source - * @param {Number} line - * @param {Number} col - * @return {Promise} - * @static - */ -function removeBreakpoint(dbg, sourceId, line, col) { - return dbg.actions.removeBreakpoint({ sourceId, line, col }); -} - -/** - * Toggles the Pause on exceptions feature in the debugger. - * - * @memberof mochitest/actions - * @param {Object} dbg - * @param {Boolean} pauseOnExceptions - * @param {Boolean} ignoreCaughtExceptions - * @return {Promise} - * @static - */ -function togglePauseOnExceptions(dbg, - pauseOnExceptions, ignoreCaughtExceptions) { - const command = dbg.actions.pauseOnExceptions( - pauseOnExceptions, - ignoreCaughtExceptions - ); - - if (!isPaused(dbg)) { - return waitForThreadEvents(dbg, "resumed"); - } - - return command; -} - -// Helpers - -/** - * Invokes a global function in the debuggee tab. - * - * @memberof mochitest/helpers - * @param {String} fnc - * @return {Promise} - * @static - */ -function invokeInTab(fnc) { - info(`Invoking function ${fnc} in tab`); - return ContentTask.spawn(gBrowser.selectedBrowser, fnc, function* (fnc) { - content.wrappedJSObject[fnc](); // eslint-disable-line mozilla/no-cpows-in-tests, max-len - }); -} - -const isLinux = Services.appinfo.OS === "Linux"; -const cmdOrCtrl = isLinux ? { ctrlKey: true } : { metaKey: true }; -const keyMappings = { - sourceSearch: { code: "p", modifiers: cmdOrCtrl}, - fileSearch: { code: "f", modifiers: cmdOrCtrl}, - "Enter": { code: "VK_RETURN" }, - "Up": { code: "VK_UP" }, - "Down": { code: "VK_DOWN" }, - pauseKey: { code: "VK_F8" }, - resumeKey: { code: "VK_F8" }, - stepOverKey: { code: "VK_F10" }, - stepInKey: { code: "VK_F11", modifiers: { ctrlKey: isLinux }}, - stepOutKey: { code: "VK_F11", modifiers: { ctrlKey: isLinux, shiftKey: true }} -}; - -/** - * Simulates a key press in the debugger window. - * - * @memberof mochitest/helpers - * @param {Object} dbg - * @param {String} keyName - * @return {Promise} - * @static - */ -function pressKey(dbg, keyName) { - let keyEvent = keyMappings[keyName]; - - const { code, modifiers } = keyEvent; - return EventUtils.synthesizeKey( - code, - modifiers || {}, - dbg.win - ); -} - -function type(dbg, string) { - string.split("").forEach(char => { - EventUtils.synthesizeKey(char, {}, dbg.win); - }); -} - -function isVisibleWithin(outerEl, innerEl) { - const innerRect = innerEl.getBoundingClientRect(); - const outerRect = outerEl.getBoundingClientRect(); - return innerRect.top > outerRect.top && - innerRect.bottom < outerRect.bottom; -} - -const selectors = { - callStackHeader: ".call-stack-pane ._header", - callStackBody: ".call-stack-pane .pane", - scopesHeader: ".scopes-pane ._header", - breakpointItem: i => `.breakpoints-list .breakpoint:nth-child(${i})`, - scopeNode: i => `.scopes-list .tree-node:nth-child(${i}) .object-label`, - frame: i => `.frames ul li:nth-child(${i})`, - frames: ".frames ul li", - gutter: i => `.CodeMirror-code *:nth-child(${i}) .CodeMirror-linenumber`, - menuitem: i => `menupopup menuitem:nth-child(${i})`, - pauseOnExceptions: ".pause-exceptions", - breakpoint: ".CodeMirror-code > .new-breakpoint", - highlightLine: ".CodeMirror-code > .highlight-line", - codeMirror: ".CodeMirror", - resume: ".resume.active", - stepOver: ".stepOver.active", - stepOut: ".stepOut.active", - stepIn: ".stepIn.active", - toggleBreakpoints: ".toggleBreakpoints", - prettyPrintButton: ".prettyPrint", - sourceFooter: ".source-footer", - sourceNode: i => `.sources-list .tree-node:nth-child(${i})`, - sourceNodes: ".sources-list .tree-node", - sourceArrow: i => `.sources-list .tree-node:nth-child(${i}) .arrow`, -}; - -function getSelector(elementName, ...args) { - let selector = selectors[elementName]; - if (!selector) { - throw new Error(`The selector ${elementName} is not defined`); - } - - if (typeof selector == "function") { - selector = selector(...args); - } - - return selector; -} - -function findElement(dbg, elementName, ...args) { - const selector = getSelector(elementName, ...args); - return findElementWithSelector(dbg, selector); -} - -function findElementWithSelector(dbg, selector) { - return dbg.win.document.querySelector(selector); -} - -function findAllElements(dbg, elementName, ...args) { - const selector = getSelector(elementName, ...args); - return dbg.win.document.querySelectorAll(selector); -} - -/** - * Simulates a mouse click in the debugger DOM. - * - * @memberof mochitest/helpers - * @param {Object} dbg - * @param {String} elementName - * @param {Array} args - * @return {Promise} - * @static - */ -function clickElement(dbg, elementName, ...args) { - const selector = getSelector(elementName, ...args); - return EventUtils.synthesizeMouseAtCenter( - findElementWithSelector(dbg, selector), - {}, - dbg.win - ); -} - -function rightClickElement(dbg, elementName, ...args) { - const selector = getSelector(elementName, ...args); - const doc = dbg.win.document; - return EventUtils.synthesizeMouseAtCenter( - doc.querySelector(selector), - {type: "contextmenu"}, - dbg.win - ); -} - -function selectMenuItem(dbg, index) { - // the context menu is in the toolbox window - const doc = dbg.toolbox.win.document; - - // there are several context menus, we want the one with the menu-api - const popup = doc.querySelector("menupopup[menu-api=\"true\"]"); - - const item = popup.querySelector(`menuitem:nth-child(${index})`); - return EventUtils.synthesizeMouseAtCenter(item, {}, dbg.toolbox.win ); -} - -/** - * Toggles the debugger call stack accordian. - * - * @memberof mochitest/actions - * @param {Object} dbg - * @return {Promise} - * @static - */ -function toggleCallStack(dbg) { - return findElement(dbg, "callStackHeader").click(); -} - -function toggleScopes(dbg) { - return findElement(dbg, "scopesHeader").click(); -} diff --git a/src/test/node-unit-tests.js b/src/test/node-unit-tests.js deleted file mode 100644 index c12fde1ddf..0000000000 --- a/src/test/node-unit-tests.js +++ /dev/null @@ -1,83 +0,0 @@ -"use strict"; // eslint-disable-line - -require("amd-loader"); -require("babel-register"); -const mock = require("mock-require"); - -const glob = require("glob").sync; -const path = require("path"); -const Mocha = require("mocha"); -const minimist = require("minimist"); - -const getConfig = require("../../bin/getConfig"); -const setConfig = require("devtools-config").setConfig; - -// Mock various functions. This allows tests to load files from a -// local directory easily. -const networkRequest = require("devtools-network-request"); -mock("devtools-network-request", networkRequest.stubNetworkRequest); -mock("../utils/prefs", { prefs: { clientSourceMapsEnabled: true }}); - -const baseWorkerURL = path.join(__dirname, "../../assets/build/"); -const packagesPath = path.join(__dirname, "../../packages"); - -const envConfig = getConfig(); -setConfig(Object.assign({}, envConfig, { baseWorkerURL })); - -const args = minimist(process.argv.slice(2), -{ boolean: ["ci", "dots"] }); - -const isCI = args.ci; -const useDots = args.dots; - -const webpack = require("webpack"); -const webpackConfig = require("../../webpack.config"); -delete webpackConfig.entry.bundle; - -// The source map worker is compiled with webpack (and mock-require -// doesn't work in workers) so mock it with an alias, and tweak a few -// things to make the stub fetcher work in node. -webpackConfig.resolve.alias["devtools-network-request"] = - path.resolve(packagesPath, "devtools-network-request/stubNetworkRequest.js"); - -webpackConfig.externals = [{ fs: "commonjs fs" }]; -webpackConfig.node = { __dirname: false }; - -global.Worker = require("workerjs"); - -// disable unecessary require calls -require.extensions[".css"] = () => {}; -require.extensions[".svg"] = () => {}; - -let testFiles; -if (args._.length) { - testFiles = args._.reduce((paths, p) => paths.concat(glob(p)), []); -} else { - testFiles = glob("src/actions/tests/*.js") - .concat(glob("src/reducers/tests/*.js")) - .concat(glob("src/utils/tests/*.js")) - .concat(glob("config/tests/*.js")); -} - -const mocha = new Mocha(); - -if (isCI) { - mocha.reporter("mocha-circleci-reporter"); -} else if (useDots) { - mocha.reporter("dot"); -} - -testFiles.forEach(file => mocha.addFile(file)); - -webpack(webpackConfig).run(function(_, stats) { - if (stats.compilation.errors.length) { - stats.compilation.errors.forEach(err => { - console.log(err.message); - }); - return; - } - - mocha.run(function(failures) { - process.exit(failures); - }); -}); diff --git a/src/test/utils/renderComponentFromFixture.js b/src/test/utils/renderComponentFromFixture.js deleted file mode 100644 index a28716f106..0000000000 --- a/src/test/utils/renderComponentFromFixture.js +++ /dev/null @@ -1,36 +0,0 @@ -const React = require("react"); -const { DOM: dom, createElement } = React; -const { Provider } = require("react-redux"); -const { combineReducers } = require("redux"); -const dehydrate = require("../../utils/dehydrate-state"); - -const fixtures = require("../fixtures"); -const configureStore = require("../../utils/create-store"); -const reducers = require("../../reducers"); - -function createStore(state = {}) { - return configureStore({})(combineReducers(reducers), state); -} - -function getData(fixtureName) { - const fixture = fixtures[fixtureName]; - - if (!fixture) { - throw new Error(`Fixture ${fixtureName} not found`); - } - - return dehydrate(fixture); -} - -function renderComponentFromFixture(Component, fixtureName, - { style = {}}) { - const data = getData(fixtureName); - const store = createStore(data); - - return dom.div( - { className: "theme-light", style }, - createElement(Provider, { store }, Component) - ); -} - -module.exports = renderComponentFromFixture; diff --git a/src/types.js b/src/types.js deleted file mode 100644 index 0405ad6114..0000000000 --- a/src/types.js +++ /dev/null @@ -1,125 +0,0 @@ -// @flow - -/** - * Flow types - * @module types - */ - -export type Why = { - type: string -} - -export type Pause = { - frames: Frame[], - why: Why -} - -export type Expression = { - id: number, - input: string -} - -export type Grip = { - actor: string, - class: string, - extensible: boolean, - frozen: boolean, - isGlobal: boolean, - ownPropertyLength: number, - preview: { - kind: string, - url: string - }, - sealed: boolean, - type: string -} - -/** - * Source - * - * @memberof types - * @static - */ -export type Source = { - id: string, - url?: string, - sourceMapURL?: string -}; - -/** - * Source File Location - * - * @memberof actions/types - * @static - */ -export type Location = { - sourceId: string, - line: number, - column?: number -}; - -/** - * Breakpoint - * - * @memberof actions/types - * @static - */ -export type Breakpoint = { - id: string, - location: Location, - loading: boolean, - disabled: boolean, - text: string, - condition: ?string, -}; - -/** - * Source Text - * - * @memberof actions/types - * @static - */ -export type SourceText = { - id: string, - text: string, - contentType: string -}; - -/** - * Scope - * @memberof types - * @static - */ -export type Scope = { - actor: string, - parent: Scope, - bindings: { - // FIXME Define these types more clearly - arguments: Array, - variables: Object - }, - function: { - actor: string, - class: string, - displayName: string, - location: Location, - // FIXME Define this type more clearly - parameterNames: Array - }, - type: string -} - -/** - * Frame - * @memberof types - * @static - */ -export type Frame = { - id: string, - displayName: string, - location: Location, - source: Source, - scope: Scope, - // FIXME Define this type more clearly - this: Object - } diff --git a/src/utils/DevToolsUtils.js b/src/utils/DevToolsUtils.js deleted file mode 100644 index d162b6f1c3..0000000000 --- a/src/utils/DevToolsUtils.js +++ /dev/null @@ -1,16 +0,0 @@ -const assert = require("./assert"); - -function reportException(who, exception) { - let msg = `${who} threw an exception: `; - console.error(msg, exception); -} - -function executeSoon(fn) { - setTimeout(fn, 0); -} - -module.exports = { - reportException, - executeSoon, - assert -}; diff --git a/src/utils/assert.js b/src/utils/assert.js deleted file mode 100644 index 4fcbf14193..0000000000 --- a/src/utils/assert.js +++ /dev/null @@ -1,9 +0,0 @@ -// @flow - -function assert(condition: boolean, message: string) { - if (!condition) { - throw new Error(`Assertion failure: ${message}`); - } -} - -module.exports = assert; diff --git a/src/utils/client.js b/src/utils/client.js deleted file mode 100644 index 4ac948eb89..0000000000 --- a/src/utils/client.js +++ /dev/null @@ -1,47 +0,0 @@ -const { createSource, firefox } = require("devtools-client-adapters"); - -function onFirefoxConnect(actions) { - const tabTarget = firefox.getTabTarget(); - const threadClient = firefox.getThreadClient(); - - if (!tabTarget) { - return; - } - - tabTarget.on("will-navigate", actions.willNavigate); - tabTarget.on("navigate", actions.navigated); - - // In Firefox, we need to initially request all of the sources. This - // usually fires off individual `newSource` notifications as the - // debugger finds them, but there may be existing sources already in - // the debugger (if it's paused already, or if loading the page from - // bfcache) so explicity fire `newSource` events for all returned - // sources. - return threadClient.getSources().then(({ sources }) => { - actions.newSources(sources.map(createSource)); - - // If the threadClient is already paused, make sure to show a - // paused state. - const pausedPacket = threadClient.getLastPausePacket(); - if (pausedPacket) { - firefox.clientEvents.paused(null, pausedPacket); - } - }); -} - -function onConnect(connection, actions) { - // NOTE: the landing page does not connect to a JS process - if (!connection) { - return; - } - - const { tab } = connection; - if (tab.clientType == "firefox") { - return onFirefoxConnect(actions); - } -} - -module.exports = { - onFirefoxConnect, - onConnect -}; diff --git a/src/utils/create-store.js b/src/utils/create-store.js deleted file mode 100644 index bd767bff89..0000000000 --- a/src/utils/create-store.js +++ /dev/null @@ -1,76 +0,0 @@ -// @flow - -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -/* global window */ - -/** - * Redux store utils - * @module utils/create-store - */ - -const { createStore, applyMiddleware } = require("redux"); -const { waitUntilService } = require("./redux/middleware/wait-service"); -const { log } = require("./redux/middleware/log"); -const { history } = require("./redux/middleware/history"); -const { promise } = require("./redux/middleware/promise"); -const { thunk } = require("./redux/middleware/thunk"); - -/** - * @memberof utils/create-store - * @static - */ -type ReduxStoreOptions = { - makeThunkArgs?: Function, - history?: boolean, - middleware?: Function[], - log?: boolean -}; - -/** - * This creates a dispatcher with all the standard middleware in place - * that all code requires. It can also be optionally configured in - * various ways, such as logging and recording. - * - * @param {object} opts: - * - log: log all dispatched actions to console - * - history: an array to store every action in. Should only be - * used in tests. - * - middleware: array of middleware to be included in the redux store - * @memberof utils/create-store - * @static - */ -const configureStore = (opts: ReduxStoreOptions = {}) => { - const middleware = [ - thunk(opts.makeThunkArgs), - promise, - - // Order is important: services must go last as they always - // operate on "already transformed" actions. Actions going through - // them shouldn't have any special fields like promises, they - // should just be normal JSON objects. - waitUntilService - ]; - - if (opts.history) { - middleware.push(history(opts.history)); - } - - if (opts.middleware) { - opts.middleware.forEach(fn => middleware.push(fn)); - } - - if (opts.log) { - middleware.push(log); - } - - // Hook in the redux devtools browser extension if it exists - const devtoolsExt = typeof window === "object" && window.devToolsExtension ? - window.devToolsExtension() : - f => f; - - return applyMiddleware(...middleware)(devtoolsExt(createStore)); -}; - -module.exports = configureStore; diff --git a/src/utils/defer.js b/src/utils/defer.js deleted file mode 100644 index b24bc4ad43..0000000000 --- a/src/utils/defer.js +++ /dev/null @@ -1,26 +0,0 @@ -/* flow */ - -export type deferred = { - resolve: (result: any) => void, - reject: (result: any) => void, - promise: Promise -}; - -function defer(): deferred { - let resolve: (result: any) => void; - let reject: (result: any) => void; - let promise = new Promise(function( - innerResolve: (result: any) => void, - innerReject: (result: any) => void - ) { - resolve = innerResolve; - reject = innerReject; - }); - return { - resolve: resolve, - reject: reject, - promise: promise - }; -} - -module.exports = defer; diff --git a/src/utils/dehydrate-state.js b/src/utils/dehydrate-state.js deleted file mode 100644 index 88279d6475..0000000000 --- a/src/utils/dehydrate-state.js +++ /dev/null @@ -1,28 +0,0 @@ -const I = require("immutable"); -const { fromJS } = I; -const SourcesState = require("../reducers/sources").State; -const BreakpointsState = require("../reducers/breakpoints").State; - -function dehydrate(jsState) { - return { - sources: SourcesState({ - sources: fromJS(jsState.sources.sources), - selectedSource: fromJS(jsState.sources.selectedSource), - sourcesText: fromJS(jsState.sources.sourcesText), - tabs: fromJS(jsState.sources.tabs) - }), - breakpoints: jsState.breakpoints ? BreakpointsState({ - breakpoints: I.Map(jsState.breakpoints.breakpoints) - }) : null, - eventListeners: fromJS(jsState.eventListeners), - pause: jsState.pause ? I.Map({ - pause: fromJS(jsState.pause.pause), - loadedObjects: fromJS(jsState.pause.loadedObjects), - frames: jsState.pause.frames, - selectedFrameId: jsState.pause.selectedFrameId - }) : null, - tabs: fromJS(jsState.tabs) - }; -} - -module.exports = dehydrate; diff --git a/src/utils/editor.js b/src/utils/editor.js deleted file mode 100644 index 35bcfc6cff..0000000000 --- a/src/utils/editor.js +++ /dev/null @@ -1,24 +0,0 @@ -const { isPretty, isJavaScript } = require("./source"); -const { isOriginalId } = require("../utils/source-map"); - -function shouldShowPrettyPrint(selectedSource) { - const _isPretty = isPretty(selectedSource); - const _isJavaScript = isJavaScript(selectedSource.url); - const isOriginal = isOriginalId(selectedSource.id); - const hasSourceMap = selectedSource.sourceMapURL; - - if (_isPretty || isOriginal || hasSourceMap || !_isJavaScript) { - return false; - } - - return true; -} - -function shouldShowFooter(selectedSource) { - return shouldShowPrettyPrint(selectedSource); -} - -module.exports = { - shouldShowPrettyPrint, - shouldShowFooter -}; diff --git a/src/utils/fromJS.js b/src/utils/fromJS.js deleted file mode 100644 index ff61c7323a..0000000000 --- a/src/utils/fromJS.js +++ /dev/null @@ -1,50 +0,0 @@ -// @flow - -/** - * Immutable JS conversion utils - * @deprecated - * @module utils/fromJS - */ - -const Immutable = require("immutable"); - -/** - * When our app state is fully typed, we should be able to get rid of - * this function. This is only temporarily necessary to support - * converting typed objects to immutable.js, which usually happens in - * reducers. - * - * @memberof utils/fromJS - * @static - */ -function fromJS(value: any) : any { - if (Array.isArray(value)) { - return Immutable.Seq(value).map(fromJS).toList(); - } - if (value && value.constructor.meta) { - // This adds support for tcomb objects which are native JS objects - // but are not "plain", so the above checks fail. Since they - // behave the same we can use the same constructors, but we need - // special checks for them. - const kind = value.constructor.meta.kind; - if (kind === "struct") { - return Immutable.Seq(value).map(fromJS).toMap(); - } else if (kind === "list") { - return Immutable.Seq(value).map(fromJS).toList(); - } - } - - // If it's a primitive type, just return the value. Note `==` check - // for null, which is intentionally used to match either `null` or - // `undefined`. - if (value == null || (typeof value !== "object")) { - return value; - } - - // Otherwise, treat it like an object. We can't reliably detect if - // it's a plain object because we might be objects from other JS - // contexts so `Object !== Object`. - return Immutable.Seq(value).map(fromJS).toMap(); -} - -module.exports = fromJS; diff --git a/src/utils/log.js b/src/utils/log.js deleted file mode 100644 index 444f0c3c63..0000000000 --- a/src/utils/log.js +++ /dev/null @@ -1,13 +0,0 @@ -/* @flow */ - -const { isDevelopment } = require("devtools-config"); - -function log(...args: any[]) { - if (!isDevelopment()) { - return; - } - - console.log.apply(console, ["[log]", ...args]); -} - -module.exports = log; diff --git a/src/utils/makeRecord.js b/src/utils/makeRecord.js deleted file mode 100644 index 68b08d2fa1..0000000000 --- a/src/utils/makeRecord.js +++ /dev/null @@ -1,41 +0,0 @@ -// @flow - -/** - * When Flow 0.29 is released (very soon), we can use this Record type - * instead of the builtin immutable.js Record type. This is better - * because all the fields are actually typed, unlike the builtin one. - * This depends on a performance fix that will go out in 0.29 though; - * @module utils/makeRecord - */ - -const I = require("immutable"); - -/** - * @memberof utils/makeRecord - * @static - */ -export type Record = { - get(key: $Keys): A; - set(key: $Keys, value: A): Record; - setIn(keyPath: Array, ...iterables: Array): Record; - merge(values: $Shape): Record; - mergeIn(keyPath: Array, ...iterables: Array): Record; - delete(key: $Keys, value: A): Record; - deleteIn(keyPath: Array, ...iterables: Array): Record; -} & T; - -/** - * Make an immutable record type - * - * @param spec - the keys and their default values - * @return a state record factory function - * @memberof utils/makeRecord - * @static - */ -function makeRecord( - spec: T & Object -): (init: $Shape) => Record { - return I.Record(spec); -} - -module.exports = makeRecord; diff --git a/src/utils/menu.js b/src/utils/menu.js deleted file mode 100644 index 824291312e..0000000000 --- a/src/utils/menu.js +++ /dev/null @@ -1,81 +0,0 @@ -const { Menu, MenuItem } = require("devtools-sham-modules"); -const { isFirefoxPanel } = require("devtools-config"); - -function createPopup(doc) { - let popup = doc.createElement("menupopup"); - - if (popup.openPopupAtScreen) { - return popup; - } - - function preventDefault(e) { - e.preventDefault(); - e.returnValue = false; - } - - let mask = document.querySelector("#contextmenu-mask"); - if (!mask) { - mask = doc.createElement("div"); - mask.id = "contextmenu-mask"; - document.body.appendChild(mask); - } - - mask.onclick = () => popup.hidePopup(); - - popup.openPopupAtScreen = function(clientX, clientY) { - this.style.setProperty("left", `${clientX}px`); - this.style.setProperty("top", `${clientY}px`); - mask = document.querySelector("#contextmenu-mask"); - window.onwheel = preventDefault; - mask.classList.add("show"); - this.dispatchEvent(new Event("popupshown")); - this.popupshown; - }; - - popup.hidePopup = function() { - this.remove(); - mask = document.querySelector("#contextmenu-mask"); - mask.classList.remove("show"); - window.onwheel = null; - }; - - return popup; -} - -if (!isFirefoxPanel()) { - Menu.prototype.createPopup = createPopup; -} - -function onShown(menu, popup) { - popup.childNodes.forEach((menuitem, index) => { - const item = menu.items[index]; - menuitem.onclick = () => { - item.click(); - popup.hidePopup(); - }; - }); -} - -function showMenu(e, items) { - const menu = new Menu(); - items.forEach(item => menu.append(new MenuItem(item))); - - if (isFirefoxPanel()) { - return menu.popup(e.screenX, e.screenY, { doc: window.parent.document }); - } - - menu.on("open", (_, popup) => onShown(menu, popup)); - return menu.popup(e.clientX, e.clientY, { doc: document }); -} - -function buildMenu(items) { - return items.map(itm => { - const hide = typeof itm.hidden === "function" ? itm.hidden() : itm.hidden; - return hide ? null : itm.item; - }).filter(itm => itm !== null); -} - -module.exports = { - showMenu, - buildMenu -}; diff --git a/src/utils/path.js b/src/utils/path.js deleted file mode 100644 index 2cd07f0f53..0000000000 --- a/src/utils/path.js +++ /dev/null @@ -1,26 +0,0 @@ -// @flow - -function basename(path: string) { - return path.split("/").pop(); -} - -function dirname(path: string) { - const idx = path.lastIndexOf("/"); - return path.slice(0, idx); -} - -function isURL(str: string) { - return str.indexOf("://") !== -1; -} - -function isAbsolute(str: string) { - return str[0] === "/"; -} - -function join(base: string, dir: string) { - return `${base}/${dir}`; -} - -module.exports = { - basename, dirname, isURL, isAbsolute, join -}; diff --git a/src/utils/pause.js b/src/utils/pause.js deleted file mode 100644 index 024fd94722..0000000000 --- a/src/utils/pause.js +++ /dev/null @@ -1,24 +0,0 @@ -// @flow -const { Frame } = require("../tcomb-types"); -const { getOriginalLocation } = require("./source-map"); - -import type { Frame as FrameType } from "../types"; - -function updateFrameLocations(frames: FrameType[]): Promise { - if (!frames) { - return Promise.resolve(frames); - } - return Promise.all( - frames.map(frame => { - return getOriginalLocation(frame.location).then(loc => { - return Frame.update(frame, { - $merge: { location: loc } - }); - }); - }) - ); -} - -module.exports = { - updateFrameLocations -}; diff --git a/src/utils/prefs.js b/src/utils/prefs.js deleted file mode 100644 index 93e385b261..0000000000 --- a/src/utils/prefs.js +++ /dev/null @@ -1,13 +0,0 @@ -var { PrefsHelper } = require("devtools-sham-modules"); -const { Services: { pref }} = require("devtools-modules"); -const { isDevelopment } = require("devtools-config"); - -if (isDevelopment()) { - pref("devtools.debugger.client-source-maps-enabled", true); -} - -const prefs = new PrefsHelper("devtools", { - clientSourceMapsEnabled: ["Bool", "debugger.client-source-maps-enabled"], -}); - -module.exports = { prefs }; diff --git a/src/utils/pretty-print-worker.js b/src/utils/pretty-print-worker.js deleted file mode 100644 index 912e8142e8..0000000000 --- a/src/utils/pretty-print-worker.js +++ /dev/null @@ -1,53 +0,0 @@ -const prettyFast = require("pretty-fast"); -const assert = require("./assert"); - -function prettyPrint({ url, indent, source }) { - try { - const prettified = prettyFast(source, { - url: url, - indent: " ".repeat(indent) - }); - - return { - code: prettified.code, - mappings: prettified.map._mappings - }; - } catch (e) { - return new Error(`${e.message}\n${e.stack}`); - } -} - -function invertMappings(mappings) { - return mappings._array.map(m => { - let mapping = { - generated: { - line: m.originalLine, - column: m.originalColumn - } - }; - if (m.source) { - mapping.source = m.source; - mapping.original = { - line: m.generatedLine, - column: m.generatedColumn - }; - mapping.name = m.name; - } - return mapping; - }); -} - -self.onmessage = function(msg) { - const { id, args } = msg.data; - assert(msg.data.method === "prettyPrint", - "Method must be `prettyPrint`"); - - try { - let { code, mappings } = prettyPrint(args[0]); - self.postMessage({ id, response: { - code, mappings: invertMappings(mappings) - }}); - } catch (e) { - self.postMessage({ id, error: e }); - } -}; diff --git a/src/utils/pretty-print.js b/src/utils/pretty-print.js deleted file mode 100644 index 3d4f6c155a..0000000000 --- a/src/utils/pretty-print.js +++ /dev/null @@ -1,36 +0,0 @@ -const { getValue } = require("devtools-config"); -const { workerTask } = require("./utils"); -const { isJavaScript } = require("./source"); -const assert = require("./assert"); - -let prettyPrintWorker = new Worker( - `${getValue("baseWorkerURL")}pretty-print-worker.js` -); - -function destroyWorker() { - prettyPrintWorker.terminate(); - prettyPrintWorker = null; -} - -const _prettyPrint = workerTask(prettyPrintWorker, "prettyPrint"); - -async function prettyPrint({ source, sourceText, url }) { - const contentType = sourceText ? sourceText.contentType : null; - const indent = 2; - - assert( - isJavaScript(source.url, contentType), - "Can't prettify non-javascript files." - ); - - return await _prettyPrint({ - url, - indent, - source: sourceText.text - }); -} - -module.exports = { - prettyPrint, - destroyWorker -}; diff --git a/src/utils/redux-devtools.js b/src/utils/redux-devtools.js deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/utils/redux/middleware/history.js b/src/utils/redux/middleware/history.js deleted file mode 100644 index 986bc6f49d..0000000000 --- a/src/utils/redux/middleware/history.js +++ /dev/null @@ -1,22 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -const { isDevelopment } = require("devtools-config"); - -/** - * A middleware that stores every action coming through the store in the passed - * in logging object. Should only be used for tests, as it collects all - * action information, which will cause memory bloat. - */ -exports.history = (log = []) => ({ dispatch, getState }) => { - if (isDevelopment()) { - console.warn("Using history middleware stores all actions in state for " + - "testing and devtools is not currently running in test " + - "mode. Be sure this is intentional."); - } - return next => action => { - log.push(action); - next(action); - }; -}; diff --git a/src/utils/redux/middleware/log.js b/src/utils/redux/middleware/log.js deleted file mode 100644 index 8fa9da4c6f..0000000000 --- a/src/utils/redux/middleware/log.js +++ /dev/null @@ -1,14 +0,0 @@ -/** - * A middleware that logs all actions coming through the system - * to the console. - */ -function log({ dispatch, getState }) { - return next => action => { - const actionText = JSON.stringify(action, null, 2); - const truncatedActionText = actionText.slice(0, 1000) + "..."; - console.log(`[DISPATCH ${action.type}]`, action, truncatedActionText); - next(action); - }; -} - -exports.log = log; diff --git a/src/utils/redux/middleware/promise.js b/src/utils/redux/middleware/promise.js deleted file mode 100644 index a3df99af6d..0000000000 --- a/src/utils/redux/middleware/promise.js +++ /dev/null @@ -1,57 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -const defer = require("../../defer"); -const { entries, toObject } = require("../../utils"); -const { executeSoon } = require("../../DevToolsUtils"); - -const PROMISE = exports.PROMISE = "@@dispatch/promise"; -let seqIdVal = 1; - -function seqIdGen() { - return seqIdVal++; -} - -function promiseMiddleware({ dispatch, getState }) { - return next => action => { - if (!(PROMISE in action)) { - return next(action); - } - - const promiseInst = action[PROMISE]; - const seqId = seqIdGen().toString(); - - // Create a new action that doesn't have the promise field and has - // the `seqId` field that represents the sequence id - action = Object.assign( - toObject(entries(action).filter(pair => pair[0] !== PROMISE)), { seqId } - ); - - dispatch(Object.assign({}, action, { status: "start" })); - - // Return the promise so action creators can still compose if they - // want to. - const deferred = defer(); - promiseInst.then(value => { - executeSoon(() => { - dispatch(Object.assign({}, action, { - status: "done", - value: value - })); - deferred.resolve(value); - }); - }, error => { - executeSoon(() => { - dispatch(Object.assign({}, action, { - status: "error", - error: error.message || error - })); - deferred.reject(error); - }); - }); - return deferred.promise; - }; -} - -exports.promise = promiseMiddleware; diff --git a/src/utils/redux/middleware/thunk.js b/src/utils/redux/middleware/thunk.js deleted file mode 100644 index c6f11aae7c..0000000000 --- a/src/utils/redux/middleware/thunk.js +++ /dev/null @@ -1,20 +0,0 @@ - -/** - * A middleware that allows thunks (functions) to be dispatched. If - * it's a thunk, it is called with an argument that contains - * `dispatch`, `getState`, and any additional args passed in via the - * middleware constructure. This allows the action to create multiple - * actions (most likely asynchronously). - */ -function thunk(makeArgs) { - return ({ dispatch, getState }) => { - const args = { dispatch, getState }; - - return next => action => { - return (typeof action === "function") - ? action(makeArgs ? makeArgs(args, getState()) : args) - : next(action); - }; - }; -} -exports.thunk = thunk; diff --git a/src/utils/redux/middleware/wait-service.js b/src/utils/redux/middleware/wait-service.js deleted file mode 100644 index 7336cc4574..0000000000 --- a/src/utils/redux/middleware/wait-service.js +++ /dev/null @@ -1,63 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/** - * A middleware which acts like a service, because it is stateful - * and "long-running" in the background. It provides the ability - * for actions to install a function to be run once when a specific - * condition is met by an action coming through the system. Think of - * it as a thunk that blocks until the condition is met. Example: - * - * ```js - * const services = { WAIT_UNTIL: require('wait-service').NAME }; - * - * { type: services.WAIT_UNTIL, - * predicate: action => action.type === constants.ADD_ITEM, - * run: (dispatch, getState, action) => { - * // Do anything here. You only need to accept the arguments - * // if you need them. `action` is the action that satisfied - * // the predicate. - * } - * } - * ``` - */ -const NAME = exports.NAME = "@@service/waitUntil"; - -function waitUntilService({ dispatch, getState }) { - let pending = []; - - function checkPending(action) { - let readyRequests = []; - let stillPending = []; - - // Find the pending requests whose predicates are satisfied with - // this action. Wait to run the requests until after we update the - // pending queue because the request handler may synchronously - // dispatch again and run this service (that use case is - // completely valid). - for (let request of pending) { - if (request.predicate(action)) { - readyRequests.push(request); - } else { - stillPending.push(request); - } - } - - pending = stillPending; - for (let request of readyRequests) { - request.run(dispatch, getState, action); - } - } - - return next => action => { - if (action.type === NAME) { - pending.push(action); - return null; - } - let result = next(action); - checkPending(action); - return result; - }; -} -exports.waitUntilService = waitUntilService; diff --git a/src/utils/source-documents.js b/src/utils/source-documents.js deleted file mode 100644 index 0d0d9eb51e..0000000000 --- a/src/utils/source-documents.js +++ /dev/null @@ -1,24 +0,0 @@ -let sourceDocs = {}; - -function getDocument(key) { - return sourceDocs[key]; -} - -function setDocument(key, doc) { - sourceDocs[key] = doc; -} - -function removeDocument(key) { - delete sourceDocs[key]; -} - -function clearDocuments() { - sourceDocs = {}; -} - -module.exports = { - getDocument, - setDocument, - removeDocument, - clearDocuments -}; diff --git a/src/utils/source-editor.js b/src/utils/source-editor.js deleted file mode 100644 index c0b85fa5bc..0000000000 --- a/src/utils/source-editor.js +++ /dev/null @@ -1,108 +0,0 @@ -/** - * CodeMirror source editor utils - * @module utils/source-editor - */ - -const CodeMirror = require("codemirror"); - -require("codemirror/lib/codemirror.css"); -require("codemirror/mode/javascript/javascript"); -require("codemirror/mode/htmlmixed/htmlmixed"); -require("../lib/codemirror-mozilla.css"); -require("codemirror/addon/search/searchcursor"); - -// Maximum allowed margin (in number of lines) from top or bottom of the editor -// while shifting to a line which was initially out of view. -const MAX_VERTICAL_OFFSET = 3; - -class SourceEditor { - constructor(opts) { - this.opts = opts; - } - - appendToLocalElement(node) { - this.editor = CodeMirror(node, this.opts); - } - - destroy() { - // No need to do anything. - } - - get codeMirror() { - return this.editor; - } - - setText(str) { - this.editor.setValue(str); - } - - getText() { - return this.editor.getValue(); - } - - setMode(value) { - this.editor.setOption("mode", value); - } - - /** - * Replaces the current document with a new source document - * @memberof utils/source-editor - */ - replaceDocument(doc) { - this.editor.swapDoc(doc); - } - - /** - * Creates a CodeMirror Document - * @returns CodeMirror.Doc - * @memberof utils/source-editor - */ - createDocument() { - return new CodeMirror.Doc(""); - } - - /** - * Aligns the provided line to either "top", "center" or "bottom" of the - * editor view with a maximum margin of MAX_VERTICAL_OFFSET lines from top or - * bottom. - * @memberof utils/source-editor - */ - alignLine(line, align = "top") { - let cm = this.editor; - let from = cm.lineAtHeight(0, "page"); - let to = cm.lineAtHeight(cm.getWrapperElement().clientHeight, "page"); - let linesVisible = to - from; - let halfVisible = Math.round(linesVisible / 2); - - // If the target line is in view, skip the vertical alignment part. - if (line <= to && line >= from) { - return; - } - - // Setting the offset so that the line always falls in the upper half - // of visible lines (lower half for bottom aligned). - // MAX_VERTICAL_OFFSET is the maximum allowed value. - let offset = Math.min(halfVisible, MAX_VERTICAL_OFFSET); - - let topLine = { - "center": Math.max(line - halfVisible, 0), - "bottom": Math.max(line - linesVisible + offset, 0), - "top": Math.max(line - offset, 0) - }[align || "top"] || offset; - - // Bringing down the topLine to total lines in the editor if exceeding. - topLine = Math.min(topLine, cm.lineCount()); - this.setFirstVisibleLine(topLine); - } - - /** - * Scrolls the view such that the given line number is the first visible line. - * @memberof utils/source-editor - */ - setFirstVisibleLine(line) { - let { top } = this.editor.charCoords({ line: line, ch: 0 }, "local"); - this.editor.scrollTo(0, top); - } -} - -module.exports = SourceEditor; diff --git a/src/utils/source-map-util.js b/src/utils/source-map-util.js deleted file mode 100644 index affb8373c8..0000000000 --- a/src/utils/source-map-util.js +++ /dev/null @@ -1,24 +0,0 @@ -// @flow - -const md5 = require("md5"); - -function originalToGeneratedId(originalId: string) { - const match = originalId.match(/(.*)\/originalSource/); - return match ? match[1] : ""; -} - -function generatedToOriginalId(generatedId: string, url: string) { - return `${generatedId}/originalSource-${md5(url)}`; -} - -function isOriginalId(id: string) { - return !!id.match(/\/originalSource/); -} - -function isGeneratedId(id: string) { - return !isOriginalId(id); -} - -module.exports = { - originalToGeneratedId, generatedToOriginalId, isOriginalId, isGeneratedId -}; diff --git a/src/utils/source-map-worker.js b/src/utils/source-map-worker.js deleted file mode 100644 index 86a7e76f7d..0000000000 --- a/src/utils/source-map-worker.js +++ /dev/null @@ -1,237 +0,0 @@ -// @flow - -/** - * Source Map Worker - * @module utils/source-map-worker - */ - -const networkRequest = require("devtools-network-request"); -const { parse } = require("url"); -const path = require("./path"); -const { SourceMapConsumer, SourceMapGenerator } = require("source-map"); -const { isJavaScript } = require("./source"); -const assert = require("./assert"); -const { - originalToGeneratedId, - generatedToOriginalId, - isGeneratedId, - isOriginalId -} = require("./source-map-util"); - -import type { Location, Source } from "../types"; -type Message = { - data: { - id: string, - method: string, - args: Array - } -} - -let sourceMapRequests = new Map(); -let sourceMapsEnabled = false; - -function clearSourceMaps() { - sourceMapRequests.clear(); -} - -function enableSourceMaps() { - sourceMapsEnabled = true; -} - -function _resolveSourceMapURL(source: Source) { - const { url = "", sourceMapURL = "" } = source; - if (path.isURL(sourceMapURL) || url == "") { - // If it's already a full URL or the source doesn't have a URL, - // don't resolve anything. - return sourceMapURL; - } else if (path.isAbsolute(sourceMapURL)) { - // If it's an absolute path, it should be resolved relative to the - // host of the source. - const { protocol = "", host = "" } = parse(url); - return `${protocol}//${host}${sourceMapURL}`; - } - // Otherwise, it's a relative path and should be resolved relative - // to the source. - return `${path.dirname(url)}/${sourceMapURL}`; -} - -/** - * Sets the source map's sourceRoot to be relative to the source map url. - * @memberof utils/source-map-worker - * @static - */ -function _setSourceMapRoot(sourceMap, absSourceMapURL, source) { - // No need to do this fiddling if we won't be fetching any sources over the - // wire. - if (sourceMap.hasContentsOfAllSources()) { - return; - } - - const base = path.dirname( - (absSourceMapURL.indexOf("data:") === 0 && source.url) ? - source.url : - absSourceMapURL - ); - - if (sourceMap.sourceRoot) { - sourceMap.sourceRoot = path.join(base, sourceMap.sourceRoot); - } else { - sourceMap.sourceRoot = base; - } - - return sourceMap; -} - -function _getSourceMap(generatedSourceId: string) - : ?Promise { - return sourceMapRequests.get(generatedSourceId); -} - -async function _resolveAndFetch(generatedSource: Source) : SourceMapConsumer { - // Fetch the sourcemap over the network and create it. - const sourceMapURL = _resolveSourceMapURL(generatedSource); - const fetched = await networkRequest( - sourceMapURL, { loadFromCache: false } - ); - - // Create the source map and fix it up. - const map = new SourceMapConsumer(fetched.content); - _setSourceMapRoot(map, sourceMapURL, generatedSource); - return map; -} - -function _fetchSourceMap(generatedSource: Source) { - const existingRequest = sourceMapRequests.get(generatedSource.id); - if (existingRequest) { - // If it has already been requested, return the request. Make sure - // to do this even if sourcemapping is turned off, because - // pretty-printing uses sourcemaps. - // - // An important behavior here is that if it's in the middle of - // requesting it, all subsequent calls will block on the initial - // request. - return existingRequest; - } else if (!generatedSource.sourceMapURL || !sourceMapsEnabled) { - return Promise.resolve(null); - } - - // Fire off the request, set it in the cache, and return it. - // Suppress any errors and just return null (ignores bogus - // sourcemaps). - const req = _resolveAndFetch(generatedSource).catch(() => null); - sourceMapRequests.set(generatedSource.id, req); - return req; -} - -async function getOriginalURLs(generatedSource) { - const map = await _fetchSourceMap(generatedSource); - return map && map.sources; -} - -async function getGeneratedLocation(location: Location, originalSource: Source) - : Promise { - if (!isOriginalId(location.sourceId)) { - return location; - } - - const generatedSourceId = originalToGeneratedId(location.sourceId); - const map = await _getSourceMap(generatedSourceId); - if (!map) { - return location; - } - - const { line, column } = map.generatedPositionFor({ - source: originalSource.url, - line: location.line, - column: location.column == null ? 0 : location.column - }); - - return { - sourceId: generatedSourceId, - line: line, - // Treat 0 as no column so that line breakpoints work correctly. - column: column === 0 ? undefined : column - }; -} - -async function getOriginalLocation(location: Location) { - if (!isGeneratedId(location.sourceId)) { - return location; - } - - const map = await _getSourceMap(location.sourceId); - if (!map) { - return location; - } - - const { source: url, line, column } = map.originalPositionFor({ - line: location.line, - column: location.column == null ? Infinity : location.column - }); - - if (url == null) { - // No url means the location didn't map. - return location; - } - - return { - sourceId: generatedToOriginalId(location.sourceId, url), - line, - column - }; -} - -async function getOriginalSourceText(originalSource: Source) { - assert(isOriginalId(originalSource.id), - "Source is not an original source"); - - const generatedSourceId = originalToGeneratedId(originalSource.id); - const map = await _getSourceMap(generatedSourceId); - if (!map) { - return null; - } - - let text = map.sourceContentFor(originalSource.url); - if (!text) { - text = (await networkRequest( - originalSource.url, { loadFromCache: false } - )).content; - } - - return { - text, - contentType: isJavaScript(originalSource.url || "") ? - "text/javascript" : - "text/plain" - }; -} - -function applySourceMap(generatedId, url, code, mappings) { - const generator = new SourceMapGenerator({ file: url }); - mappings.forEach(mapping => generator.addMapping(mapping)); - generator.setSourceContent(url, code); - - const map = SourceMapConsumer(generator.toJSON()); - sourceMapRequests.set(generatedId, Promise.resolve(map)); -} - -const publicInterface = { - getOriginalURLs, - getGeneratedLocation, - getOriginalLocation, - getOriginalSourceText, - enableSourceMaps, - applySourceMap, - clearSourceMaps -}; - -self.onmessage = function(msg: Message) { - const { id, method, args } = msg.data; - const response = publicInterface[method].apply(undefined, args); - if (response instanceof Promise) { - response.then(val => self.postMessage({ id, response: val }), - err => self.postMessage({ id, error: err })); - } else { - self.postMessage({ id, response }); - } -}; diff --git a/src/utils/source-map.js b/src/utils/source-map.js deleted file mode 100644 index ba185d1ee3..0000000000 --- a/src/utils/source-map.js +++ /dev/null @@ -1,61 +0,0 @@ -// @flow - -const { getValue } = require("devtools-config"); -const { workerTask } = require("./utils"); -const { - originalToGeneratedId, - generatedToOriginalId, - isGeneratedId, - isOriginalId -} = require("./source-map-util"); -const { prefs } = require("./prefs"); - -let sourceMapWorker; -function restartWorker() { - if (sourceMapWorker) { - sourceMapWorker.terminate(); - } - sourceMapWorker = new Worker( - `${getValue("baseWorkerURL")}source-map-worker.js` - ); - - sourceMapWorker.postMessage({ id: 0, method: "enableSourceMaps" }); -} -restartWorker(); - -function destroyWorker() { - if (sourceMapWorker) { - sourceMapWorker.terminate(); - sourceMapWorker = null; - } -} - -function shouldSourceMap(): boolean { - return prefs.clientSourceMapsEnabled; -} - -const getOriginalURLs = workerTask(sourceMapWorker, "getOriginalURLs"); -const getGeneratedLocation = workerTask(sourceMapWorker, - "getGeneratedLocation"); -const getOriginalLocation = workerTask(sourceMapWorker, - "getOriginalLocation"); -const getOriginalSourceText = workerTask(sourceMapWorker, - "getOriginalSourceText"); -const applySourceMap = workerTask(sourceMapWorker, "applySourceMap"); -const clearSourceMaps = workerTask(sourceMapWorker, "clearSourceMaps"); - -module.exports = { - originalToGeneratedId, - generatedToOriginalId, - isGeneratedId, - isOriginalId, - - getOriginalURLs, - getGeneratedLocation, - getOriginalLocation, - getOriginalSourceText, - applySourceMap, - clearSourceMaps, - destroyWorker, - shouldSourceMap -}; diff --git a/src/utils/source-search.js b/src/utils/source-search.js deleted file mode 100644 index c31bd1de34..0000000000 --- a/src/utils/source-search.js +++ /dev/null @@ -1,200 +0,0 @@ -const { escapeRegExp } = require("lodash"); -/** - * These functions implement search within the debugger. Since - * search in the debugger is different from other components, - * we can't use search.js CodeMirror addon. This is a slightly - * modified version of that addon. Depends on searchcursor.js. - * @module utils/source-search - */ - -/** - * @memberof utils/source-search - * @static - */ -function SearchState() { - this.posFrom = this.posTo = this.query = null; - this.overlay = null; -} - -/** - * @memberof utils/source-search - * @static - */ -function getSearchState(cm) { - return cm.state.search || (cm.state.search = new SearchState()); -} - -/** - * @memberof utils/source-search - * @static - */ -function getSearchCursor(cm, query, pos) { - // If the query string is all lowercase, do a case insensitive search. - return cm.getSearchCursor(query, pos, - typeof query == "string" && query == query.toLowerCase()); -} - -/** - * Ignore doing outline matches for less than 3 whitespaces - * - * @memberof utils/source-search - * @static - */ -function ignoreWhiteSpace(str) { - return /^\s{0,2}$/.test(str) ? "(?!\s*.*)" : str; -} - -/** - * This returns a mode object used by CoeMirror's addOverlay function - * to parse and style tokens in the file. - * The mode object contains a tokenizer function (token) which takes - * a character stream as input, advances it past a token, and returns - * a style for that token. For more details see - * https://codemirror.net/doc/manual.html#modeapi - * - * @memberof utils/source-search - * @static - */ -function searchOverlay(query) { - query = new RegExp(escapeRegExp(ignoreWhiteSpace(query)), "g"); - return { - token: function(stream) { - query.lastIndex = stream.pos; - let match = query.exec(stream.string); - if (match && match.index == stream.pos) { - stream.pos += match[0].length || 1; - return "selecting"; - } else if (match) { - stream.pos = match.index; - } else { - stream.skipToEnd(); - } - } - }; -} - -/** - * @memberof utils/source-search - * @static - */ -function startSearch(cm, state, query) { - cm.removeOverlay(state.overlay); - state.overlay = searchOverlay(query); - cm.addOverlay(state.overlay, { opaque: false }); -} - -/** - * If there's a saved search, selects the next results. - * Otherwise, creates a new search and selects the first - * result. - * - * @memberof utils/source-search - * @static - */ -function doSearch(ctx, rev, query) { - let { cm } = ctx; - let state = getSearchState(cm); - - if (state.query) { - searchNext(ctx, rev); - return; - } - - cm.operation(function() { - if (state.query) { - return; - } - startSearch(cm, state, query); - state.query = query; - state.posFrom = state.posTo = { line: 0, ch: 0 }; - searchNext(ctx, rev); - }); -} - -/** - * Selects the next result of a saved search. - * - * @memberof utils/source-search - * @static - */ -function searchNext(ctx, rev) { - let { cm, ed } = ctx; - cm.operation(function() { - let state = getSearchState(cm); - let cursor = getSearchCursor(cm, state.query, - rev ? state.posFrom : state.posTo); - - if (!cursor.find(rev)) { - cursor = getSearchCursor(cm, state.query, rev ? - { line: cm.lastLine(), ch: null } : { line: cm.firstLine(), ch: 0 }); - if (!cursor.find(rev)) { - return; - } - } - - ed.alignLine(cursor.from().line, "center"); - cm.setSelection(cursor.from(), cursor.to()); - state.posFrom = cursor.from(); - state.posTo = cursor.to(); - }); -} - -/** - * Remove overlay. - * - * @memberof utils/source-search - * @static - */ -function removeOverlay(ctx) { - let state = getSearchState(ctx.cm); - ctx.cm.removeOverlay(state.overlay); -} - -/** - * Clears the currently saved search. - * - * @memberof utils/source-search - * @static - */ -function clearSearch(cm) { - let state = getSearchState(cm); - - if (!state.query) { - return; - } - cm.removeOverlay(state.overlay); - state.query = null; -} - -/** - * Starts a new search. - * - * @memberof utils/source-search - * @static - */ -function find(ctx, query) { - clearSearch(ctx.cm); - doSearch(ctx, false, query); -} - -/** - * Finds the next item based on the currently saved search. - * - * @memberof utils/source-search - * @static - */ -function findNext(ctx, query) { - doSearch(ctx, false, query); -} - -/** - * Finds the previous item based on the currently saved search. - * - * @memberof utils/source-search - * @static - */ -function findPrev(ctx, query) { - doSearch(ctx, true, query); -} - -module.exports = { find, findNext, findPrev, removeOverlay }; diff --git a/src/utils/source.js b/src/utils/source.js deleted file mode 100644 index 4e08a05c6b..0000000000 --- a/src/utils/source.js +++ /dev/null @@ -1,85 +0,0 @@ -// @flow - -/** - * Utils for working with Source URLs - * @module utils/source - */ - -const { endTruncateStr } = require("./utils"); -const { basename } = require("../utils/path"); - -import type { Source } from "../types"; - -/** - * Trims the query part or reference identifier of a url string, if necessary. - * - * @memberof utils/source - * @static - */ -function trimUrlQuery(url: string): string { - let length = url.length; - let q1 = url.indexOf("?"); - let q2 = url.indexOf("&"); - let q3 = url.indexOf("#"); - let q = Math.min(q1 != -1 ? q1 : length, - q2 != -1 ? q2 : length, - q3 != -1 ? q3 : length); - - return url.slice(0, q); -} - -/** - * Returns true if the specified url and/or content type are specific to - * javascript files. - * - * @return boolean - * True if the source is likely javascript. - * - * @memberof utils/source - * @static - */ -function isJavaScript(url: string, contentType: string = ""): boolean { - return (url && /\.(jsm|js)?$/.test(trimUrlQuery(url))) || - contentType.includes("javascript"); -} - -/** - * @memberof utils/source - * @static - */ -function isPretty(source: Source): boolean { - return source.url ? /formatted$/.test(source.url) : false; -} - -/** - * @memberof utils/source - * @static - */ -function getPrettySourceURL(url: string): string { - return `${url}:formatted`; -} - -/** - * Show a source url's filename. - * If the source does not have a url, use the source id. - * - * @memberof utils/source - * @static - */ -function getFilename(source: Source) { - const { url, id } = source; - if (!url) { - const sourceId = id.split("/")[1]; - return `SOURCE${sourceId}`; - } - - const name = basename(source.url || "") || "(index)"; - return endTruncateStr(name, 50); -} - -module.exports = { - isJavaScript, - isPretty, - getPrettySourceURL, - getFilename -}; diff --git a/src/utils/sources-tree.js b/src/utils/sources-tree.js deleted file mode 100644 index 9c85739cec..0000000000 --- a/src/utils/sources-tree.js +++ /dev/null @@ -1,275 +0,0 @@ -// @flow - -/** - * Utils for Sources Tree Component - * @module utils/sources-tree - */ - -const { parse } = require("url"); -const { assert } = require("./DevToolsUtils"); -const { isPretty } = require("./source"); -const merge = require("lodash/merge"); - -const IGNORED_URLS = ["debugger eval code", "XStringBundle"]; - -/** - * Temporary Source type to be used only within this module - * TODO: Replace with real Source type definition when refactoring types - * @memberof utils/sources-tree - * @static - */ -type TmpSource = { get: (key: string) => string, toJS: Function }; - -/** - * TODO: createNode is exported so this type could be useful to other modules - * @memberof utils/sources-tree - * @static - */ -type Node = { name: any, path: any, contents?: any }; - -/** - * @memberof utils/sources-tree - * @static - */ -function nodeHasChildren(item: Node): boolean { - return Array.isArray(item.contents); -} - -/** - * @memberof utils/sources-tree - * @static - */ -function createNode(name: any, path: any, contents?: any): Node { - return { - name, - path, - contents: contents || null - }; -} - -/** - * @memberof utils/sources-tree - * @static - */ -function createParentMap(tree: any): WeakMap { - const map = new WeakMap(); - - function _traverse(subtree) { - if (nodeHasChildren(subtree)) { - for (let child of subtree.contents) { - map.set(child, subtree); - _traverse(child); - } - } - } - - // Don't link each top-level path to the "root" node because the - // user never sees the root - tree.contents.forEach(_traverse); - return map; -} - -/** - * @memberof utils/sources-tree - * @static - */ -function getURL(source: TmpSource): { path: string, group: string } { - const url = source.get("url"); - let def = { path: "", group: "" }; - if (!url) { - return def; - } - - const { pathname, protocol, host, path } = parse(url); - - switch (protocol) { - case "javascript:": - // Ignore `javascript:` URLs for now - return def; - - case "about:": - // An about page is a special case - return merge(def, { - path: "/", - group: url - }); - - case null: - if (pathname && pathname.startsWith("/")) { - // If it's just a URL like "/foo/bar.js", resolve it to the file - // protocol - return merge(def, { - path: path, - group: "file://" - }); - } else if (host === null) { - // We don't know what group to put this under, and it's a script - // with a weird URL. Just group them all under an anonymous group. - return merge(def, { - path: url, - group: "(no domain)" - }); - } - break; - - case "http:": - case "https:": - return merge(def, { - path: pathname, - group: host - }); - } - - return merge(def, { - path: path, - group: protocol ? `${protocol}//` : "" - }); -} - -/** - * @memberof utils/sources-tree - * @static - */ -function addToTree(tree: any, source: TmpSource) { - const url = getURL(source); - - if (IGNORED_URLS.indexOf(url) != -1 || - !source.get("url") || - isPretty(source.toJS())) { - return; - } - - url.path = decodeURIComponent(url.path); - - const parts = url.path.split("/").filter(p => p !== ""); - const isDir = (parts.length === 0 || - parts[parts.length - 1].indexOf(".") === -1); - parts.unshift(url.group); - - let path = ""; - let subtree = tree; - - for (let i = 0; i < parts.length; i++) { - const part = parts[i]; - const isLastPart = i === parts.length - 1; - - // Currently we assume that we are descending into a node with - // children. This will fail if a path has a directory named the - // same as another file, like `foo/bar.js/file.js`. - // - // TODO: Be smarter about this, which we'll probably do when we - // are smarter about folders and collapsing empty ones. - assert(nodeHasChildren(subtree), `${subtree.name} should have children`); - const children = subtree.contents; - - let index = determineFileSortOrder(children, part, isLastPart); - - if (index >= 0 && children[index].name === part) { - // A node with the same name already exists, simply traverse - // into it. - subtree = children[index]; - } else { - // No node with this name exists, so insert a new one in the - // place that is alphabetically sorted. - const node = createNode(part, `${path}/${part}`, []); - const where = index === -1 ? children.length : index; - children.splice(where, 0, node); - subtree = children[where]; - } - - // Keep track of the children so we can tag each node with them. - path = `${path}/${part}`; - } - - // Overwrite the contents of the final node to store the source - // there. - if (isDir) { - subtree.contents.unshift(createNode("(index)", source.get("url"), source)); - } else { - subtree.contents = source; - } -} - -/** - * Look at the nodes in the source tree, and determine the index of where to - * insert a new node. The ordering is index -> folder -> file. - * @memberof utils/sources-tree - * @static - */ -function determineFileSortOrder(nodes:Array, pathPart:string, - isLastPart:boolean) { - const partIsDir = !isLastPart || pathPart.indexOf(".") === -1; - - return nodes.findIndex(node => { - const nodeIsDir = nodeHasChildren(node); - - // The index will always be the first thing, so this pathPart will be - // after it. - if (node.name === "(index)") { - return false; - } - - // If both the pathPart and node are the same type, then compare them - // alphabetically. - if (partIsDir === nodeIsDir) { - return node.name.localeCompare(pathPart) >= 0; - } - - // If the pathPart and node differ, then stop here if the pathPart is a - // directory. Keep on searching if the part is a file, as it needs to be - // placed after the directories. - return partIsDir; - }); -} - -/** - * Take an existing source tree, and return a new one with collapsed nodes. - * @memberof utils/sources-tree - * @static - */ -function collapseTree(node: any, depth: number = 0) { - // Node is a folder. - if (nodeHasChildren(node)) { - // Node is not a root/domain node, and only contains 1 item. - if (depth > 1 && node.contents.length === 1) { - const next = node.contents[0]; - // Do not collapse if the next node is a leaf node. - if (nodeHasChildren(next)) { - return collapseTree( - createNode(`${node.name}/${next.name}`, next.path, next.contents), - depth + 1); - } - } - // Map the contents. - return createNode(node.name, node.path, - node.contents.map(next => collapseTree(next, depth + 1))); - } - // Node is a leaf, not a folder, do not modify it. - return node; -} - -/** - * @memberof utils/sources-tree - * @static - */ -function createTree(sources: any) { - const uncollapsedTree = createNode("root", "", []); - for (let source of sources.valueSeq()) { - addToTree(uncollapsedTree, source); - } - const sourceTree = collapseTree(uncollapsedTree); - - return { uncollapsedTree, - sourceTree, - parentMap: createParentMap(sourceTree), - focusedItem: null }; -} - -module.exports = { - createNode, - nodeHasChildren, - createParentMap, - addToTree, - collapseTree, - createTree -}; diff --git a/src/utils/task.js b/src/utils/task.js deleted file mode 100644 index 5cfcd19ee7..0000000000 --- a/src/utils/task.js +++ /dev/null @@ -1,48 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ts=2 et sw=2 tw=80 filetype=javascript: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/** - * This object provides the public module functions. - */ -const Task = { - // XXX: Not sure if this works in all cases... - async: function(task) { - return function() { - return Task.spawn(task, this, arguments); - }; - }, - - /** - * Creates and starts a new task. - * @param task A generator function - * @return A promise, resolved when the task terminates - */ - spawn: function(task, scope, args) { - return new Promise(function(resolve, reject) { - const iterator = task.apply(scope, args); - - const callNext = lastValue => { - const iteration = iterator.next(lastValue); - Promise.resolve(iteration.value) - .then(value => { - if (iteration.done) { - resolve(value); - } else { - callNext(value); - } - }) - .catch(error => { - reject(error); - iterator.throw(error); - }); - }; - - callNext(undefined); - }); - }, -}; - -module.exports = { Task }; diff --git a/src/utils/test-head.js b/src/utils/test-head.js deleted file mode 100644 index 2d97933204..0000000000 --- a/src/utils/test-head.js +++ /dev/null @@ -1,66 +0,0 @@ -// @flow - -/** - * Utils for mochitest - * @module utils/test-head - */ - -const { combineReducers } = require("redux"); -const reducers = require("../reducers"); -const actions = require("../actions"); -const selectors = require("../selectors"); -const constants = require("../constants"); - -const configureStore = require("../utils/create-store"); - -/** - * @memberof utils/test-head - * @static - */ -function createStore(client: any, initialState: any = {}) { - return configureStore({ - log: false, - makeThunkArgs: args => { - return Object.assign({}, args, { client }); - } - })(combineReducers(reducers), initialState); -} - -/** - * @memberof utils/test-head - * @static - */ -function commonLog(msg: string, data: any = {}) { - console.log(`[INFO] ${msg} ${JSON.stringify(data)}`); -} - -/** - * @memberof utils/test-head - * @static - */ -function makeSource(name: string, props: any = {}) { - return Object.assign({ - id: name, - url: `http://example.com/test/${name}` - }, props); -} - -/** - * @memberof utils/test-head - * @static - */ -function waitForState(store: any, predicate: any) { - return new Promise(resolve => { - const unsubscribe = store.subscribe(() => { - if (predicate(store.getState())) { - unsubscribe(); - resolve(); - } - }); - }); -} - -module.exports = { - actions, constants, selectors, reducers, createStore, commonLog, - makeSource, waitForState -}; diff --git a/src/utils/tests/.eslintrc b/src/utils/tests/.eslintrc deleted file mode 100644 index e39b7d0071..0000000000 --- a/src/utils/tests/.eslintrc +++ /dev/null @@ -1,32 +0,0 @@ -{ - "globals": { - "after": true, - "afterEach": true, - "before": true, - "beforeEach": true, - "context": true, - "describe": true, - "it": true, - "mocha": true, - "setup": true, - "specify": true, - "suite": true, - "suiteSetup": true, - "suiteTeardown": true, - "teardown": true, - "test": true, - "xcontext": true, - "xdescribe": true, - "xit": true, - "xspecify": true, - "assert": true, - "expect": true, - "equal": true, - "ok": true - }, - "rules": { - "camelcase": 0, - "no-unused-vars": [2, {"vars": "all", "args": "none", "varsIgnorePattern": "run_test"}], - "max-nested-callbacks": [2, 4], - } -} diff --git a/src/utils/tests/menu.js b/src/utils/tests/menu.js deleted file mode 100644 index 396ceb1553..0000000000 --- a/src/utils/tests/menu.js +++ /dev/null @@ -1,14 +0,0 @@ -const expect = require("expect.js"); -const { buildMenu } = require("../menu.js"); - -describe("menu", () => { - it("should return an array of visible menu items", () => { - let menuItems = [ - { item: "bla", hidden: false }, - { item: "foo", hidden: true }, - { item: "baa", hidden: () => true }, - { item: "foobar" } - ]; - expect(buildMenu(menuItems)[1]).to.be("foobar"); - }); -}); diff --git a/src/utils/tests/source.js b/src/utils/tests/source.js deleted file mode 100644 index 4a25b5b7f1..0000000000 --- a/src/utils/tests/source.js +++ /dev/null @@ -1,15 +0,0 @@ -const expect = require("expect.js"); -const { - getFilename -} = require("../source.js"); - -describe("sources", () => { - describe("getFilename", () => { - it("should give us a default of (index)", () => { - expect(getFilename({ url: "http://localhost.com:7999/increment/", id: "" })).to.be("(index)"); - }); - it("should give us the filename", () => { - expect(getFilename({ url: "http://localhost.com:7999/increment/hello.html", id: "" })).to.be("hello.html"); - }); - }); -}); diff --git a/src/utils/tests/sources-tree.js b/src/utils/tests/sources-tree.js deleted file mode 100644 index d233e40d62..0000000000 --- a/src/utils/tests/sources-tree.js +++ /dev/null @@ -1,326 +0,0 @@ -const expect = require("expect.js"); -const { Map } = require("immutable"); -const { - createNode, nodeHasChildren, addToTree, collapseTree -} = require("../sources-tree.js"); - -describe("sources-tree", () => { - const abcSource = Map({ - url: "http://example.com/a/b/c.js", - actor: "actor1" - }); - const abcdeSource = Map({ - url: "http://example.com/a/b/c/d/e.js", - actor: "actor2" - }); - const abxSource = Map({ - url: "http://example.com/a/b/x.js", - actor: "actor3" - }); - - it("should provide node API", () => { - const root = createNode("root", "", [createNode("foo", "/foo")]); - expect(root.name).to.be("root"); - expect(nodeHasChildren(root)).to.be(true); - expect(root.contents.length).to.be(1); - - const child = root.contents[0]; - expect(child.name).to.be("foo"); - expect(child.path).to.be("/foo"); - expect(child.contents).to.be(null); - expect(nodeHasChildren(child)).to.be(false); - }); - - it("builds a path-based tree", () => { - const source1 = Map({ - url: "http://example.com/foo/source1.js", - actor: "actor1" - }); - const tree = createNode("root", "", []); - - addToTree(tree, source1); - expect(tree.contents.length).to.be(1); - - let base = tree.contents[0]; - expect(base.name).to.be("example.com"); - expect(base.contents.length).to.be(1); - - let fooNode = base.contents[0]; - expect(fooNode.name).to.be("foo"); - expect(fooNode.contents.length).to.be(1); - - let source1Node = fooNode.contents[0]; - expect(source1Node.name).to.be("source1.js"); - }); - - it("alphabetically sorts children", () => { - const source1 = Map({ - url: "http://example.com/source1.js", - actor: "actor1" - }); - const source2 = Map({ - url: "http://example.com/foo/b_source2.js", - actor: "actor2" - }); - const source3 = Map({ - url: "http://example.com/foo/a_source3.js", - actor: "actor3" - }); - const tree = createNode("root", "", []); - - addToTree(tree, source1); - addToTree(tree, source2); - addToTree(tree, source3); - - let base = tree.contents[0]; - let fooNode = base.contents[0]; - expect(fooNode.name).to.be("foo"); - expect(fooNode.contents.length).to.be(2); - - let source1Node = base.contents[1]; - expect(source1Node.name).to.be("source1.js"); - - // source2 should be after source1 alphabetically - let source2Node = fooNode.contents[1]; - let source3Node = fooNode.contents[0]; - expect(source2Node.name).to.be("b_source2.js"); - expect(source3Node.name).to.be("a_source3.js"); - }); - - it("sorts folders first", () => { - const sources = [ - Map({ - url: "http://example.com/a.js", - actor: "actor1" - }), - Map({ - url: "http://example.com/b.js/b_source.js", - actor: "actor2" - }), - Map({ - url: "http://example.com/c.js", - actor: "actor1" - }), - Map({ - url: "http://example.com", - actor: "actor1" - }), - Map({ - url: "http://example.com/d/d_source.js", - actor: "actor3" - }), - Map({ - url: "http://example.com/b2", - actor: "actor2" - }), - ]; - - const tree = createNode("root", "", []); - sources.forEach(source => addToTree(tree, source)); - const domain = tree.contents[0]; - - const [ - bFolderNode, - b2FolderNode, - dFolderNode, - aFileNode, - cFileNode, - ] = domain.contents; - - expect(bFolderNode.name).to.be("b.js"); - expect(bFolderNode.contents.length).to.be(1); - expect(bFolderNode.contents[0].name).to.be("b_source.js"); - - expect(b2FolderNode.name).to.be("b2"); - expect(b2FolderNode.contents.length).to.be(1); - expect(b2FolderNode.contents[0].name).to.be("(index)"); - - expect(dFolderNode.name).to.be("d"); - expect(dFolderNode.contents.length).to.be(1); - expect(dFolderNode.contents[0].name).to.be("d_source.js"); - - expect(aFileNode.name).to.be("a.js"); - - expect(cFileNode.name).to.be("c.js"); - }); - - it("puts (index) at the top of the sort", () => { - const sources = [ - Map({ - url: "http://example.com/folder/a.js", - actor: "actor1" - }), - Map({ - url: "http://example.com/folder/b/b.js", - actor: "actor2" - }), - Map({ - url: "http://example.com/folder", - actor: "actor1" - }), - Map({ - url: "http://example.com/folder/c/", - actor: "actor1" - }), - ]; - - const tree = createNode("root", "", []); - sources.forEach(source => addToTree(tree, source)); - const [ - indexNode, - bFolderNode, - cFolderNode, - aFileNode, - ] = tree.contents[0].contents[0].contents; - - expect(indexNode.name).to.be("(index)"); - - expect(bFolderNode.name).to.be("b"); - expect(bFolderNode.contents.length).to.be(1); - expect(bFolderNode.contents[0].name).to.be("b.js"); - - expect(cFolderNode.name).to.be("c"); - expect(cFolderNode.contents.length).to.be(1); - expect(cFolderNode.contents[0].name).to.be("(index)"); - - expect(aFileNode.name).to.be("a.js"); - }); - - it("can collapse a single source", () => { - const fullTree = createNode("root", "", []); - addToTree(fullTree, abcSource); - expect(fullTree.contents.length).to.be(1); - const tree = collapseTree(fullTree); - - const host = tree.contents[0]; - expect(host.name).to.be("example.com"); - expect(host.contents.length).to.be(1); - - const abFolder = host.contents[0]; - expect(abFolder.name).to.be("a/b"); - expect(abFolder.contents.length).to.be(1); - - const abcNode = abFolder.contents[0]; - expect(abcNode.name).to.be("c.js"); - expect(abcNode.path).to.be("/example.com/a/b/c.js"); - }); - - it("correctly merges in a collapsed source with a deeper level", () => { - const fullTree = createNode("root", "", []); - addToTree(fullTree, abcSource); - addToTree(fullTree, abcdeSource); - const tree = collapseTree(fullTree); - - expect(tree.contents.length).to.be(1); - - const host = tree.contents[0]; - expect(host.name).to.be("example.com"); - expect(host.contents.length).to.be(1); - - const abFolder = host.contents[0]; - expect(abFolder.name).to.be("a/b"); - expect(abFolder.contents.length).to.be(2); - - const [cdFolder, abcNode] = abFolder.contents; - expect(abcNode.name).to.be("c.js"); - expect(abcNode.path).to.be("/example.com/a/b/c.js"); - expect(cdFolder.name).to.be("c/d"); - - const [abcdeNode] = cdFolder.contents; - expect(abcdeNode.name).to.be("e.js"); - expect(abcdeNode.path).to.be("/example.com/a/b/c/d/e.js"); - }); - - it("correctly merges in a collapsed source with a shallower level", () => { - const fullTree = createNode("root", "", []); - addToTree(fullTree, abcSource); - addToTree(fullTree, abxSource); - const tree = collapseTree(fullTree); - - expect(tree.contents.length).to.be(1); - - const host = tree.contents[0]; - expect(host.name).to.be("example.com"); - expect(host.contents.length).to.be(1); - - const abFolder = host.contents[0]; - expect(abFolder.name).to.be("a/b"); - expect(abFolder.contents.length).to.be(2); - - const [abcNode, abxNode] = abFolder.contents; - expect(abcNode.name).to.be("c.js"); - expect(abcNode.path).to.be("/example.com/a/b/c.js"); - expect(abxNode.name).to.be("x.js"); - expect(abxNode.path).to.be("/example.com/a/b/x.js"); - }); - - it("correctly merges in a collapsed source with the same level", () => { - const fullTree = createNode("root", "", []); - addToTree(fullTree, abcdeSource); - addToTree(fullTree, abcSource); - const tree = collapseTree(fullTree); - - expect(tree.contents.length).to.be(1); - - const host = tree.contents[0]; - expect(host.name).to.be("example.com"); - expect(host.contents.length).to.be(1); - - const abFolder = host.contents[0]; - expect(abFolder.name).to.be("a/b"); - expect(abFolder.contents.length).to.be(2); - - const [cdFolder, abcNode] = abFolder.contents; - expect(abcNode.name).to.be("c.js"); - expect(abcNode.path).to.be("/example.com/a/b/c.js"); - expect(cdFolder.name).to.be("c/d"); - - const [abcdeNode] = cdFolder.contents; - expect(abcdeNode.name).to.be("e.js"); - expect(abcdeNode.path).to.be("/example.com/a/b/c/d/e.js"); - }); - - it("correctly parses webpack sources correctly", () => { - const source = Map({ - url: "webpack:///a/b.js", - actor: "actor1" - }); - const tree = createNode("root", "", []); - - addToTree(tree, source); - expect(tree.contents.length).to.be(1); - - let base = tree.contents[0]; - expect(base.name).to.be("webpack://"); - expect(base.contents.length).to.be(1); - - const aNode = base.contents[0]; - expect(aNode.name).to.be("a"); - expect(aNode.contents.length).to.be(1); - - const bNode = aNode.contents[0]; - expect(bNode.name).to.be("b.js"); - }); - - it("correctly parses file sources correctly", () => { - const source = Map({ - url: "file:///a/b.js", - actor: "actor1" - }); - const tree = createNode("root", "", []); - - addToTree(tree, source); - expect(tree.contents.length).to.be(1); - - let base = tree.contents[0]; - expect(base.name).to.be("file://"); - expect(base.contents.length).to.be(1); - - const aNode = base.contents[0]; - expect(aNode.name).to.be("a"); - expect(aNode.contents.length).to.be(1); - - const bNode = aNode.contents[0]; - expect(bNode.name).to.be("b.js"); - }); -}); diff --git a/src/utils/text.js b/src/utils/text.js deleted file mode 100644 index 5b811aa003..0000000000 --- a/src/utils/text.js +++ /dev/null @@ -1,20 +0,0 @@ -// @flow - -/** - * Utils for keyboard command strings - * @module utils/text - */ - -const { Services: { appinfo }} = require("devtools-modules"); - -/** - * @memberof utils/text - * @static - */ -function cmdString(): string { - return (appinfo.OS === "Darwin") ? "⌘" : "Ctrl"; -} - -module.exports = { - cmdString -}; diff --git a/src/utils/utils.js b/src/utils/utils.js deleted file mode 100644 index a48a7a4526..0000000000 --- a/src/utils/utils.js +++ /dev/null @@ -1,241 +0,0 @@ -// @flow -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/** - * Utils for utils, by utils - * @module utils/utils - */ - -const co = require("co"); - -/** - * @memberof utils/utils - * @static - */ -function asPaused(client: any, func: any) { - if (client.state != "paused") { - return co(function* () { - yield client.interrupt(); - let result; - - try { - result = yield func(); - } catch (e) { - // Try to put the debugger back in a working state by resuming - // it - yield client.resume(); - throw e; - } - - yield client.resume(); - return result; - }); - } - return func(); -} - -/** - * @memberof utils/utils - * @static - */ -function handleError(err: any) { - console.log("ERROR: ", err); -} - -/** - * @memberof utils/utils - * @static - */ -function promisify(context: any, method: any, ...args: any) { - return new Promise((resolve, reject) => { - args.push(response => { - if (response.error) { - reject(response); - } else { - resolve(response); - } - }); - method.apply(context, args); - }); -} - -/** - * @memberof utils/utils - * @static - */ -function truncateStr(str: any, size: any) { - if (str.length > size) { - return `${str.slice(0, size)}...`; - } - return str; -} - -/** - * @memberof utils/utils - * @static - */ -function endTruncateStr(str: any, size: any) { - if (str.length > size) { - return `...${str.slice(str.length - size)}`; - } - return str; -} - -let msgId = 1; -/** - * @memberof utils/utils - * @static - */ -function workerTask(worker: any, method: string) { - return function(...args: any) { - return new Promise((resolve, reject) => { - const id = msgId++; - worker.postMessage({ id, method, args }); - - const listener = ({ data: result }) => { - if (result.id !== id) { - return; - } - - worker.removeEventListener("message", listener); - if (result.error) { - reject(result.error); - } else { - resolve(result.response); - } - }; - - worker.addEventListener("message", listener); - }); - }; -} - -/** - * Interleaves two arrays element by element, returning the combined array, like - * a zip. In the case of arrays with different sizes, undefined values will be - * interleaved at the end along with the extra values of the larger array. - * - * @param Array a - * @param Array b - * @returns Array - * The combined array, in the form [a1, b1, a2, b2, ...] - * @memberof utils/utils - * @static - */ -function zip(a: any, b: any) { - if (!b) { - return a; - } - if (!a) { - return b; - } - const pairs = []; - for (let i = 0, aLength = a.length, bLength = b.length; - i < aLength || i < bLength; - i++) { - pairs.push([a[i], b[i]]); - } - return pairs; -} - -/** - * Converts an object into an array with 2-element arrays as key/value - * pairs of the object. `{ foo: 1, bar: 2}` would become - * `[[foo, 1], [bar 2]]` (order not guaranteed); - * - * @returns array - * @memberof utils/utils - * @static - */ -function entries(obj: any) { - return Object.keys(obj).map(k => [k, obj[k]]); -} - -/** - * @memberof utils/utils - * @static - */ -function mapObject(obj: any, iteratee: any) { - return toObject(entries(obj).map(([key, value]) => { - return [key, iteratee(key, value)]; - })); -} - -/** - * Takes an array of 2-element arrays as key/values pairs and - * constructs an object using them. - * @memberof utils/utils - * @static - */ -function toObject(arr: any) { - const obj = {}; - for (let pair of arr) { - obj[pair[0]] = pair[1]; - } - return obj; -} - -/** - * Composes the given functions into a single function, which will - * apply the results of each function right-to-left, starting with - * applying the given arguments to the right-most function. - * `compose(foo, bar, baz)` === `args => foo(bar(baz(args)` - * - * @param ...function funcs - * @returns function - * @memberof utils/utils - * @static - */ -function compose(...funcs: any) { - return (...args: any) => { - const initialValue = funcs[funcs.length - 1].apply(null, args); - const leftFuncs = funcs.slice(0, -1); - return leftFuncs.reduceRight((composed, f) => f(composed), - initialValue); - }; -} - -/** - * @memberof utils/utils - * @static - */ -function updateObj(obj: T, fields: $Shape) : T { - return Object.assign({}, obj, fields); -} - -/** - * @memberof utils/utils - * @static - */ -function throttle(func: any, ms: number) { - let timeout, _this; - return function(...args: any) { - _this = this; - if (!timeout) { - timeout = setTimeout(() => { - func.apply(_this, ...args); - timeout = null; - }, ms); - } - }; -} - -module.exports = { - asPaused, - handleError, - promisify, - truncateStr, - endTruncateStr, - workerTask, - zip, - entries, - toObject, - mapObject, - compose, - updateObj, - throttle -}; diff --git a/webpack.config.js b/webpack.config.js deleted file mode 100644 index 70a88b2694..0000000000 --- a/webpack.config.js +++ /dev/null @@ -1,34 +0,0 @@ -const toolbox = require("./node_modules/devtools-local-toolbox/index"); -const getConfig = require("./bin/getConfig"); - -const path = require("path"); -const projectPath = path.join(__dirname, "src"); - -function buildConfig(envConfig) { - const webpackConfig = { - entry: { - bundle: [path.join(projectPath, "main.js")], - "source-map-worker": path.join(projectPath, "utils/source-map-worker.js"), - "pretty-print-worker": - path.join(projectPath, "utils/pretty-print-worker.js") - }, - - output: { - path: path.join(__dirname, "assets/build"), - filename: "[name].js", - publicPath: "/assets/build" - }, - - resolve: { - alias: { - "devtools/client/shared/vendor/react": "react", - "devtools/client/shared/vendor/react-dom": "react-dom", - } - } - } - - return toolbox.toolboxConfig(webpackConfig, envConfig); -} - -const envConfig = getConfig(); -module.exports = buildConfig(envConfig); diff --git a/yarn.lock b/yarn.lock deleted file mode 100644 index aae2e2c7a6..0000000000 --- a/yarn.lock +++ /dev/null @@ -1,6506 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 -abbrev@1: - version "1.0.9" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135" - -accepts@~1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.3.tgz#c3ca7434938648c3e0d9c1e328dd68b622c284ca" - dependencies: - mime-types "~2.1.11" - negotiator "0.6.1" - -acorn-jsx@^3.0.0, acorn-jsx@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" - dependencies: - acorn "^3.0.4" - -acorn@^3.0.0, acorn@^3.0.4, acorn@^3.1.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" - -acorn@^4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.3.tgz#1a3e850b428e73ba6b09d1cc527f5aaad4d03ef1" - -acorn@~0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-0.11.0.tgz#6e95f0253ad161ff0127db32983e5e2e5352d59a" - -adm-zip@^0.4.7, adm-zip@~0.4.x, adm-zip@0.4.7: - version "0.4.7" - resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.4.7.tgz#8606c2cbf1c426ce8c8ec00174447fd49b6eafc1" - -ajv-keywords@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.1.1.tgz#02550bc605a3e576041565628af972e06c549d50" - -ajv@^4.7.0: - version "4.9.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.9.0.tgz#5a358085747b134eb567d6d15e015f1d7802f45c" - dependencies: - co "^4.6.0" - json-stable-stringify "^1.0.1" - -align-text@^0.1.1, align-text@^0.1.3: - version "0.1.4" - resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" - dependencies: - kind-of "^3.0.2" - longest "^1.0.1" - repeat-string "^1.5.2" - -alphanum-sort@^1.0.1, alphanum-sort@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" - -amd-loader@0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/amd-loader/-/amd-loader-0.0.5.tgz#9b4c1c26b70015e4ddaec7d6dcd21265090819a0" - -amdefine@>=0.0.4: - version "1.0.1" - resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" - -ansi-escapes@^1.0.0, ansi-escapes@^1.1.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" - -ansi-html@0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/ansi-html/-/ansi-html-0.0.5.tgz#0dcaa5a081206866bc240a3b773a184ea3b88b64" - -ansi-html@0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/ansi-html/-/ansi-html-0.0.6.tgz#bda8e33dd2ee1c20f54c08eb405713cbfc0ed80e" - -ansi-regex@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.0.0.tgz#c5061b6e0ef8a81775e50f5d66151bf6bf371107" - -ansi-styles@^2.0.1, ansi-styles@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" - -anymatch@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.0.tgz#a3e52fa39168c825ff57b0248126ce5a8ff95507" - dependencies: - arrify "^1.0.0" - micromatch "^2.1.5" - -aproba@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.0.4.tgz#2713680775e7614c8ba186c065d4e2e52d1072c0" - -archiver-utils@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/archiver-utils/-/archiver-utils-1.3.0.tgz#e50b4c09c70bf3d680e32ff1b7994e9f9d895174" - dependencies: - glob "^7.0.0" - graceful-fs "^4.1.0" - lazystream "^1.0.0" - lodash "^4.8.0" - normalize-path "^2.0.0" - readable-stream "^2.0.0" - -archiver@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/archiver/-/archiver-1.2.0.tgz#fb5c6af5443b3fa6a426344753bad2a7b444aadd" - dependencies: - archiver-utils "^1.3.0" - async "^2.0.0" - buffer-crc32 "^0.2.1" - glob "^7.0.0" - lodash "^4.8.0" - readable-stream "^2.0.0" - tar-stream "^1.5.0" - zip-stream "^1.1.0" - -are-we-there-yet@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.2.tgz#80e470e95a084794fe1899262c5667c6e88de1b3" - dependencies: - delegates "^1.0.0" - readable-stream "^2.0.0 || ^1.1.13" - -argparse@^1.0.7: - version "1.0.9" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86" - dependencies: - sprintf-js "~1.0.2" - -arr-diff@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" - dependencies: - arr-flatten "^1.0.1" - -arr-flatten@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.0.1.tgz#e5ffe54d45e19f32f216e91eb99c8ce892bb604b" - -array-differ@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031" - -array-find-index@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" - -array-flatten@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" - -array-from@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/array-from/-/array-from-2.1.1.tgz#cfe9d8c26628b9dc5aecc62a9f5d8f1f352c1195" - -array-union@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" - dependencies: - array-uniq "^1.0.1" - -array-uniq@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" - -array-unique@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" - -array.prototype.find@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/array.prototype.find/-/array.prototype.find-2.0.0.tgz#56a9ab1edde2a7701ed6d9166acec338919d8430" - dependencies: - define-properties "^1.1.2" - es-abstract "^1.5.0" - -arrify@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" - -asap@~2.0.3: - version "2.0.5" - resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.5.tgz#522765b50c3510490e52d7dcfe085ef9ba96958f" - -asn1@~0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" - -assert-plus@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" - -assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - -assert@^1.1.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/assert/-/assert-1.4.1.tgz#99912d591836b5a6f5b345c0f07eefc08fc65d91" - dependencies: - util "0.10.3" - -ast-types@0.8.15: - version "0.8.15" - resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.8.15.tgz#8eef0827f04dff0ec8857ba925abe3fea6194e52" - -async-each@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" - -async@^0.9.0: - version "0.9.2" - resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d" - -async@^1.3.0, async@^1.5.0: - version "1.5.2" - resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" - -async@^2.0.0, async@~2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/async/-/async-2.1.2.tgz#612a4ab45ef42a70cde806bad86ee6db047e8385" - dependencies: - lodash "^4.14.0" - -async@~0.2.6: - version "0.2.10" - resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1" - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - -attach-ware@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/attach-ware/-/attach-ware-2.0.1.tgz#01d67a0972c750ea427cbd030d4c0399ff15125d" - dependencies: - unherit "^1.0.0" - -autoprefixer@^6.0.0, autoprefixer@^6.3.1: - version "6.5.3" - resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-6.5.3.tgz#2d853af66d04449fcf50db3066279ab54c3e4b01" - dependencies: - browserslist "~1.4.0" - caniuse-db "^1.0.30000578" - normalize-range "^0.1.2" - num2fraction "^1.2.2" - postcss "^5.2.5" - postcss-value-parser "^3.2.3" - -aws-sign2@~0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" - -aws4@^1.2.1: - version "1.5.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.5.0.tgz#0a29ffb79c31c9e712eeb087e8e7a64b4a56d755" - -babel-cli@^6.7.5: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-cli/-/babel-cli-6.18.0.tgz#92117f341add9dead90f6fa7d0a97c0cc08ec186" - dependencies: - babel-core "^6.18.0" - babel-polyfill "^6.16.0" - babel-register "^6.18.0" - babel-runtime "^6.9.0" - commander "^2.8.1" - convert-source-map "^1.1.0" - fs-readdir-recursive "^1.0.0" - glob "^5.0.5" - lodash "^4.2.0" - output-file-sync "^1.1.0" - path-is-absolute "^1.0.0" - slash "^1.0.0" - source-map "^0.5.0" - v8flags "^2.0.10" - optionalDependencies: - chokidar "^1.0.0" - -babel-code-frame@^6.11.0, babel-code-frame@^6.16.0: - version "6.16.0" - resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.16.0.tgz#f90e60da0862909d3ce098733b5d3987c97cb8de" - dependencies: - chalk "^1.1.0" - esutils "^2.0.2" - js-tokens "^2.0.0" - -babel-core@^6.0.14, babel-core@^6.17.0, babel-core@^6.18.0, babel-core@^6.5.2: - version "6.18.2" - resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.18.2.tgz#d8bb14dd6986fa4f3566a26ceda3964fa0e04e5b" - dependencies: - babel-code-frame "^6.16.0" - babel-generator "^6.18.0" - babel-helpers "^6.16.0" - babel-messages "^6.8.0" - babel-register "^6.18.0" - babel-runtime "^6.9.1" - babel-template "^6.16.0" - babel-traverse "^6.18.0" - babel-types "^6.18.0" - babylon "^6.11.0" - convert-source-map "^1.1.0" - debug "^2.1.1" - json5 "^0.5.0" - lodash "^4.2.0" - minimatch "^3.0.2" - path-is-absolute "^1.0.0" - private "^0.1.6" - slash "^1.0.0" - source-map "^0.5.0" - -babel-eslint@^7.1.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-7.1.0.tgz#d506a5174ba224e25a2d17e128e2ba8987139ddc" - dependencies: - babel-traverse "^6.15.0" - babel-types "^6.15.0" - babylon "^6.11.2" - lodash.pickby "^4.6.0" - -babel-generator@^6.18.0: - version "6.19.0" - resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.19.0.tgz#9b2f244204777a3d6810ec127c673c87b349fac5" - dependencies: - babel-messages "^6.8.0" - babel-runtime "^6.9.0" - babel-types "^6.19.0" - detect-indent "^4.0.0" - jsesc "^1.3.0" - lodash "^4.2.0" - source-map "^0.5.0" - -babel-helper-bindify-decorators@^6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-helper-bindify-decorators/-/babel-helper-bindify-decorators-6.18.0.tgz#fc00c573676a6e702fffa00019580892ec8780a5" - dependencies: - babel-runtime "^6.0.0" - babel-traverse "^6.18.0" - babel-types "^6.18.0" - -babel-helper-builder-binary-assignment-operator-visitor@^6.8.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.18.0.tgz#8ae814989f7a53682152e3401a04fabd0bb333a6" - dependencies: - babel-helper-explode-assignable-expression "^6.18.0" - babel-runtime "^6.0.0" - babel-types "^6.18.0" - -babel-helper-builder-react-jsx@^6.8.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-6.18.0.tgz#ab02f19a2eb7ace936dd87fa55896d02be59bf71" - dependencies: - babel-runtime "^6.9.0" - babel-types "^6.18.0" - esutils "^2.0.0" - lodash "^4.2.0" - -babel-helper-call-delegate@^6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.18.0.tgz#05b14aafa430884b034097ef29e9f067ea4133bd" - dependencies: - babel-helper-hoist-variables "^6.18.0" - babel-runtime "^6.0.0" - babel-traverse "^6.18.0" - babel-types "^6.18.0" - -babel-helper-define-map@^6.18.0, babel-helper-define-map@^6.8.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.18.0.tgz#8d6c85dc7fbb4c19be3de40474d18e97c3676ec2" - dependencies: - babel-helper-function-name "^6.18.0" - babel-runtime "^6.9.0" - babel-types "^6.18.0" - lodash "^4.2.0" - -babel-helper-explode-assignable-expression@^6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.18.0.tgz#14b8e8c2d03ad735d4b20f1840b24cd1f65239fe" - dependencies: - babel-runtime "^6.0.0" - babel-traverse "^6.18.0" - babel-types "^6.18.0" - -babel-helper-explode-class@^6.8.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-helper-explode-class/-/babel-helper-explode-class-6.18.0.tgz#c44f76f4fa23b9c5d607cbac5d4115e7a76f62cb" - dependencies: - babel-helper-bindify-decorators "^6.18.0" - babel-runtime "^6.0.0" - babel-traverse "^6.18.0" - babel-types "^6.18.0" - -babel-helper-function-name@^6.18.0, babel-helper-function-name@^6.8.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.18.0.tgz#68ec71aeba1f3e28b2a6f0730190b754a9bf30e6" - dependencies: - babel-helper-get-function-arity "^6.18.0" - babel-runtime "^6.0.0" - babel-template "^6.8.0" - babel-traverse "^6.18.0" - babel-types "^6.18.0" - -babel-helper-get-function-arity@^6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.18.0.tgz#a5b19695fd3f9cdfc328398b47dafcd7094f9f24" - dependencies: - babel-runtime "^6.0.0" - babel-types "^6.18.0" - -babel-helper-hoist-variables@^6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.18.0.tgz#a835b5ab8b46d6de9babefae4d98ea41e866b82a" - dependencies: - babel-runtime "^6.0.0" - babel-types "^6.18.0" - -babel-helper-optimise-call-expression@^6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.18.0.tgz#9261d0299ee1a4f08a6dd28b7b7c777348fd8f0f" - dependencies: - babel-runtime "^6.0.0" - babel-types "^6.18.0" - -babel-helper-regex@^6.8.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.18.0.tgz#ae0ebfd77de86cb2f1af258e2cc20b5fe893ecc6" - dependencies: - babel-runtime "^6.9.0" - babel-types "^6.18.0" - lodash "^4.2.0" - -babel-helper-remap-async-to-generator@^6.16.0, babel-helper-remap-async-to-generator@^6.16.2: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.18.0.tgz#336cdf3cab650bb191b02fc16a3708e7be7f9ce5" - dependencies: - babel-helper-function-name "^6.18.0" - babel-runtime "^6.0.0" - babel-template "^6.16.0" - babel-traverse "^6.18.0" - babel-types "^6.18.0" - -babel-helper-replace-supers@^6.18.0, babel-helper-replace-supers@^6.8.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.18.0.tgz#28ec69877be4144dbd64f4cc3a337e89f29a924e" - dependencies: - babel-helper-optimise-call-expression "^6.18.0" - babel-messages "^6.8.0" - babel-runtime "^6.0.0" - babel-template "^6.16.0" - babel-traverse "^6.18.0" - babel-types "^6.18.0" - -babel-helpers@^6.16.0: - version "6.16.0" - resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.16.0.tgz#1095ec10d99279460553e67eb3eee9973d3867e3" - dependencies: - babel-runtime "^6.0.0" - babel-template "^6.16.0" - -babel-loader@^6.2.4: - version "6.2.7" - resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-6.2.7.tgz#16fdbf64328030dc5a606827d389c8b92a2a8032" - dependencies: - find-cache-dir "^0.1.1" - loader-utils "^0.2.11" - mkdirp "^0.5.1" - object-assign "^4.0.1" - -babel-messages@^6.8.0: - version "6.8.0" - resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.8.0.tgz#bf504736ca967e6d65ef0adb5a2a5f947c8e0eb9" - dependencies: - babel-runtime "^6.0.0" - -babel-plugin-check-es2015-constants@^6.3.13: - version "6.8.0" - resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.8.0.tgz#dbf024c32ed37bfda8dee1e76da02386a8d26fe7" - dependencies: - babel-runtime "^6.0.0" - -babel-plugin-module-resolver@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/babel-plugin-module-resolver/-/babel-plugin-module-resolver-2.3.0.tgz#2c0eee55b9eb51e20cf763bafa400fe16e9003d1" - dependencies: - find-babel-config "^1.0.1" - glob "^7.1.1" - resolve "^1.1.7" - -babel-plugin-syntax-async-functions@^6.8.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" - -babel-plugin-syntax-async-generators@^6.5.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz#6bc963ebb16eccbae6b92b596eb7f35c342a8b9a" - -babel-plugin-syntax-class-constructor-call@^6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-class-constructor-call/-/babel-plugin-syntax-class-constructor-call-6.18.0.tgz#9cb9d39fe43c8600bec8146456ddcbd4e1a76416" - -babel-plugin-syntax-class-properties@^6.8.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz#d7eb23b79a317f8543962c505b827c7d6cac27de" - -babel-plugin-syntax-decorators@^6.1.18, babel-plugin-syntax-decorators@^6.13.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz#312563b4dbde3cc806cee3e416cceeaddd11ac0b" - -babel-plugin-syntax-do-expressions@^6.8.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-do-expressions/-/babel-plugin-syntax-do-expressions-6.13.0.tgz#5747756139aa26d390d09410b03744ba07e4796d" - -babel-plugin-syntax-dynamic-import@^6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz#8d6a26229c83745a9982a441051572caa179b1da" - -babel-plugin-syntax-exponentiation-operator@^6.8.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" - -babel-plugin-syntax-export-extensions@^6.8.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-export-extensions/-/babel-plugin-syntax-export-extensions-6.13.0.tgz#70a1484f0f9089a4e84ad44bac353c95b9b12721" - -babel-plugin-syntax-flow@^6.18.0, babel-plugin-syntax-flow@^6.3.13: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz#4c3ab20a2af26aa20cd25995c398c4eb70310c8d" - -babel-plugin-syntax-function-bind@^6.8.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-function-bind/-/babel-plugin-syntax-function-bind-6.13.0.tgz#48c495f177bdf31a981e732f55adc0bdd2601f46" - -babel-plugin-syntax-jsx@^6.3.13, babel-plugin-syntax-jsx@^6.8.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946" - -babel-plugin-syntax-object-rest-spread@^6.8.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5" - -babel-plugin-syntax-trailing-function-commas@^6.3.13: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.13.0.tgz#2b84b7d53dd744f94ff1fad7669406274b23f541" - -babel-plugin-transform-async-generator-functions@^6.17.0: - version "6.17.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-6.17.0.tgz#d0b5a2b2f0940f2b245fa20a00519ed7bc6cae54" - dependencies: - babel-helper-remap-async-to-generator "^6.16.2" - babel-plugin-syntax-async-generators "^6.5.0" - babel-runtime "^6.0.0" - -babel-plugin-transform-async-to-generator@^6.16.0: - version "6.16.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.16.0.tgz#19ec36cb1486b59f9f468adfa42ce13908ca2999" - dependencies: - babel-helper-remap-async-to-generator "^6.16.0" - babel-plugin-syntax-async-functions "^6.8.0" - babel-runtime "^6.0.0" - -babel-plugin-transform-class-constructor-call@^6.3.13: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-constructor-call/-/babel-plugin-transform-class-constructor-call-6.18.0.tgz#80855e38a1ab47b8c6c647f8ea1bcd2c00ca3aae" - dependencies: - babel-plugin-syntax-class-constructor-call "^6.18.0" - babel-runtime "^6.0.0" - babel-template "^6.8.0" - -babel-plugin-transform-class-properties@^6.18.0: - version "6.19.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.19.0.tgz#1274b349abaadc835164e2004f4a2444a2788d5f" - dependencies: - babel-helper-function-name "^6.18.0" - babel-plugin-syntax-class-properties "^6.8.0" - babel-runtime "^6.9.1" - babel-template "^6.15.0" - -babel-plugin-transform-decorators-legacy@1.3.4: - version "1.3.4" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-decorators-legacy/-/babel-plugin-transform-decorators-legacy-1.3.4.tgz#741b58f6c5bce9e6027e0882d9c994f04f366925" - dependencies: - babel-plugin-syntax-decorators "^6.1.18" - babel-runtime "^6.2.0" - babel-template "^6.3.0" - -babel-plugin-transform-decorators@^6.13.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-decorators/-/babel-plugin-transform-decorators-6.13.0.tgz#82d65c1470ae83e2d13eebecb0a1c2476d62da9d" - dependencies: - babel-helper-define-map "^6.8.0" - babel-helper-explode-class "^6.8.0" - babel-plugin-syntax-decorators "^6.13.0" - babel-runtime "^6.0.0" - babel-template "^6.8.0" - babel-types "^6.13.0" - -babel-plugin-transform-do-expressions@^6.3.13: - version "6.8.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-do-expressions/-/babel-plugin-transform-do-expressions-6.8.0.tgz#fda692af339835cc255bb7544efb8f7c1306c273" - dependencies: - babel-plugin-syntax-do-expressions "^6.8.0" - babel-runtime "^6.0.0" - -babel-plugin-transform-es2015-arrow-functions@^6.3.13: - version "6.8.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.8.0.tgz#5b63afc3181bdc9a8c4d481b5a4f3f7d7fef3d9d" - dependencies: - babel-runtime "^6.0.0" - -babel-plugin-transform-es2015-block-scoped-functions@^6.3.13: - version "6.8.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.8.0.tgz#ed95d629c4b5a71ae29682b998f70d9833eb366d" - dependencies: - babel-runtime "^6.0.0" - -babel-plugin-transform-es2015-block-scoping@^6.18.0, babel-plugin-transform-es2015-block-scoping@^6.7.1: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.18.0.tgz#3bfdcfec318d46df22525cdea88f1978813653af" - dependencies: - babel-runtime "^6.9.0" - babel-template "^6.15.0" - babel-traverse "^6.18.0" - babel-types "^6.18.0" - lodash "^4.2.0" - -babel-plugin-transform-es2015-classes@^6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.18.0.tgz#ffe7a17321bf83e494dcda0ae3fc72df48ffd1d9" - dependencies: - babel-helper-define-map "^6.18.0" - babel-helper-function-name "^6.18.0" - babel-helper-optimise-call-expression "^6.18.0" - babel-helper-replace-supers "^6.18.0" - babel-messages "^6.8.0" - babel-runtime "^6.9.0" - babel-template "^6.14.0" - babel-traverse "^6.18.0" - babel-types "^6.18.0" - -babel-plugin-transform-es2015-computed-properties@^6.3.13: - version "6.8.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.8.0.tgz#f51010fd61b3bd7b6b60a5fdfd307bb7a5279870" - dependencies: - babel-helper-define-map "^6.8.0" - babel-runtime "^6.0.0" - babel-template "^6.8.0" - -babel-plugin-transform-es2015-destructuring@^6.18.0, babel-plugin-transform-es2015-destructuring@^6.6.5: - version "6.19.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.19.0.tgz#ff1d911c4b3f4cab621bd66702a869acd1900533" - dependencies: - babel-runtime "^6.9.0" - -babel-plugin-transform-es2015-duplicate-keys@^6.6.0: - version "6.8.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.8.0.tgz#fd8f7f7171fc108cc1c70c3164b9f15a81c25f7d" - dependencies: - babel-runtime "^6.0.0" - babel-types "^6.8.0" - -babel-plugin-transform-es2015-for-of@^6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.18.0.tgz#4c517504db64bf8cfc119a6b8f177211f2028a70" - dependencies: - babel-runtime "^6.0.0" - -babel-plugin-transform-es2015-function-name@^6.9.0: - version "6.9.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.9.0.tgz#8c135b17dbd064e5bba56ec511baaee2fca82719" - dependencies: - babel-helper-function-name "^6.8.0" - babel-runtime "^6.9.0" - babel-types "^6.9.0" - -babel-plugin-transform-es2015-literals@^6.3.13: - version "6.8.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.8.0.tgz#50aa2e5c7958fc2ab25d74ec117e0cc98f046468" - dependencies: - babel-runtime "^6.0.0" - -babel-plugin-transform-es2015-modules-amd@^6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.18.0.tgz#49a054cbb762bdf9ae2d8a807076cfade6141e40" - dependencies: - babel-plugin-transform-es2015-modules-commonjs "^6.18.0" - babel-runtime "^6.0.0" - babel-template "^6.8.0" - -babel-plugin-transform-es2015-modules-commonjs@^6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.18.0.tgz#c15ae5bb11b32a0abdcc98a5837baa4ee8d67bcc" - dependencies: - babel-plugin-transform-strict-mode "^6.18.0" - babel-runtime "^6.0.0" - babel-template "^6.16.0" - babel-types "^6.18.0" - -babel-plugin-transform-es2015-modules-systemjs@^6.18.0: - version "6.19.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.19.0.tgz#50438136eba74527efa00a5b0fefaf1dc4071da6" - dependencies: - babel-helper-hoist-variables "^6.18.0" - babel-runtime "^6.11.6" - babel-template "^6.14.0" - -babel-plugin-transform-es2015-modules-umd@^6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.18.0.tgz#23351770ece5c1f8e83ed67cb1d7992884491e50" - dependencies: - babel-plugin-transform-es2015-modules-amd "^6.18.0" - babel-runtime "^6.0.0" - babel-template "^6.8.0" - -babel-plugin-transform-es2015-object-super@^6.3.13: - version "6.8.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.8.0.tgz#1b858740a5a4400887c23dcff6f4d56eea4a24c5" - dependencies: - babel-helper-replace-supers "^6.8.0" - babel-runtime "^6.0.0" - -babel-plugin-transform-es2015-parameters@^6.18.0, babel-plugin-transform-es2015-parameters@^6.7.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.18.0.tgz#9b2cfe238c549f1635ba27fc1daa858be70608b1" - dependencies: - babel-helper-call-delegate "^6.18.0" - babel-helper-get-function-arity "^6.18.0" - babel-runtime "^6.9.0" - babel-template "^6.16.0" - babel-traverse "^6.18.0" - babel-types "^6.18.0" - -babel-plugin-transform-es2015-shorthand-properties@^6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.18.0.tgz#e2ede3b7df47bf980151926534d1dd0cbea58f43" - dependencies: - babel-runtime "^6.0.0" - babel-types "^6.18.0" - -babel-plugin-transform-es2015-spread@^6.3.13, babel-plugin-transform-es2015-spread@^6.6.5: - version "6.8.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.8.0.tgz#0217f737e3b821fa5a669f187c6ed59205f05e9c" - dependencies: - babel-runtime "^6.0.0" - -babel-plugin-transform-es2015-sticky-regex@^6.3.13: - version "6.8.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.8.0.tgz#e73d300a440a35d5c64f5c2a344dc236e3df47be" - dependencies: - babel-helper-regex "^6.8.0" - babel-runtime "^6.0.0" - babel-types "^6.8.0" - -babel-plugin-transform-es2015-template-literals@^6.6.0: - version "6.8.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.8.0.tgz#86eb876d0a2c635da4ec048b4f7de9dfc897e66b" - dependencies: - babel-runtime "^6.0.0" - -babel-plugin-transform-es2015-typeof-symbol@^6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.18.0.tgz#0b14c48629c90ff47a0650077f6aa699bee35798" - dependencies: - babel-runtime "^6.0.0" - -babel-plugin-transform-es2015-unicode-regex@^6.3.13: - version "6.11.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.11.0.tgz#6298ceabaad88d50a3f4f392d8de997260f6ef2c" - dependencies: - babel-helper-regex "^6.8.0" - babel-runtime "^6.0.0" - regexpu-core "^2.0.0" - -babel-plugin-transform-exponentiation-operator@^6.3.13: - version "6.8.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.8.0.tgz#db25742e9339eade676ca9acec46f955599a68a4" - dependencies: - babel-helper-builder-binary-assignment-operator-visitor "^6.8.0" - babel-plugin-syntax-exponentiation-operator "^6.8.0" - babel-runtime "^6.0.0" - -babel-plugin-transform-export-extensions@^6.3.13: - version "6.8.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-export-extensions/-/babel-plugin-transform-export-extensions-6.8.0.tgz#fa80ff655b636549431bfd38f6b817bd82e47f5b" - dependencies: - babel-plugin-syntax-export-extensions "^6.8.0" - babel-runtime "^6.0.0" - -babel-plugin-transform-flow-strip-types@^6.14.0, babel-plugin-transform-flow-strip-types@^6.3.13: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.18.0.tgz#4d3e642158661e9b40db457c004a30817fa32592" - dependencies: - babel-plugin-syntax-flow "^6.18.0" - babel-runtime "^6.0.0" - -babel-plugin-transform-function-bind@^6.3.13: - version "6.8.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-function-bind/-/babel-plugin-transform-function-bind-6.8.0.tgz#e7f334ce69f50d28fe850a822eaaab9fa4f4d821" - dependencies: - babel-plugin-syntax-function-bind "^6.8.0" - babel-runtime "^6.0.0" - -babel-plugin-transform-object-rest-spread@^6.16.0: - version "6.19.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.19.0.tgz#f6ac428ee3cb4c6aa00943ed1422ce813603b34c" - dependencies: - babel-plugin-syntax-object-rest-spread "^6.8.0" - babel-runtime "^6.0.0" - -babel-plugin-transform-react-display-name@^6.3.13: - version "6.8.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-display-name/-/babel-plugin-transform-react-display-name-6.8.0.tgz#f7a084977383d728bdbdc2835bba0159577f660e" - dependencies: - babel-runtime "^6.0.0" - -babel-plugin-transform-react-jsx-self@^6.11.0: - version "6.11.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx-self/-/babel-plugin-transform-react-jsx-self-6.11.0.tgz#605c9450c1429f97a930f7e1dfe3f0d9d0dbd0f4" - dependencies: - babel-plugin-syntax-jsx "^6.8.0" - babel-runtime "^6.9.0" - -babel-plugin-transform-react-jsx-source@^6.3.13: - version "6.9.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx-source/-/babel-plugin-transform-react-jsx-source-6.9.0.tgz#af684a05c2067a86e0957d4f343295ccf5dccf00" - dependencies: - babel-plugin-syntax-jsx "^6.8.0" - babel-runtime "^6.9.0" - -babel-plugin-transform-react-jsx@^6.3.13: - version "6.8.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx/-/babel-plugin-transform-react-jsx-6.8.0.tgz#94759942f70af18c617189aa7f3593f1644a71ab" - dependencies: - babel-helper-builder-react-jsx "^6.8.0" - babel-plugin-syntax-jsx "^6.8.0" - babel-runtime "^6.0.0" - -babel-plugin-transform-regenerator@^6.16.0: - version "6.16.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.16.1.tgz#a75de6b048a14154aae14b0122756c5bed392f59" - dependencies: - babel-runtime "^6.9.0" - babel-types "^6.16.0" - private "~0.1.5" - -babel-plugin-transform-runtime@^6.7.5: - version "6.15.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-runtime/-/babel-plugin-transform-runtime-6.15.0.tgz#3d75b4d949ad81af157570273846fb59aeb0d57c" - dependencies: - babel-runtime "^6.9.0" - -babel-plugin-transform-strict-mode@^6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.18.0.tgz#df7cf2991fe046f44163dcd110d5ca43bc652b9d" - dependencies: - babel-runtime "^6.0.0" - babel-types "^6.18.0" - -babel-plugin-webpack-alias@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/babel-plugin-webpack-alias/-/babel-plugin-webpack-alias-2.1.2.tgz#05a1ba23c28595660fb6ea5736424fc596b4a247" - dependencies: - babel-types "^6.14.0" - find-up "^2.0.0" - lodash.some "^4.5.1" - lodash.template "^4.3.0" - -babel-polyfill@^6.16.0, babel-polyfill@^6.7.4: - version "6.16.0" - resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.16.0.tgz#2d45021df87e26a374b6d4d1a9c65964d17f2422" - dependencies: - babel-runtime "^6.9.1" - core-js "^2.4.0" - regenerator-runtime "^0.9.5" - -babel-preset-es2015@^6.5.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-preset-es2015/-/babel-preset-es2015-6.18.0.tgz#b8c70df84ec948c43dcf2bf770e988eb7da88312" - dependencies: - babel-plugin-check-es2015-constants "^6.3.13" - babel-plugin-transform-es2015-arrow-functions "^6.3.13" - babel-plugin-transform-es2015-block-scoped-functions "^6.3.13" - babel-plugin-transform-es2015-block-scoping "^6.18.0" - babel-plugin-transform-es2015-classes "^6.18.0" - babel-plugin-transform-es2015-computed-properties "^6.3.13" - babel-plugin-transform-es2015-destructuring "^6.18.0" - babel-plugin-transform-es2015-duplicate-keys "^6.6.0" - babel-plugin-transform-es2015-for-of "^6.18.0" - babel-plugin-transform-es2015-function-name "^6.9.0" - babel-plugin-transform-es2015-literals "^6.3.13" - babel-plugin-transform-es2015-modules-amd "^6.18.0" - babel-plugin-transform-es2015-modules-commonjs "^6.18.0" - babel-plugin-transform-es2015-modules-systemjs "^6.18.0" - babel-plugin-transform-es2015-modules-umd "^6.18.0" - babel-plugin-transform-es2015-object-super "^6.3.13" - babel-plugin-transform-es2015-parameters "^6.18.0" - babel-plugin-transform-es2015-shorthand-properties "^6.18.0" - babel-plugin-transform-es2015-spread "^6.3.13" - babel-plugin-transform-es2015-sticky-regex "^6.3.13" - babel-plugin-transform-es2015-template-literals "^6.6.0" - babel-plugin-transform-es2015-typeof-symbol "^6.18.0" - babel-plugin-transform-es2015-unicode-regex "^6.3.13" - babel-plugin-transform-regenerator "^6.16.0" - -babel-preset-react@^6.5.0: - version "6.16.0" - resolved "https://registry.yarnpkg.com/babel-preset-react/-/babel-preset-react-6.16.0.tgz#aa117d60de0928607e343c4828906e4661824316" - dependencies: - babel-plugin-syntax-flow "^6.3.13" - babel-plugin-syntax-jsx "^6.3.13" - babel-plugin-transform-flow-strip-types "^6.3.13" - babel-plugin-transform-react-display-name "^6.3.13" - babel-plugin-transform-react-jsx "^6.3.13" - babel-plugin-transform-react-jsx-self "^6.11.0" - babel-plugin-transform-react-jsx-source "^6.3.13" - -babel-preset-stage-0@^6.5.0: - version "6.16.0" - resolved "https://registry.yarnpkg.com/babel-preset-stage-0/-/babel-preset-stage-0-6.16.0.tgz#f5a263c420532fd57491f1a7315b3036e428f823" - dependencies: - babel-plugin-transform-do-expressions "^6.3.13" - babel-plugin-transform-function-bind "^6.3.13" - babel-preset-stage-1 "^6.16.0" - -babel-preset-stage-1@^6.16.0: - version "6.16.0" - resolved "https://registry.yarnpkg.com/babel-preset-stage-1/-/babel-preset-stage-1-6.16.0.tgz#9d31fbbdae7b17c549fd3ac93e3cf6902695e479" - dependencies: - babel-plugin-transform-class-constructor-call "^6.3.13" - babel-plugin-transform-export-extensions "^6.3.13" - babel-preset-stage-2 "^6.16.0" - -babel-preset-stage-2@^6.16.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-preset-stage-2/-/babel-preset-stage-2-6.18.0.tgz#9eb7bf9a8e91c68260d5ba7500493caaada4b5b5" - dependencies: - babel-plugin-syntax-dynamic-import "^6.18.0" - babel-plugin-transform-class-properties "^6.18.0" - babel-plugin-transform-decorators "^6.13.0" - babel-preset-stage-3 "^6.17.0" - -babel-preset-stage-3@^6.17.0: - version "6.17.0" - resolved "https://registry.yarnpkg.com/babel-preset-stage-3/-/babel-preset-stage-3-6.17.0.tgz#b6638e46db6e91e3f889013d8ce143917c685e39" - dependencies: - babel-plugin-syntax-trailing-function-commas "^6.3.13" - babel-plugin-transform-async-generator-functions "^6.17.0" - babel-plugin-transform-async-to-generator "^6.16.0" - babel-plugin-transform-exponentiation-operator "^6.3.13" - babel-plugin-transform-object-rest-spread "^6.16.0" - -babel-register@^6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.18.0.tgz#892e2e03865078dd90ad2c715111ec4449b32a68" - dependencies: - babel-core "^6.18.0" - babel-runtime "^6.11.6" - core-js "^2.4.0" - home-or-tmp "^2.0.0" - lodash "^4.2.0" - mkdirp "^0.5.1" - source-map-support "^0.4.2" - -babel-runtime@^6.0.0, babel-runtime@^6.11.6, babel-runtime@^6.2.0, babel-runtime@^6.9.0, babel-runtime@^6.9.1: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.18.0.tgz#0f4177ffd98492ef13b9f823e9994a02584c9078" - dependencies: - core-js "^2.4.0" - regenerator-runtime "^0.9.5" - -babel-runtime@6.11.6: - version "6.11.6" - resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.11.6.tgz#6db707fef2d49c49bfa3cb64efdb436b518b8222" - dependencies: - core-js "^2.4.0" - regenerator-runtime "^0.9.5" - -babel-template@^6.14.0, babel-template@^6.15.0, babel-template@^6.16.0, babel-template@^6.3.0, babel-template@^6.8.0: - version "6.16.0" - resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.16.0.tgz#e149dd1a9f03a35f817ddbc4d0481988e7ebc8ca" - dependencies: - babel-runtime "^6.9.0" - babel-traverse "^6.16.0" - babel-types "^6.16.0" - babylon "^6.11.0" - lodash "^4.2.0" - -babel-traverse@^6.15.0, babel-traverse@^6.16.0, babel-traverse@^6.18.0, babel-traverse@^6.5.0: - version "6.19.0" - resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.19.0.tgz#68363fb821e26247d52a519a84b2ceab8df4f55a" - dependencies: - babel-code-frame "^6.16.0" - babel-messages "^6.8.0" - babel-runtime "^6.9.0" - babel-types "^6.19.0" - babylon "^6.11.0" - debug "^2.2.0" - globals "^9.0.0" - invariant "^2.2.0" - lodash "^4.2.0" - -babel-types@^6.13.0, babel-types@^6.14.0, babel-types@^6.15.0, babel-types@^6.16.0, babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.7.2, babel-types@^6.8.0, babel-types@^6.9.0: - version "6.19.0" - resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.19.0.tgz#8db2972dbed01f1192a8b602ba1e1e4c516240b9" - dependencies: - babel-runtime "^6.9.1" - esutils "^2.0.2" - lodash "^4.2.0" - to-fast-properties "^1.0.1" - -babelify@^7.2.0: - version "7.3.0" - resolved "https://registry.yarnpkg.com/babelify/-/babelify-7.3.0.tgz#aa56aede7067fd7bd549666ee16dc285087e88e5" - dependencies: - babel-core "^6.0.14" - object-assign "^4.0.0" - -babylon@^6.11.0, babylon@^6.11.2, babylon@^6.5.2: - version "6.14.0" - resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.14.0.tgz#c8ba4b69b544b2cd8f3fb96b06614660a49b7128" - -bail@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/bail/-/bail-1.0.1.tgz#912579de8b391aadf3c5fdf4cd2a0fc225df3bc2" - -balanced-match@^0.4.0, balanced-match@^0.4.1, balanced-match@^0.4.2: - version "0.4.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838" - -balanced-match@~0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.1.0.tgz#b504bd05869b39259dd0c5efc35d843176dccc4a" - -base62@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/base62/-/base62-1.1.2.tgz#22ced6a49913565bc0b8d9a11563a465c084124c" - -base64-js@^1.0.2: - version "1.2.0" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.2.0.tgz#a39992d723584811982be5e290bb6a53d86700f1" - -Base64@~0.2.0: - version "0.2.1" - resolved "https://registry.yarnpkg.com/Base64/-/Base64-0.2.1.tgz#ba3a4230708e186705065e66babdd4c35cf60028" - -batch@0.5.3: - version "0.5.3" - resolved "https://registry.yarnpkg.com/batch/-/batch-0.5.3.tgz#3f3414f380321743bfc1042f9a83ff1d5824d464" - -bcrypt-pbkdf@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.0.tgz#3ca76b85241c7170bf7d9703e7b9aa74630040d4" - dependencies: - tweetnacl "^0.14.3" - -big.js@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.1.3.tgz#4cada2193652eb3ca9ec8e55c9015669c9806978" - -binary-extensions@^1.0.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.7.0.tgz#6c1610db163abfb34edfe42fa423343a1e01185d" - -bl@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/bl/-/bl-1.1.2.tgz#fdca871a99713aa00d19e3bbba41c44787a65398" - dependencies: - readable-stream "~2.0.5" - -block-stream@*: - version "0.0.9" - resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" - dependencies: - inherits "~2.0.0" - -bluebird@^2.9.34: - version "2.11.0" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-2.11.0.tgz#534b9033c022c9579c56ba3b3e5a5caafbb650e1" - -bluebird@3.4.6: - version "3.4.6" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.4.6.tgz#01da8d821d87813d158967e743d5fe6c62cf8c0f" - -body-parser@^1.15.0: - version "1.15.2" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.15.2.tgz#d7578cf4f1d11d5f6ea804cef35dc7a7ff6dae67" - dependencies: - bytes "2.4.0" - content-type "~1.0.2" - debug "~2.2.0" - depd "~1.1.0" - http-errors "~1.5.0" - iconv-lite "0.4.13" - on-finished "~2.3.0" - qs "6.2.0" - raw-body "~2.1.7" - type-is "~1.6.13" - -body-parser@~1.14.0: - version "1.14.2" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.14.2.tgz#1015cb1fe2c443858259581db53332f8d0cf50f9" - dependencies: - bytes "2.2.0" - content-type "~1.0.1" - debug "~2.2.0" - depd "~1.1.0" - http-errors "~1.3.1" - iconv-lite "0.4.13" - on-finished "~2.3.0" - qs "5.2.0" - raw-body "~2.1.5" - type-is "~1.6.10" - -boom@2.x.x: - version "2.10.1" - resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f" - dependencies: - hoek "2.x.x" - -brace-expansion@^1.0.0: - version "1.1.6" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.6.tgz#7197d7eaa9b87e648390ea61fc66c84427420df9" - dependencies: - balanced-match "^0.4.1" - concat-map "0.0.1" - -braces@^1.8.2: - version "1.8.5" - resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" - dependencies: - expand-range "^1.8.1" - preserve "^0.2.0" - repeat-element "^1.1.2" - -browser-resolve@^1.7.0: - version "1.11.2" - resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-1.11.2.tgz#8ff09b0a2c421718a1051c260b32e48f442938ce" - dependencies: - resolve "1.1.7" - -browser-stdout@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.0.tgz#f351d32969d32fa5d7a5567154263d928ae3bd1f" - -browserify-zlib@~0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.1.4.tgz#bb35f8a519f600e0fa6b8485241c979d0141fb2d" - dependencies: - pako "~0.2.0" - -browserslist@^1.1.1, browserslist@^1.1.3, browserslist@~1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-1.4.0.tgz#9cfdcf5384d9158f5b70da2aa00b30e8ff019049" - dependencies: - caniuse-db "^1.0.30000539" - -buffer-crc32@^0.2.1: - version "0.2.5" - resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.5.tgz#db003ac2671e62ebd6ece78ea2c2e1b405736e91" - -buffer-shims@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/buffer-shims/-/buffer-shims-1.0.0.tgz#9978ce317388c649ad8793028c3477ef044a8b51" - -buffer@^4.9.0: - version "4.9.1" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" - dependencies: - base64-js "^1.0.2" - ieee754 "^1.1.4" - isarray "^1.0.0" - -builtin-modules@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" - -bytes@2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-2.2.0.tgz#fd35464a403f6f9117c2de3609ecff9cae000588" - -bytes@2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-2.4.0.tgz#7d97196f9d5baf7f6935e25985549edd2a6c2339" - -caller-id@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/caller-id/-/caller-id-0.1.0.tgz#59bdac0893d12c3871408279231f97458364f07b" - dependencies: - stack-trace "~0.0.7" - -caller-path@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" - dependencies: - callsites "^0.2.0" - -callsites@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" - -camelcase-keys@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" - dependencies: - camelcase "^2.0.0" - map-obj "^1.0.0" - -camelcase@^1.0.2: - version "1.2.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" - -camelcase@^2.0.0, camelcase@^2.0.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" - -camelcase@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" - -caniuse-db@^1.0.30000187, caniuse-db@^1.0.30000539, caniuse-db@^1.0.30000578: - version "1.0.30000584" - resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000584.tgz#cfbce897a48145fa73f96d893025581e838648c4" - -capture-stack-trace@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz#4a6fa07399c26bba47f0b2496b4d0fb408c5550d" - -caseless@~0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.11.0.tgz#715b96ea9841593cc33067923f5ec60ebda4f7d7" - -ccount@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/ccount/-/ccount-1.0.1.tgz#665687945168c218ec77ff61a4155ae00227a96c" - -center-align@^0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad" - dependencies: - align-text "^0.1.3" - lazy-cache "^1.0.3" - -chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" - dependencies: - ansi-styles "^2.2.1" - escape-string-regexp "^1.0.2" - has-ansi "^2.0.0" - strip-ansi "^3.0.0" - supports-color "^2.0.0" - -character-entities-html4@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/character-entities-html4/-/character-entities-html4-1.1.0.tgz#1ab08551d3ce1fa1df08d00fb9ca1defb147a06c" - -character-entities-legacy@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-1.1.0.tgz#b18aad98f6b7bcc646c1e4c81f9f1956376a561a" - -character-entities@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/character-entities/-/character-entities-1.2.0.tgz#a683e2cf75dbe8b171963531364e58e18a1b155f" - -character-reference-invalid@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-1.1.0.tgz#dec9ad1dfb9f8d06b4fcdaa2adc3c4fd97af1e68" - -charenc@~0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.1.tgz#004cff9feaf102382ed12db58dd6f962796d6e88" - -check-node-version@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/check-node-version/-/check-node-version-1.1.2.tgz#d48214ec629e3bf9f8f3ecee9feefeac723c864e" - dependencies: - minimist "^1.2.0" - run-parallel "^1.1.4" - semver "^5.0.3" - -chokidar@^1.0.0, chokidar@^1.0.5, chokidar@^1.2.0: - version "1.6.1" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.6.1.tgz#2f4447ab5e96e50fb3d789fd90d4c72e0e4c70c2" - dependencies: - anymatch "^1.3.0" - async-each "^1.0.0" - glob-parent "^2.0.0" - inherits "^2.0.1" - is-binary-path "^1.0.0" - is-glob "^2.0.0" - path-is-absolute "^1.0.0" - readdirp "^2.0.0" - optionalDependencies: - fsevents "^1.0.0" - -chrome-remote-debugging-protocol@0.0.10: - version "0.0.10" - resolved "https://registry.yarnpkg.com/chrome-remote-debugging-protocol/-/chrome-remote-debugging-protocol-0.0.10.tgz#0d364cbc3c0f18f43e3cdcd908c8b06f702a6dee" - -chrome-remote-debugging-protocol@0.0.11: - version "0.0.11" - resolved "https://registry.yarnpkg.com/chrome-remote-debugging-protocol/-/chrome-remote-debugging-protocol-0.0.11.tgz#d16dc5617ead5fc76fa9d1f584863c359f3be32f" - -ci-info@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.0.0.tgz#dc5285f2b4e251821683681c381c3388f46ec534" - -circular-json@^0.3.0: - version "0.3.1" - resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.1.tgz#be8b36aefccde8b3ca7aa2d6afc07a37242c0d2d" - -clap@^1.0.9: - version "1.1.1" - resolved "https://registry.yarnpkg.com/clap/-/clap-1.1.1.tgz#a8a93e0bfb7581ac199c4f001a5525a724ce696d" - dependencies: - chalk "^1.1.3" - -classnames@^2.2.5: - version "2.2.5" - resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.5.tgz#fb3801d453467649ef3603c7d61a02bd129bde6d" - -cli-cursor@^1.0.1, cli-cursor@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987" - dependencies: - restore-cursor "^1.0.1" - -cli-width@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.1.0.tgz#b234ca209b29ef66fc518d9b98d5847b00edf00a" - -cliui@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" - dependencies: - center-align "^0.1.1" - right-align "^0.1.1" - wordwrap "0.0.2" - -cliui@^3.0.3, cliui@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" - dependencies: - string-width "^1.0.1" - strip-ansi "^3.0.1" - wrap-ansi "^2.0.0" - -clone-regexp@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/clone-regexp/-/clone-regexp-1.0.0.tgz#eae0a2413f55c0942f818c229fefce845d7f3b1c" - dependencies: - is-regexp "^1.0.0" - is-supported-regexp-flag "^1.0.0" - -clone-stats@^0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-0.0.1.tgz#b88f94a82cf38b8791d58046ea4029ad88ca99d1" - -clone@^1.0.0, clone@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.2.tgz#260b7a99ebb1edfe247538175f783243cb19d149" - -cmd-shim@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/cmd-shim/-/cmd-shim-2.0.2.tgz#6fcbda99483a8fd15d7d30a196ca69d688a2efdb" - dependencies: - graceful-fs "^4.1.2" - mkdirp "~0.5.0" - -co@^4.6.0, co@=4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" - -co@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/co/-/co-3.1.0.tgz#4ea54ea5a08938153185e15210c68d9092bc1b78" - -coa@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/coa/-/coa-1.0.1.tgz#7f959346cfc8719e3f7233cd6852854a7c67d8a3" - dependencies: - q "^1.1.2" - -code-point-at@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" - -codemirror@^5.1.0: - version "5.20.2" - resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.20.2.tgz#918e0ece96d57a99030b2f8b33011284bed5217a" - -collapse-white-space@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/collapse-white-space/-/collapse-white-space-1.0.2.tgz#9c463fb9c6d190d2dcae21a356a01bcae9eeef6d" - -color-convert@^1.3.0: - version "1.8.2" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.8.2.tgz#be868184d7c8631766d54e7078e2672d7c7e3339" - dependencies: - color-name "^1.1.1" - -color-diff@^0.1.3: - version "0.1.7" - resolved "https://registry.yarnpkg.com/color-diff/-/color-diff-0.1.7.tgz#6db78cd9482a8e459d40821eaf4b503283dcb8e2" - -color-name@^1.0.0, color-name@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.1.tgz#4b1415304cf50028ea81643643bd82ea05803689" - -color-string@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/color-string/-/color-string-0.3.0.tgz#27d46fb67025c5c2fa25993bfbf579e47841b991" - dependencies: - color-name "^1.0.0" - -color@^0.11.0: - version "0.11.4" - resolved "https://registry.yarnpkg.com/color/-/color-0.11.4.tgz#6d7b5c74fb65e841cd48792ad1ed5e07b904d764" - dependencies: - clone "^1.0.2" - color-convert "^1.3.0" - color-string "^0.3.0" - -colorguard@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/colorguard/-/colorguard-1.2.0.tgz#f3facaf5caaeba4ef54653d9fb25bb73177c0d84" - dependencies: - chalk "^1.1.1" - color-diff "^0.1.3" - log-symbols "^1.0.2" - object-assign "^4.0.1" - pipetteur "^2.0.0" - plur "^2.0.0" - postcss "^5.0.4" - postcss-reporter "^1.2.1" - text-table "^0.2.0" - yargs "^1.2.6" - -colormin@^1.0.5: - version "1.1.2" - resolved "https://registry.yarnpkg.com/colormin/-/colormin-1.1.2.tgz#ea2f7420a72b96881a38aae59ec124a6f7298133" - dependencies: - color "^0.11.0" - css-color-names "0.0.4" - has "^1.0.1" - -colors@^1.0.3, colors@^1.1.2, colors@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" - -combined-stream@^1.0.5, combined-stream@~1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009" - dependencies: - delayed-stream "~1.0.0" - -command-join@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/command-join/-/command-join-1.1.1.tgz#09e7609012e1dd8b4f0a14fde41a69eff1d2111f" - dependencies: - array-from "^2.1.1" - repeat-string "^1.5.4" - -commander@^2.0.0, commander@^2.5.0, commander@^2.8.1, commander@^2.9.0, commander@2.9.0: - version "2.9.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" - dependencies: - graceful-readlink ">= 1.0.0" - -commander@0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-0.6.1.tgz#fa68a14f6a945d54dbbe50d8cdb3320e9e3b1a06" - -commander@2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.3.0.tgz#fd430e889832ec353b9acd1de217c11cb3eef873" - -commondir@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" - -commoner@^0.10.1: - version "0.10.4" - resolved "https://registry.yarnpkg.com/commoner/-/commoner-0.10.4.tgz#98f3333dd3ad399596bb2d384a783bb7213d68f8" - dependencies: - commander "^2.5.0" - detective "^4.3.1" - glob "^5.0.15" - graceful-fs "^4.1.2" - iconv-lite "^0.4.5" - mkdirp "^0.5.0" - private "^0.1.6" - q "^1.1.2" - recast "^0.10.0" - -compress-commons@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/compress-commons/-/compress-commons-1.1.0.tgz#9f4460bb1288564c7473916e0298aa3c320dcadb" - dependencies: - buffer-crc32 "^0.2.1" - crc32-stream "^1.0.0" - normalize-path "^2.0.0" - readable-stream "^2.0.0" - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - -concat-stream@^1.0.0, concat-stream@^1.4.6, concat-stream@^1.5.0, concat-stream@~1.5.0: - version "1.5.2" - resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.5.2.tgz#708978624d856af41a5a741defdd261da752c266" - dependencies: - inherits "~2.0.1" - readable-stream "~2.0.0" - typedarray "~0.0.5" - -console-browserify@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.1.0.tgz#f0241c45730a9fc6323b206dbf38edc741d0bb10" - dependencies: - date-now "^0.1.4" - -console-control-strings@^1.0.0, console-control-strings@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" - -constants-browserify@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-0.0.1.tgz#92577db527ba6c4cf0a4568d84bc031f441e21f2" - -content-disposition@0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.1.tgz#87476c6a67c8daa87e32e87616df883ba7fb071b" - -content-type@~1.0.1, content-type@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.2.tgz#b7d113aee7a8dd27bd21133c4dc2529df1721eed" - -convert-source-map@^1.1.0, convert-source-map@^1.1.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.3.0.tgz#e9f3e9c6e2728efc2676696a70eb382f73106a67" - -cookie-signature@1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" - -cookie@0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" - -core-js@^1.0.0: - version "1.2.7" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" - -core-js@^2.4.0: - version "2.4.1" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.4.1.tgz#4de911e667b0eae9124e34254b53aea6fc618d3e" - -core-util-is@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - -cosmiconfig@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-2.1.0.tgz#26e384a2055ea4e087050e5e08d53eb4eac8f86e" - dependencies: - graceful-fs "^4.1.2" - js-yaml "^3.4.3" - minimist "^1.2.0" - object-assign "^4.1.0" - os-homedir "^1.0.1" - parse-json "^2.2.0" - require-from-string "^1.1.0" - -crc32-stream@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/crc32-stream/-/crc32-stream-1.0.0.tgz#ea155e5e1d738ed3778438ffe92ffe2a141aeb3f" - dependencies: - buffer-crc32 "^0.2.1" - readable-stream "^2.0.0" - -create-error-class@^3.0.1: - version "3.0.2" - resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6" - dependencies: - capture-stack-trace "^1.0.0" - -cross-spawn@^4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-4.0.2.tgz#7b9247621c23adfdd3856004a823cbe397424d41" - dependencies: - lru-cache "^4.0.1" - which "^1.2.9" - -crypt@~0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.1.tgz#5f11b21a6c05ef1b5e79708366da6374ece1e6a2" - -cryptiles@2.x.x: - version "2.0.5" - resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" - dependencies: - boom "2.x.x" - -crypto-browserify@~3.2.6: - version "3.2.8" - resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.2.8.tgz#b9b11dbe6d9651dd882a01e6cc467df718ecf189" - dependencies: - pbkdf2-compat "2.0.1" - ripemd160 "0.2.0" - sha.js "2.2.6" - -css-color-names@0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.3.tgz#de0cef16f4d8aa8222a320d5b6d7e9bbada7b9f6" - -css-color-names@0.0.4: - version "0.0.4" - resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0" - -css-loader@^0.25.0: - version "0.25.0" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-0.25.0.tgz#c3febc8ce28f4c83576b6b13707f47f90c390223" - dependencies: - babel-code-frame "^6.11.0" - css-selector-tokenizer "^0.6.0" - cssnano ">=2.6.1 <4" - loader-utils "~0.2.2" - lodash.camelcase "^3.0.1" - object-assign "^4.0.1" - postcss "^5.0.6" - postcss-modules-extract-imports "^1.0.0" - postcss-modules-local-by-default "^1.0.1" - postcss-modules-scope "^1.0.0" - postcss-modules-values "^1.1.0" - source-list-map "^0.1.4" - -css-rule-stream@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/css-rule-stream/-/css-rule-stream-1.1.0.tgz#3786e7198983d965a26e31957e09078cbb7705a2" - dependencies: - css-tokenize "^1.0.1" - duplexer2 "0.0.2" - ldjson-stream "^1.2.1" - through2 "^0.6.3" - -css-selector-tokenizer@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/css-selector-tokenizer/-/css-selector-tokenizer-0.6.0.tgz#6445f582c7930d241dcc5007a43d6fcb8f073152" - dependencies: - cssesc "^0.1.0" - fastparse "^1.1.1" - regexpu-core "^1.0.0" - -css-tokenize@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/css-tokenize/-/css-tokenize-1.0.1.tgz#4625cb1eda21c143858b7f81d6803c1d26fc14be" - dependencies: - inherits "^2.0.1" - readable-stream "^1.0.33" - -cssesc@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-0.1.0.tgz#c814903e45623371a0477b40109aaafbeeaddbb4" - -"cssnano@>=2.6.1 <4": - version "3.8.0" - resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-3.8.0.tgz#bb90ac5292f42b679d9a05f6da0e9697556bb80d" - dependencies: - autoprefixer "^6.3.1" - decamelize "^1.1.2" - defined "^1.0.0" - has "^1.0.1" - object-assign "^4.0.1" - postcss "^5.0.14" - postcss-calc "^5.2.0" - postcss-colormin "^2.1.8" - postcss-convert-values "^2.3.4" - postcss-discard-comments "^2.0.4" - postcss-discard-duplicates "^2.0.1" - postcss-discard-empty "^2.0.1" - postcss-discard-overridden "^0.1.1" - postcss-discard-unused "^2.2.1" - postcss-filter-plugins "^2.0.0" - postcss-merge-idents "^2.1.5" - postcss-merge-longhand "^2.0.1" - postcss-merge-rules "^2.0.3" - postcss-minify-font-values "^1.0.2" - postcss-minify-gradients "^1.0.1" - postcss-minify-params "^1.0.4" - postcss-minify-selectors "^2.0.4" - postcss-normalize-charset "^1.1.0" - postcss-normalize-url "^3.0.7" - postcss-ordered-values "^2.1.0" - postcss-reduce-idents "^2.2.2" - postcss-reduce-initial "^1.0.0" - postcss-reduce-transforms "^1.0.3" - postcss-svgo "^2.1.1" - postcss-unique-selectors "^2.0.2" - postcss-value-parser "^3.2.3" - postcss-zindex "^2.0.1" - -csso@~2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/csso/-/csso-2.2.1.tgz#51fbb5347e50e81e6ed51668a48490ae6fe2afe2" - dependencies: - clap "^1.0.9" - source-map "^0.5.3" - -currently-unhandled@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" - dependencies: - array-find-index "^1.0.1" - -d@^0.1.1, d@~0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/d/-/d-0.1.1.tgz#da184c535d18d8ee7ba2aa229b914009fae11309" - dependencies: - es5-ext "~0.10.2" - -dashdash@^1.12.0: - version "1.14.0" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.0.tgz#29e486c5418bf0f356034a993d51686a33e84141" - dependencies: - assert-plus "^1.0.0" - -date-now@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" - -date-now@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/date-now/-/date-now-1.0.1.tgz#bb7d086438debe4182a485fb3df3fbfb99d6153c" - -debounce@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.0.0.tgz#0948af513d2e4ce407916f8506a423d3f9cf72d8" - dependencies: - date-now "1.0.1" - -debug@^2.0.0, debug@^2.1.1, debug@^2.2.0: - version "2.3.2" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.3.2.tgz#94cb466ef7d6d2c7e5245cdd6e4104f2d0d70d30" - dependencies: - ms "0.7.2" - -debug@~2.2.0, debug@2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da" - dependencies: - ms "0.7.1" - -decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2: - version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - -deep-extend@~0.4.0: - version "0.4.1" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.1.tgz#efe4113d08085f4e6f9687759810f807469e2253" - -deep-is@~0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" - -define-properties@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.2.tgz#83a73f2fea569898fb737193c8f873caf6d45c94" - dependencies: - foreach "^2.0.5" - object-keys "^1.0.8" - -defined@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" - -del@^2.0.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8" - dependencies: - globby "^5.0.0" - is-path-cwd "^1.0.0" - is-path-in-cwd "^1.0.0" - object-assign "^4.0.1" - pify "^2.0.0" - pinkie-promise "^2.0.0" - rimraf "^2.2.8" - -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - -delegates@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" - -depd@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.0.tgz#e1bd82c6aab6ced965b97b88b17ed3e528ca18c3" - -destroy@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" - -detab@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/detab/-/detab-1.0.2.tgz#01bc2a4abe7bc7cc67c3039808edbae47049a0ee" - dependencies: - repeat-string "^1.5.2" - -detect-indent@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" - dependencies: - repeating "^2.0.0" - -detective@^4.0.0, detective@^4.3.1: - version "4.3.2" - resolved "https://registry.yarnpkg.com/detective/-/detective-4.3.2.tgz#77697e2e7947ac3fe7c8e26a6d6f115235afa91c" - dependencies: - acorn "^3.1.0" - defined "^1.0.0" - -devtools-client-adapters@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/devtools-client-adapters/-/devtools-client-adapters-0.0.1.tgz#8f90c62aaa96ca4a079be0ee36e8b070ee8705a3" - dependencies: - chrome-remote-debugging-protocol "0.0.11" - devtools-config "^0.0.9" - devtools-modules "^0.0.9" - devtools-sham-modules "^0.0.9" - -devtools-config@^0.0.9: - version "0.0.9" - resolved "https://registry.yarnpkg.com/devtools-config/-/devtools-config-0.0.9.tgz#505712f3575f5991219a14a1cdd2a6da37d62a2c" - -devtools-local-toolbox@^0.0.10: - version "0.0.10" - resolved "https://registry.yarnpkg.com/devtools-local-toolbox/-/devtools-local-toolbox-0.0.10.tgz#34abb96d4452ac9674f61fd7df9cf095dc9bbeb6" - dependencies: - amd-loader "0.0.5" - babel-cli "^6.7.5" - babel-core "^6.17.0" - babel-eslint "^7.1.0" - babel-loader "^6.2.4" - babel-plugin-module-resolver "^2.2.0" - babel-plugin-transform-async-to-generator "^6.16.0" - babel-plugin-transform-es2015-block-scoping "^6.7.1" - babel-plugin-transform-es2015-destructuring "^6.6.5" - babel-plugin-transform-es2015-parameters "^6.7.0" - babel-plugin-transform-es2015-spread "^6.6.5" - babel-plugin-transform-flow-strip-types "^6.14.0" - babel-plugin-transform-runtime "^6.7.5" - babel-plugin-webpack-alias "^2.1.1" - babel-polyfill "^6.7.4" - babel-register "^6.18.0" - body-parser "^1.15.0" - check-node-version "^1.1.2" - chrome-remote-debugging-protocol "0.0.10" - classnames "^2.2.5" - co "=4.6.0" - css-loader "^0.25.0" - devtools-config "^0.0.9" - devtools-modules "^0.0.9" - devtools-network-request "^0.0.9" - devtools-sham-modules "^0.0.9" - eslint "^3.10.0" - eslint-plugin-babel "^3.3.0" - eslint-plugin-flowtype "^2.20.0" - eslint-plugin-mozilla "0.2.3" - eslint-plugin-react "^6.7.1" - express "^4.13.4" - extract-text-webpack-plugin "^1.0.1" - immutable "^3.7.6" - json-loader "^0.5.4" - minimist "^1.2.0" - mustache "^2.2.1" - react "=0.14.7" - react-dom "=0.14.7" - react-hot-loader "^1.3.0" - react-immutable-proptypes "^1.7.1" - react-inlinesvg "^0.5.3" - react-redux "4.4.5" - redux "3.5.2" - style-loader "^0.13.1" - svg-inline-loader "^0.7.1" - tcomb "^3.1.0" - webpack "1.13.1" - webpack-dev-middleware "^1.6.1" - webpack-env-loader-plugin "^0.1.4" - webpack-hot-middleware "^2.12.0" - ws "^1.0.1" - -devtools-modules@^0.0.9: - version "0.0.9" - resolved "https://registry.yarnpkg.com/devtools-modules/-/devtools-modules-0.0.9.tgz#cfd75ebcf35b6e673d6eb3223deb1738fe8ff0d7" - -devtools-network-request@^0.0.9: - version "0.0.9" - resolved "https://registry.yarnpkg.com/devtools-network-request/-/devtools-network-request-0.0.9.tgz#cdf51f4f21d7cb8cedba5b9d89e860ba531ddeb7" - -devtools-sham-modules@^0.0.9: - version "0.0.9" - resolved "https://registry.yarnpkg.com/devtools-sham-modules/-/devtools-sham-modules-0.0.9.tgz#f02f6f9d715e57ac36aa1f8495e5003b9fbfe994" - -diff@^1.3.2, diff@1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-1.4.0.tgz#7f28d2eb9ee7b15a97efd89ce63dcfdaa3ccbabf" - -disparity@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/disparity/-/disparity-2.0.0.tgz#57ddacb47324ae5f58d2cc0da886db4ce9eeb718" - dependencies: - ansi-styles "^2.0.1" - diff "^1.3.2" - -doctrine@^1.1.0, doctrine@^1.2.2: - version "1.5.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" - dependencies: - esutils "^2.0.2" - isarray "^1.0.0" - -documentation@^4.0.0-beta11: - version "4.0.0-beta9" - resolved "https://registry.yarnpkg.com/documentation/-/documentation-4.0.0-beta9.tgz#8221b25286ce9563c7c9bb7710241255ccd2ee79" - dependencies: - ansi-html "0.0.5" - babel-core "^6.5.2" - babel-plugin-transform-decorators-legacy "1.3.4" - babel-preset-es2015 "^6.5.0" - babel-preset-react "^6.5.0" - babel-preset-stage-0 "^6.5.0" - babel-traverse "^6.5.0" - babel-types "^6.7.2" - babelify "^7.2.0" - babylon "^6.5.2" - chalk "^1.1.1" - chokidar "^1.2.0" - concat-stream "^1.5.0" - debounce "^1.0.0" - disparity "^2.0.0" - doctrine "^1.1.0" - events "^1.1.0" - extend "^3.0.0" - get-comments "^1.0.1" - git-url-parse "^6.0.1" - github-slugger "1.1.1" - globals-docs "2.2.0" - highlight.js "^9.1.0" - js-yaml "^3.3.1" - lodash "^4.11.1" - mdast-util-inject "^1.1.0" - micromatch "^2.1.6" - mime "^1.3.4" - module-deps-sortable "4.0.6" - parse-filepath "^0.6.3" - remark "^4.1.2" - remark-html "3.0.0" - remark-toc "^3.0.0" - remote-origin-url "0.4.0" - resolve "^1.1.6" - stream-array "^1.1.0" - strip-json-comments "^2.0.0" - tiny-lr "^0.2.1" - unist-builder "^1.0.0" - unist-util-visit "^1.0.1" - vfile "^1.1.2" - vfile-reporter "^2.0.0" - vfile-sort "^1.0.0" - vinyl "^1.1.0" - vinyl-fs "^2.3.1" - yargs "^4.3.1" - -doiuse@^2.4.1: - version "2.5.0" - resolved "https://registry.yarnpkg.com/doiuse/-/doiuse-2.5.0.tgz#c7f156965d054bf4d699a4067af1cadbc7350b7c" - dependencies: - browserslist "^1.1.1" - caniuse-db "^1.0.30000187" - css-rule-stream "^1.1.0" - duplexer2 "0.0.2" - jsonfilter "^1.1.2" - ldjson-stream "^1.2.1" - lodash "^4.0.0" - multimatch "^2.0.0" - postcss "^5.0.8" - source-map "^0.4.2" - through2 "^0.6.3" - yargs "^3.5.4" - -domain-browser@^1.1.1: - version "1.1.7" - resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.1.7.tgz#867aa4b093faa05f1de08c06f4d7b21fdf8698bc" - -duplexer@~0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" - -duplexer2@^0.1.2, duplexer2@^0.1.4, duplexer2@~0.1.0: - version "0.1.4" - resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1" - dependencies: - readable-stream "^2.0.2" - -duplexer2@0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.0.2.tgz#c614dcf67e2fb14995a91711e5a617e8a60a31db" - dependencies: - readable-stream "~1.1.9" - -duplexify@^3.2.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.5.0.tgz#1aa773002e1578457e9d9d4a50b0ccaaebcbd604" - dependencies: - end-of-stream "1.0.0" - inherits "^2.0.1" - readable-stream "^2.0.0" - stream-shift "^1.0.0" - -eastasianwidth@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.1.1.tgz#44d656de9da415694467335365fb3147b8572b7c" - -ecc-jsbn@~0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" - dependencies: - jsbn "~0.1.0" - -ee-first@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" - -elegant-spinner@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/elegant-spinner/-/elegant-spinner-1.0.1.tgz#db043521c95d7e303fd8f345bedc3349cfb0729e" - -emoji-regex@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-6.0.0.tgz#df6d704ae667c7d3af89b37dc664b3048996024d" - -emojis-list@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" - -encodeurl@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.1.tgz#79e3d58655346909fe6f0f45a5de68103b294d20" - -encoding@^0.1.11: - version "0.1.12" - resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" - dependencies: - iconv-lite "~0.4.13" - -end-of-stream@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.1.0.tgz#e9353258baa9108965efc41cb0ef8ade2f3cfb07" - dependencies: - once "~1.3.0" - -end-of-stream@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.0.0.tgz#d4596e702734a93e40e9af864319eabd99ff2f0e" - dependencies: - once "~1.3.0" - -enhanced-resolve@~0.9.0: - version "0.9.1" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-0.9.1.tgz#4d6e689b3725f86090927ccc86cd9f1635b89e2e" - dependencies: - graceful-fs "^4.1.2" - memory-fs "^0.2.0" - tapable "^0.1.8" - -envify@^3.0.0: - version "3.4.1" - resolved "https://registry.yarnpkg.com/envify/-/envify-3.4.1.tgz#d7122329e8df1688ba771b12501917c9ce5cbce8" - dependencies: - jstransform "^11.0.3" - through "~2.3.4" - -errno@^0.1.3: - version "0.1.4" - resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.4.tgz#b896e23a9e5e8ba33871fc996abd3635fc9a1c7d" - dependencies: - prr "~0.0.0" - -error-ex@^1.2.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.0.tgz#e67b43f3e82c96ea3a584ffee0b9fc3325d802d9" - dependencies: - is-arrayish "^0.2.1" - -es-abstract@^1.5.0: - version "1.6.1" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.6.1.tgz#bb8a2064120abcf928a086ea3d9043114285ec99" - dependencies: - es-to-primitive "^1.1.1" - function-bind "^1.1.0" - is-callable "^1.1.3" - is-regex "^1.0.3" - -es-to-primitive@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.1.1.tgz#45355248a88979034b6792e19bb81f2b7975dd0d" - dependencies: - is-callable "^1.1.1" - is-date-object "^1.0.1" - is-symbol "^1.0.1" - -es5-ext@^0.10.7, es5-ext@^0.10.8, es5-ext@~0.10.11, es5-ext@~0.10.2, es5-ext@~0.10.7: - version "0.10.12" - resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.12.tgz#aa84641d4db76b62abba5e45fd805ecbab140047" - dependencies: - es6-iterator "2" - es6-symbol "~3.1" - -es6-iterator@2: - version "2.0.0" - resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.0.tgz#bd968567d61635e33c0b80727613c9cb4b096bac" - dependencies: - d "^0.1.1" - es5-ext "^0.10.7" - es6-symbol "3" - -es6-map@^0.1.3: - version "0.1.4" - resolved "https://registry.yarnpkg.com/es6-map/-/es6-map-0.1.4.tgz#a34b147be224773a4d7da8072794cefa3632b897" - dependencies: - d "~0.1.1" - es5-ext "~0.10.11" - es6-iterator "2" - es6-set "~0.1.3" - es6-symbol "~3.1.0" - event-emitter "~0.3.4" - -es6-set@~0.1.3: - version "0.1.4" - resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.4.tgz#9516b6761c2964b92ff479456233a247dc707ce8" - dependencies: - d "~0.1.1" - es5-ext "~0.10.11" - es6-iterator "2" - es6-symbol "3" - event-emitter "~0.3.4" - -es6-symbol@~3.1, es6-symbol@~3.1.0, es6-symbol@3: - version "3.1.0" - resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.0.tgz#94481c655e7a7cad82eba832d97d5433496d7ffa" - dependencies: - d "~0.1.1" - es5-ext "~0.10.11" - -es6-weak-map@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.1.tgz#0d2bbd8827eb5fb4ba8f97fbfea50d43db21ea81" - dependencies: - d "^0.1.1" - es5-ext "^0.10.8" - es6-iterator "2" - es6-symbol "3" - -escape-html@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" - -escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5, escape-string-regexp@1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - -escape-string-regexp@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz#4dbc2fe674e71949caf3fb2695ce7f2dc1d9a8d1" - -escope@^3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/escope/-/escope-3.6.0.tgz#e01975e812781a163a6dadfdd80398dc64c889c3" - dependencies: - es6-map "^0.1.3" - es6-weak-map "^2.0.1" - esrecurse "^4.1.0" - estraverse "^4.1.1" - -eslint-plugin-babel@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-babel/-/eslint-plugin-babel-3.3.0.tgz#2f494aedcf6f4aa4e75b9155980837bc1fbde193" - -eslint-plugin-flowtype@^2.20.0: - version "2.25.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-2.25.0.tgz#c462521ab20ce3d8db819f10ad3c9f1bc7f3f819" - dependencies: - lodash "^4.15.0" - -eslint-plugin-mozilla@0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/eslint-plugin-mozilla/-/eslint-plugin-mozilla-0.2.3.tgz#4deb85afb52f3622444c59420e005dc3ef44851b" - dependencies: - escope "^3.6.0" - espree "^3.2.0" - estraverse "^4.2.0" - sax "^1.1.4" - -eslint-plugin-react@^6.7.1: - version "6.7.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-6.7.1.tgz#1af96aea545856825157d97c1b50d5a8fb64a5a7" - dependencies: - doctrine "^1.2.2" - jsx-ast-utils "^1.3.3" - -eslint@^3.10.0: - version "3.10.2" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-3.10.2.tgz#c9a10e8bf6e9d65651204778c503341f1eac3ce7" - dependencies: - babel-code-frame "^6.16.0" - chalk "^1.1.3" - concat-stream "^1.4.6" - debug "^2.1.1" - doctrine "^1.2.2" - escope "^3.6.0" - espree "^3.3.1" - estraverse "^4.2.0" - esutils "^2.0.2" - file-entry-cache "^2.0.0" - glob "^7.0.3" - globals "^9.2.0" - ignore "^3.2.0" - imurmurhash "^0.1.4" - inquirer "^0.12.0" - is-my-json-valid "^2.10.0" - is-resolvable "^1.0.0" - js-yaml "^3.5.1" - json-stable-stringify "^1.0.0" - levn "^0.3.0" - lodash "^4.0.0" - mkdirp "^0.5.0" - natural-compare "^1.4.0" - optionator "^0.8.2" - path-is-inside "^1.0.1" - pluralize "^1.2.1" - progress "^1.1.8" - require-uncached "^1.0.2" - shelljs "^0.7.5" - strip-bom "^3.0.0" - strip-json-comments "~1.0.1" - table "^3.7.8" - text-table "~0.2.0" - user-home "^2.0.0" - -espree@^3.2.0, espree@^3.3.1: - version "3.3.2" - resolved "https://registry.yarnpkg.com/espree/-/espree-3.3.2.tgz#dbf3fadeb4ecb4d4778303e50103b3d36c88b89c" - dependencies: - acorn "^4.0.1" - acorn-jsx "^3.0.0" - -esprima-fb@^15001.1.0-dev-harmony-fb: - version "15001.1.0-dev-harmony-fb" - resolved "https://registry.yarnpkg.com/esprima-fb/-/esprima-fb-15001.1.0-dev-harmony-fb.tgz#30a947303c6b8d5e955bee2b99b1d233206a6901" - -esprima-fb@~15001.1001.0-dev-harmony-fb: - version "15001.1001.0-dev-harmony-fb" - resolved "https://registry.yarnpkg.com/esprima-fb/-/esprima-fb-15001.1001.0-dev-harmony-fb.tgz#43beb57ec26e8cf237d3dd8b33e42533577f2659" - -esprima@^2.6.0: - version "2.7.3" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" - -esrecurse@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.1.0.tgz#4713b6536adf7f2ac4f327d559e7756bff648220" - dependencies: - estraverse "~4.1.0" - object-assign "^4.0.1" - -estraverse@^4.1.1, estraverse@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" - -estraverse@~4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.1.1.tgz#f6caca728933a850ef90661d0e17982ba47111a2" - -esutils@^2.0.0, esutils@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" - -etag@~1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/etag/-/etag-1.7.0.tgz#03d30b5f67dd6e632d2945d30d6652731a34d5d8" - -event-emitter@~0.3.4: - version "0.3.4" - resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.4.tgz#8d63ddfb4cfe1fae3b32ca265c4c720222080bb5" - dependencies: - d "~0.1.1" - es5-ext "~0.10.7" - -events@^1.0.0, events@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" - -execall@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/execall/-/execall-1.0.0.tgz#73d0904e395b3cab0658b08d09ec25307f29bb73" - dependencies: - clone-regexp "^1.0.0" - -exit-hook@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8" - -expand-brackets@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" - dependencies: - is-posix-bracket "^0.1.0" - -expand-range@^1.8.1: - version "1.8.2" - resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" - dependencies: - fill-range "^2.1.0" - -expect.js@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/expect.js/-/expect.js-0.3.1.tgz#b0a59a0d2eff5437544ebf0ceaa6015841d09b5b" - -express@^4.13.4: - version "4.14.0" - resolved "https://registry.yarnpkg.com/express/-/express-4.14.0.tgz#c1ee3f42cdc891fb3dc650a8922d51ec847d0d66" - dependencies: - accepts "~1.3.3" - array-flatten "1.1.1" - content-disposition "0.5.1" - content-type "~1.0.2" - cookie "0.3.1" - cookie-signature "1.0.6" - debug "~2.2.0" - depd "~1.1.0" - encodeurl "~1.0.1" - escape-html "~1.0.3" - etag "~1.7.0" - finalhandler "0.5.0" - fresh "0.3.0" - merge-descriptors "1.0.1" - methods "~1.1.2" - on-finished "~2.3.0" - parseurl "~1.3.1" - path-to-regexp "0.1.7" - proxy-addr "~1.1.2" - qs "6.2.0" - range-parser "~1.2.0" - send "0.14.1" - serve-static "~1.11.1" - type-is "~1.6.13" - utils-merge "1.0.0" - vary "~1.1.0" - -extend-shallow@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" - dependencies: - is-extendable "^0.1.0" - -extend@^3.0.0, extend@~3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.0.tgz#5a474353b9f3353ddd8176dfd37b91c83a46f1d4" - -extglob@^0.3.1: - version "0.3.2" - resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" - dependencies: - is-extglob "^1.0.0" - -extract-text-webpack-plugin@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/extract-text-webpack-plugin/-/extract-text-webpack-plugin-1.0.1.tgz#c95bf3cbaac49dc96f1dc6e072549fbb654ccd2c" - dependencies: - async "^1.5.0" - loader-utils "^0.2.3" - webpack-sources "^0.1.0" - -extsprintf@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.0.2.tgz#e1080e0658e300b06294990cc70e1502235fd550" - -fast-levenshtein@~2.0.4: - version "2.0.5" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.5.tgz#bd33145744519ab1c36c3ee9f31f08e9079b67f2" - -fastparse@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/fastparse/-/fastparse-1.1.1.tgz#d1e2643b38a94d7583b479060e6c4affc94071f8" - -faye-websocket@~0.10.0: - version "0.10.0" - resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4" - dependencies: - websocket-driver ">=0.5.1" - -fbjs@^0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.6.1.tgz#9636b7705f5ba9684d44b72f78321254afc860f7" - dependencies: - core-js "^1.0.0" - loose-envify "^1.0.0" - promise "^7.0.3" - ua-parser-js "^0.7.9" - whatwg-fetch "^0.9.0" - -fbjs@^0.8, fbjs@^0.8.4: - version "0.8.6" - resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.6.tgz#7eb67d6986b2d5007a9b6e92e0e7cb6f75cad290" - dependencies: - core-js "^1.0.0" - isomorphic-fetch "^2.1.1" - loose-envify "^1.0.0" - object-assign "^4.1.0" - promise "^7.1.1" - ua-parser-js "^0.7.9" - -figures@^1.3.5: - version "1.7.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" - dependencies: - escape-string-regexp "^1.0.5" - object-assign "^4.1.0" - -file-entry-cache@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361" - dependencies: - flat-cache "^1.2.1" - object-assign "^4.0.1" - -filename-regex@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.0.tgz#996e3e80479b98b9897f15a8a58b3d084e926775" - -fill-range@^2.1.0: - version "2.2.3" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723" - dependencies: - is-number "^2.1.0" - isobject "^2.0.0" - randomatic "^1.1.3" - repeat-element "^1.1.2" - repeat-string "^1.5.2" - -finalhandler@0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-0.5.0.tgz#e9508abece9b6dba871a6942a1d7911b91911ac7" - dependencies: - debug "~2.2.0" - escape-html "~1.0.3" - on-finished "~2.3.0" - statuses "~1.3.0" - unpipe "~1.0.0" - -find-babel-config@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/find-babel-config/-/find-babel-config-1.0.1.tgz#179fa7b36bf3e94b487410855df448b6f853b9ec" - dependencies: - json5 "^0.5.0" - path-exists "^3.0.0" - -find-cache-dir@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-0.1.1.tgz#c8defae57c8a52a8a784f9e31c57c742e993a0b9" - dependencies: - commondir "^1.0.1" - mkdirp "^0.5.1" - pkg-dir "^1.0.0" - -find-up@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" - dependencies: - path-exists "^2.0.0" - pinkie-promise "^2.0.0" - -find-up@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.0.0.tgz#71e6dc2dad9222143cfc0fa5de7ab739e7320c05" - dependencies: - path-exists "^2.0.0" - -firefox-profile@^0.4.0: - version "0.4.3" - resolved "https://registry.yarnpkg.com/firefox-profile/-/firefox-profile-0.4.3.tgz#21ea2095add3c5273e10777bfe6ea7680525dd90" - dependencies: - adm-zip "~0.4.x" - archiver "~1.2.0" - async "~2.1.2" - fs-extra "~1.0.0" - ini "~1.3.3" - jetpack-id "1.0.0" - lazystream "~1.0.0" - lodash "~4.16.0" - minimist "^1.1.1" - node-uuid "~1.4.7" - xml2js "~0.4.4" - -first-chunk-stream@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/first-chunk-stream/-/first-chunk-stream-1.0.0.tgz#59bfb50cd905f60d7c394cd3d9acaab4e6ad934e" - -flat-cache@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.2.1.tgz#6c837d6225a7de5659323740b36d5361f71691ff" - dependencies: - circular-json "^0.3.0" - del "^2.0.2" - graceful-fs "^4.1.2" - write "^0.2.1" - -flatten@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782" - -flow-bin@^0.35.0: - version "0.35.0" - resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.35.0.tgz#63d4eb9582ce352541be98e6a424503217141b07" - -flow-coverage-report@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/flow-coverage-report/-/flow-coverage-report-0.2.0.tgz#8529729ecc440c676c5960b32d1393d2eeddad57" - dependencies: - array.prototype.find "2.0.0" - babel-runtime "6.11.6" - glob "7.0.5" - minimatch "3.0.3" - mkdirp "0.5.1" - react "15.3.1" - react-dom "15.3.1" - temp "0.8.3" - terminal-table "0.0.12" - yargs "5.0.0" - -for-in@^0.1.5: - version "0.1.6" - resolved "https://registry.yarnpkg.com/for-in/-/for-in-0.1.6.tgz#c9f96e89bfad18a545af5ec3ed352a1d9e5b4dc8" - -for-own@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.4.tgz#0149b41a39088c7515f51ebe1c1386d45f935072" - dependencies: - for-in "^0.1.5" - -foreach@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" - -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - -form-data@~2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.2.tgz#89c3534008b97eada4cbb157d58f6f5df025eae4" - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.5" - mime-types "^2.1.12" - -forwarded@~0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.0.tgz#19ef9874c4ae1c297bcf078fde63a09b66a84363" - -fresh@0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.3.0.tgz#651f838e22424e7566de161d8358caa199f83d4f" - -fs-extra@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-1.0.0.tgz#cd3ce5f7e7cb6145883fcae3191e9877f8587950" - dependencies: - graceful-fs "^4.1.2" - jsonfile "^2.1.0" - klaw "^1.0.0" - -fs-readdir-recursive@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.0.0.tgz#8cd1745c8b4f8a29c8caec392476921ba195f560" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - -fsevents@^1.0.0: - version "1.0.15" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.0.15.tgz#fa63f590f3c2ad91275e4972a6cea545fb0aae44" - dependencies: - nan "^2.3.0" - node-pre-gyp "^0.6.29" - -fstream-ignore@~1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/fstream-ignore/-/fstream-ignore-1.0.5.tgz#9c31dae34767018fe1d249b24dada67d092da105" - dependencies: - fstream "^1.0.0" - inherits "2" - minimatch "^3.0.0" - -fstream@^1.0.0, fstream@^1.0.2, fstream@^1.0.8, fstream@~1.0.10: - version "1.0.10" - resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.10.tgz#604e8a92fe26ffd9f6fae30399d4984e1ab22822" - dependencies: - graceful-fs "^4.1.2" - inherits "~2.0.0" - mkdirp ">=0.5 0" - rimraf "2" - -function-bind@^1.0.2, function-bind@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.0.tgz#16176714c801798e4e8f2cf7f7529467bb4a5771" - -fuzzaldrin-plus@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/fuzzaldrin-plus/-/fuzzaldrin-plus-0.3.1.tgz#36c4e0501ad08cfa6ac83d0ddc8f8ef535b901b4" - -gather-stream@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/gather-stream/-/gather-stream-1.0.0.tgz#b33994af457a8115700d410f317733cbe7a0904b" - -gauge@~2.7.1: - version "2.7.1" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.1.tgz#388473894fe8be5e13ffcdb8b93e4ed0616428c7" - dependencies: - aproba "^1.0.3" - console-control-strings "^1.0.0" - has-color "^0.1.7" - has-unicode "^2.0.0" - object-assign "^4.1.0" - signal-exit "^3.0.0" - string-width "^1.0.1" - strip-ansi "^3.0.1" - wide-align "^1.1.0" - -geckodriver@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/geckodriver/-/geckodriver-1.2.0.tgz#2bdacece5ad0e21d0b040c308a94e7622e88b4ac" - dependencies: - adm-zip "0.4.7" - bluebird "3.4.6" - got "5.6.0" - tar.gz "1.0.5" - -generate-function@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.0.0.tgz#6858fe7c0969b7d4e9093337647ac79f60dfbe74" - -generate-object-property@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0" - dependencies: - is-property "^1.0.0" - -get-caller-file@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5" - -get-comments@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/get-comments/-/get-comments-1.0.1.tgz#196759101bbbc4facf13060caaedd4870dee55be" - -get-stdin@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" - -get-stdin@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-5.0.1.tgz#122e161591e21ff4c52530305693f20e6393a398" - -getpass@^0.1.1: - version "0.1.6" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.6.tgz#283ffd9fc1256840875311c1b60e8c40187110e6" - dependencies: - assert-plus "^1.0.0" - -git-up@^2.0.0: - version "2.0.6" - resolved "https://registry.yarnpkg.com/git-up/-/git-up-2.0.6.tgz#38d6dddc5db720de83ef09ef3865e748f5887e12" - dependencies: - is-ssh "^1.3.0" - parse-url "^1.3.0" - -git-url-parse@^6.0.1: - version "6.1.0" - resolved "https://registry.yarnpkg.com/git-url-parse/-/git-url-parse-6.1.0.tgz#01a99f11ca4def4d88d9886da7f84d75d114495b" - dependencies: - git-up "^2.0.0" - -github-slugger@^1.0.0, github-slugger@^1.1.1, github-slugger@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/github-slugger/-/github-slugger-1.1.1.tgz#5444671f65e5a5a424cfa8ba3255cc1f7baf07ea" - dependencies: - emoji-regex "^6.0.0" - -glob-base@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" - dependencies: - glob-parent "^2.0.0" - is-glob "^2.0.0" - -glob-parent@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" - dependencies: - is-glob "^2.0.0" - -glob-parent@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.0.1.tgz#60021327cc963ddc3b5f085764f500479ecd82ff" - dependencies: - is-glob "^3.1.0" - path-dirname "^1.0.0" - -glob-stream@^5.3.2: - version "5.3.5" - resolved "https://registry.yarnpkg.com/glob-stream/-/glob-stream-5.3.5.tgz#a55665a9a8ccdc41915a87c701e32d4e016fad22" - dependencies: - extend "^3.0.0" - glob "^5.0.3" - glob-parent "^3.0.0" - micromatch "^2.3.7" - ordered-read-streams "^0.3.0" - through2 "^0.6.0" - to-absolute-glob "^0.1.1" - unique-stream "^2.0.2" - -glob@^5.0.15, glob@^5.0.3, glob@^5.0.5: - version "5.0.15" - resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" - dependencies: - inflight "^1.0.4" - inherits "2" - minimatch "2 || 3" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^6.0.1: - version "6.0.4" - resolved "https://registry.yarnpkg.com/glob/-/glob-6.0.4.tgz#0f08860f6a155127b2fadd4f9ce24b1aab6e4d22" - dependencies: - inflight "^1.0.4" - inherits "2" - minimatch "2 || 3" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8" - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.2" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@3.2.11: - version "3.2.11" - resolved "https://registry.yarnpkg.com/glob/-/glob-3.2.11.tgz#4a973f635b9190f715d10987d5c00fd2815ebe3d" - dependencies: - inherits "2" - minimatch "0.3" - -glob@7.0.5: - version "7.0.5" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.0.5.tgz#b4202a69099bbb4d292a7c1b95b6682b67ebdc95" - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.2" - once "^1.3.0" - path-is-absolute "^1.0.0" - -globals-docs@2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/globals-docs/-/globals-docs-2.2.0.tgz#28d9e2937cb9a6bce7e786510a5d4e337d61d3ef" - -globals@^9.0.0, globals@^9.2.0: - version "9.13.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-9.13.0.tgz#d97706b61600d8dbe94708c367d3fdcf48470b8f" - -globby@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-4.1.0.tgz#080f54549ec1b82a6c60e631fc82e1211dbe95f8" - dependencies: - array-union "^1.0.1" - arrify "^1.0.0" - glob "^6.0.1" - object-assign "^4.0.1" - pify "^2.0.0" - pinkie-promise "^2.0.0" - -globby@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d" - dependencies: - array-union "^1.0.1" - arrify "^1.0.0" - glob "^7.0.3" - object-assign "^4.0.1" - pify "^2.0.0" - pinkie-promise "^2.0.0" - -globby@^6.0.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" - dependencies: - array-union "^1.0.1" - glob "^7.0.3" - object-assign "^4.0.1" - pify "^2.0.0" - pinkie-promise "^2.0.0" - -globjoin@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/globjoin/-/globjoin-0.1.4.tgz#2f4494ac8919e3767c5cbb691e9f463324285d43" - -got@5.6.0: - version "5.6.0" - resolved "https://registry.yarnpkg.com/got/-/got-5.6.0.tgz#bb1d7ee163b78082bbc8eb836f3f395004ea6fbf" - dependencies: - create-error-class "^3.0.1" - duplexer2 "^0.1.4" - is-plain-obj "^1.0.0" - is-redirect "^1.0.0" - is-retry-allowed "^1.0.0" - is-stream "^1.0.0" - lowercase-keys "^1.0.0" - node-status-codes "^1.0.0" - object-assign "^4.0.1" - parse-json "^2.1.0" - pinkie-promise "^2.0.0" - read-all-stream "^3.0.0" - readable-stream "^2.0.5" - timed-out "^2.0.0" - unzip-response "^1.0.0" - url-parse-lax "^1.0.0" - -graceful-fs@^4.0.0, graceful-fs@^4.1.0, graceful-fs@^4.1.2, graceful-fs@^4.1.4, graceful-fs@^4.1.6, graceful-fs@^4.1.9: - version "4.1.10" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.10.tgz#f2d720c22092f743228775c75e3612632501f131" - -"graceful-readlink@>= 1.0.0": - version "1.0.1" - resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" - -growl@1.9.2: - version "1.9.2" - resolved "https://registry.yarnpkg.com/growl/-/growl-1.9.2.tgz#0ea7743715db8d8de2c5ede1775e1b45ac85c02f" - -gulp-sourcemaps@1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/gulp-sourcemaps/-/gulp-sourcemaps-1.6.0.tgz#b86ff349d801ceb56e1d9e7dc7bbcb4b7dee600c" - dependencies: - convert-source-map "^1.1.1" - graceful-fs "^4.1.2" - strip-bom "^2.0.0" - through2 "^2.0.0" - vinyl "^1.0.0" - -har-validator@~2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-2.0.6.tgz#cdcbc08188265ad119b6a5a7c8ab70eecfb5d27d" - dependencies: - chalk "^1.1.1" - commander "^2.9.0" - is-my-json-valid "^2.12.4" - pinkie-promise "^2.0.0" - -has-ansi@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" - dependencies: - ansi-regex "^2.0.0" - -has-color@^0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/has-color/-/has-color-0.1.7.tgz#67144a5260c34fc3cca677d041daf52fe7b78b2f" - -has-flag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" - -has-unicode@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" - -has@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.1.tgz#8461733f538b0837c9361e39a9ab9e9704dc2f28" - dependencies: - function-bind "^1.0.2" - -hawk@~3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" - dependencies: - boom "2.x.x" - cryptiles "2.x.x" - hoek "2.x.x" - sntp "1.x.x" - -highlight.js@^9.1.0: - version "9.8.0" - resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.8.0.tgz#38eeef40cd45eaddbec8c9e5238fb7a783a3b685" - -hoek@2.x.x: - version "2.16.3" - resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" - -hoist-non-react-statics@^1.0.3: - version "1.2.0" - resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-1.2.0.tgz#aa448cf0986d55cc40773b17174b7dd066cb7cfb" - -home-or-tmp@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" - dependencies: - os-homedir "^1.0.0" - os-tmpdir "^1.0.1" - -hosted-git-info@^2.1.4: - version "2.1.5" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.1.5.tgz#0ba81d90da2e25ab34a332e6ec77936e1598118b" - -html-comment-regex@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/html-comment-regex/-/html-comment-regex-1.1.1.tgz#668b93776eaae55ebde8f3ad464b307a4963625e" - -html-entities@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.2.0.tgz#41948caf85ce82fed36e4e6a0ed371a6664379e2" - -html-tags@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-1.1.1.tgz#869f43859f12d9bdc3892419e494a628aa1b204e" - -http-browserify@^1.3.2: - version "1.7.0" - resolved "https://registry.yarnpkg.com/http-browserify/-/http-browserify-1.7.0.tgz#33795ade72df88acfbfd36773cefeda764735b20" - dependencies: - Base64 "~0.2.0" - inherits "~2.0.1" - -http-errors@~1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.3.1.tgz#197e22cdebd4198585e8694ef6786197b91ed942" - dependencies: - inherits "~2.0.1" - statuses "1" - -http-errors@~1.5.0: - version "1.5.1" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.5.1.tgz#788c0d2c1de2c81b9e6e8c01843b6b97eb920750" - dependencies: - inherits "2.0.3" - setprototypeof "1.0.2" - statuses ">= 1.3.1 < 2" - -http-signature@~1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf" - dependencies: - assert-plus "^0.2.0" - jsprim "^1.2.2" - sshpk "^1.7.0" - -httpplease@^0.16: - version "0.16.4" - resolved "https://registry.yarnpkg.com/httpplease/-/httpplease-0.16.4.tgz#d382ebe230ef5079080b4e9ffebf316a9e75c0da" - dependencies: - urllite "~0.5.0" - xmlhttprequest "*" - xtend "~3.0.0" - -https-browserify@0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-0.0.0.tgz#b3ffdfe734b2a3d4a9efd58e8654c91fce86eafd" - -husky@^0.11.7: - version "0.11.9" - resolved "https://registry.yarnpkg.com/husky/-/husky-0.11.9.tgz#28cd1dc16bffdca1d4d93592814e5f3c327b38ee" - dependencies: - is-ci "^1.0.9" - normalize-path "^1.0.0" - -iconv-lite@^0.4.5, iconv-lite@~0.4.13, iconv-lite@0.4.13: - version "0.4.13" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.13.tgz#1f88aba4ab0b1508e8312acc39345f36e992e2f2" - -icss-replace-symbols@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/icss-replace-symbols/-/icss-replace-symbols-1.0.2.tgz#cb0b6054eb3af6edc9ab1d62d01933e2d4c8bfa5" - -ieee754@^1.1.4: - version "1.1.8" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4" - -ignore@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.2.0.tgz#8d88f03c3002a0ac52114db25d2c673b0bf1e435" - -immutable@^3.7.6: - version "3.8.1" - resolved "https://registry.yarnpkg.com/immutable/-/immutable-3.8.1.tgz#200807f11ab0f72710ea485542de088075f68cd2" - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - -indent-string@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" - dependencies: - repeating "^2.0.0" - -indexes-of@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" - -indexof@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d" - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@^2.0.1, inherits@~2.0.0, inherits@~2.0.1, inherits@2, inherits@2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - -inherits@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" - -ini@^1.3.3, ini@~1.3.0, ini@~1.3.3: - version "1.3.4" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e" - -inquirer@^0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-0.12.0.tgz#1ef2bfd63504df0bc75785fff8c2c41df12f077e" - dependencies: - ansi-escapes "^1.1.0" - ansi-regex "^2.0.0" - chalk "^1.0.0" - cli-cursor "^1.0.1" - cli-width "^2.0.0" - figures "^1.3.5" - lodash "^4.3.0" - readline2 "^1.0.1" - run-async "^0.1.0" - rx-lite "^3.1.2" - string-width "^1.0.1" - strip-ansi "^3.0.0" - through "^2.3.6" - -interpret@^0.6.4: - version "0.6.6" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-0.6.6.tgz#fecd7a18e7ce5ca6abfb953e1f86213a49f1625b" - -interpret@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.1.tgz#d579fb7f693b858004947af39fa0db49f795602c" - -invariant@^2.0.0, invariant@^2.2.0, invariant@^2.2.1: - version "2.2.2" - resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360" - dependencies: - loose-envify "^1.0.0" - -invert-kv@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" - -ipaddr.js@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.1.1.tgz#c791d95f52b29c1247d5df80ada39b8a73647230" - -irregular-plurals@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/irregular-plurals/-/irregular-plurals-1.2.0.tgz#38f299834ba8c00c30be9c554e137269752ff3ac" - -is-absolute-url@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-2.0.0.tgz#9c4b20b0e5c0cbef9a479a367ede6f991679f359" - -is-absolute@^0.2.2: - version "0.2.6" - resolved "https://registry.yarnpkg.com/is-absolute/-/is-absolute-0.2.6.tgz#20de69f3db942ef2d87b9c2da36f172235b1b5eb" - dependencies: - is-relative "^0.2.1" - is-windows "^0.2.0" - -is-alphabetical@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-1.0.0.tgz#e2544c13058255f2144cb757066cd3342a1c8c46" - -is-alphanumerical@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-alphanumerical/-/is-alphanumerical-1.0.0.tgz#e06492e719c1bf15dec239e4f1af5f67b4d6e7bf" - dependencies: - is-alphabetical "^1.0.0" - is-decimal "^1.0.0" - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - -is-binary-path@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" - dependencies: - binary-extensions "^1.0.0" - -is-buffer@^1.0.2, is-buffer@~1.1.1: - version "1.1.4" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.4.tgz#cfc86ccd5dc5a52fa80489111c6920c457e2d98b" - -is-builtin-module@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" - dependencies: - builtin-modules "^1.0.0" - -is-callable@^1.1.1, is-callable@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.3.tgz#86eb75392805ddc33af71c92a0eedf74ee7604b2" - -is-ci@^1.0.9: - version "1.0.10" - resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.0.10.tgz#f739336b2632365061a9d48270cd56ae3369318e" - dependencies: - ci-info "^1.0.0" - -is-date-object@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" - -is-decimal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-decimal/-/is-decimal-1.0.0.tgz#940579b6ea63c628080a69e62bda88c8470b4fe0" - -is-dotfile@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.2.tgz#2c132383f39199f8edc268ca01b9b007d205cc4d" - -is-equal-shallow@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" - dependencies: - is-primitive "^2.0.0" - -is-extendable@^0.1.0, is-extendable@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" - -is-extglob@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" - -is-extglob@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.0.tgz#33411a482b046bf95e6b0cb27ee2711af4cf15ad" - -is-finite@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" - dependencies: - number-is-nan "^1.0.0" - -is-fullwidth-code-point@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - dependencies: - number-is-nan "^1.0.0" - -is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - -is-glob@^2.0.0, is-glob@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" - dependencies: - is-extglob "^1.0.0" - -is-glob@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" - dependencies: - is-extglob "^2.1.0" - -is-hexadecimal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-1.0.0.tgz#5c459771d2af9a2e3952781fd54fcb1bcfe4113c" - -is-my-json-valid@^2.10.0, is-my-json-valid@^2.12.4: - version "2.15.0" - resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.15.0.tgz#936edda3ca3c211fd98f3b2d3e08da43f7b2915b" - dependencies: - generate-function "^2.0.0" - generate-object-property "^1.1.0" - jsonpointer "^4.0.0" - xtend "^4.0.0" - -is-number@^2.0.2, is-number@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" - dependencies: - kind-of "^3.0.2" - -is-path-cwd@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" - -is-path-in-cwd@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz#6477582b8214d602346094567003be8a9eac04dc" - dependencies: - is-path-inside "^1.0.0" - -is-path-inside@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.0.tgz#fc06e5a1683fbda13de667aff717bbc10a48f37f" - dependencies: - path-is-inside "^1.0.1" - -is-plain-obj@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" - -is-posix-bracket@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" - -is-primitive@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" - -is-property@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" - -is-redirect@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" - -is-regex@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.3.tgz#0d55182bddf9f2fde278220aec3a75642c908637" - -is-regexp@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" - -is-relative@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-0.2.1.tgz#d27f4c7d516d175fb610db84bbeef23c3bc97aa5" - dependencies: - is-unc-path "^0.1.1" - -is-resolvable@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.0.0.tgz#8df57c61ea2e3c501408d100fb013cf8d6e0cc62" - dependencies: - tryit "^1.0.1" - -is-retry-allowed@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" - -is-ssh@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/is-ssh/-/is-ssh-1.3.0.tgz#ebea1169a2614da392a63740366c3ce049d8dff6" - dependencies: - protocols "^1.1.0" - -is-stream@^1.0.0, is-stream@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" - -is-supported-regexp-flag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-supported-regexp-flag/-/is-supported-regexp-flag-1.0.0.tgz#8b520c85fae7a253382d4b02652e045576e13bb8" - -is-svg@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-2.1.0.tgz#cf61090da0d9efbcab8722deba6f032208dbb0e9" - dependencies: - html-comment-regex "^1.1.0" - -is-symbol@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.1.tgz#3cc59f00025194b6ab2e38dbae6689256b660572" - -is-typedarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - -is-unc-path@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-unc-path/-/is-unc-path-0.1.1.tgz#ab2533d77ad733561124c3dc0f5cd8b90054c86b" - dependencies: - unc-path-regex "^0.1.0" - -is-utf8@^0.2.0: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" - -is-valid-glob@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/is-valid-glob/-/is-valid-glob-0.3.0.tgz#d4b55c69f51886f9b65c70d6c2622d37e29f48fe" - -is-windows@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-0.2.0.tgz#de1aa6d63ea29dd248737b69f1ff8b8002d2108c" - -isarray@^1.0.0, isarray@~1.0.0, isarray@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - -isarray@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" - -isexe@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-1.1.2.tgz#36f3e22e60750920f5e7241a476a8c6a42275ad0" - -isobject@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" - dependencies: - isarray "1.0.0" - -isomorphic-fetch@^2.1.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9" - dependencies: - node-fetch "^1.0.1" - whatwg-fetch ">=0.10.0" - -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - -jade@0.26.3: - version "0.26.3" - resolved "https://registry.yarnpkg.com/jade/-/jade-0.26.3.tgz#8f10d7977d8d79f2f6ff862a81b0513ccb25686c" - dependencies: - commander "0.6.1" - mkdirp "0.3.0" - -jetpack-id@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/jetpack-id/-/jetpack-id-1.0.0.tgz#2cf9fbae46d8074fc16b7de0071c8efebca473a6" - -jodid25519@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/jodid25519/-/jodid25519-1.0.2.tgz#06d4912255093419477d425633606e0e90782967" - dependencies: - jsbn "~0.1.0" - -js-base64@^2.1.9: - version "2.1.9" - resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.1.9.tgz#f0e80ae039a4bd654b5f281fc93f04a914a7fcce" - -js-tokens@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-2.0.0.tgz#79903f5563ee778cc1162e6dcf1a0027c97f9cb5" - -js-yaml@^3.3.1, js-yaml@^3.4.3, js-yaml@^3.5.1: - version "3.7.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.7.0.tgz#5c967ddd837a9bfdca5f2de84253abe8a1c03b80" - dependencies: - argparse "^1.0.7" - esprima "^2.6.0" - -js-yaml@~3.6.1: - version "3.6.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.6.1.tgz#6e5fe67d8b205ce4d22fad05b7781e8dadcc4b30" - dependencies: - argparse "^1.0.7" - esprima "^2.6.0" - -jsbn@~0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.0.tgz#650987da0dd74f4ebf5a11377a2aa2d273e97dfd" - -jsesc@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" - -jsesc@~0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" - -json-loader@^0.5.4: - version "0.5.4" - resolved "https://registry.yarnpkg.com/json-loader/-/json-loader-0.5.4.tgz#8baa1365a632f58a3c46d20175fc6002c96e37de" - -json-schema@0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" - -json-stable-stringify@^1.0.0, json-stable-stringify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" - dependencies: - jsonify "~0.0.0" - -json-stringify-safe@~5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - -json3@3.3.2: - version "3.3.2" - resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1" - -json5@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.0.tgz#9b20715b026cbe3778fd769edccd822d8332a5b2" - -jsonfile@^2.1.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" - optionalDependencies: - graceful-fs "^4.1.6" - -jsonfilter@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/jsonfilter/-/jsonfilter-1.1.2.tgz#21ef7cedc75193813c75932e96a98be205ba5a11" - dependencies: - JSONStream "^0.8.4" - minimist "^1.1.0" - stream-combiner "^0.2.1" - through2 "^0.6.3" - -jsonify@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" - -jsonparse@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.2.0.tgz#5c0c5685107160e72fe7489bddea0b44c2bc67bd" - -jsonparse@0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-0.0.5.tgz#330542ad3f0a654665b778f3eb2d9a9fa507ac64" - -jsonpointer@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.0.tgz#6661e161d2fc445f19f98430231343722e1fcbd5" - -JSONStream@^0.8.4: - version "0.8.4" - resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-0.8.4.tgz#91657dfe6ff857483066132b4618b62e8f4887bd" - dependencies: - jsonparse "0.0.5" - through ">=2.2.7 <3" - -JSONStream@^1.0.3: - version "1.2.1" - resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.2.1.tgz#32aa5790e799481083b49b4b7fa94e23bae69bf9" - dependencies: - jsonparse "^1.2.0" - through ">=2.2.7 <3" - -jsprim@^1.2.2: - version "1.3.1" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.3.1.tgz#2a7256f70412a29ee3670aaca625994c4dcff252" - dependencies: - extsprintf "1.0.2" - json-schema "0.2.3" - verror "1.3.6" - -jstransform@^11.0.3: - version "11.0.3" - resolved "https://registry.yarnpkg.com/jstransform/-/jstransform-11.0.3.tgz#09a78993e0ae4d4ef4487f6155a91f6190cb4223" - dependencies: - base62 "^1.1.0" - commoner "^0.10.1" - esprima-fb "^15001.1.0-dev-harmony-fb" - object-assign "^2.0.0" - source-map "^0.4.2" - -jsx-ast-utils@^1.3.3: - version "1.3.4" - resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-1.3.4.tgz#0257ed1cc4b1e65b39d7d9940f9fb4f20f7ba0a9" - dependencies: - acorn-jsx "^3.0.1" - object-assign "^4.1.0" - -kind-of@^3.0.2: - version "3.0.4" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.0.4.tgz#7b8ecf18a4e17f8269d73b501c9f232c96887a74" - dependencies: - is-buffer "^1.0.2" - -klaw@^1.0.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439" - optionalDependencies: - graceful-fs "^4.1.9" - -known-css-properties@^0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/known-css-properties/-/known-css-properties-0.0.5.tgz#33de5b8279010a72db917d33119e4c27c078490a" - -lazy-cache@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" - -lazystream@^1.0.0, lazystream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/lazystream/-/lazystream-1.0.0.tgz#f6995fe0f820392f61396be89462407bb77168e4" - dependencies: - readable-stream "^2.0.5" - -lcid@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" - dependencies: - invert-kv "^1.0.0" - -ldjson-stream@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/ldjson-stream/-/ldjson-stream-1.2.1.tgz#91beceda5ac4ed2b17e649fb777e7abfa0189c2b" - dependencies: - split2 "^0.2.1" - through2 "^0.6.1" - -lerna@jasonlaster/lerna: - version "2.0.0-beta.30" - resolved "https://codeload.github.com/jasonlaster/lerna/tar.gz/f59454363fde40769b97291d4fb2f1eece4e2e9a" - dependencies: - async "^1.5.0" - chalk "^1.1.1" - cmd-shim "^2.0.2" - command-join "^1.1.1" - cross-spawn "^4.0.0" - inquirer "^0.12.0" - lodash.find "^4.3.0" - lodash.unionwith "^4.2.0" - meow "^3.7.0" - minimatch "^3.0.0" - mkdirp "^0.5.1" - normalize-path "^2.0.1" - object-assign "^4.0.1" - object-assign-sorted "^1.0.0" - pad "^1.0.0" - path-exists "^2.1.0" - progress "^1.1.8" - read-cmd-shim "^1.0.1" - rimraf "^2.4.4" - semver "^5.1.0" - signal-exit "^2.1.2" - sync-exec "^0.6.2" - -levn@^0.3.0, levn@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" - dependencies: - prelude-ls "~1.1.2" - type-check "~0.3.2" - -livereload-js@^2.2.0: - version "2.2.2" - resolved "https://registry.yarnpkg.com/livereload-js/-/livereload-js-2.2.2.tgz#6c87257e648ab475bc24ea257457edcc1f8d0bc2" - -load-json-file@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" - dependencies: - graceful-fs "^4.1.2" - parse-json "^2.2.0" - pify "^2.0.0" - pinkie-promise "^2.0.0" - strip-bom "^2.0.0" - -loader-utils@^0.2.11, loader-utils@^0.2.3, loader-utils@^0.2.7, loader-utils@~0.2.2: - version "0.2.16" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.16.tgz#f08632066ed8282835dff88dfb52704765adee6d" - dependencies: - big.js "^3.1.3" - emojis-list "^2.0.0" - json5 "^0.5.0" - object-assign "^4.0.1" - -lodash-es@^4.2.1: - version "4.17.2" - resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.2.tgz#59011b585166e613eb9dd5fc256b2cd1a30f3712" - -lodash._baseassign@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz#8c38a099500f215ad09e59f1722fd0c52bfe0a4e" - dependencies: - lodash._basecopy "^3.0.0" - lodash.keys "^3.0.0" - -lodash._basecopy@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36" - -lodash._basecreate@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz#1bc661614daa7fc311b7d03bf16806a0213cf821" - -lodash._createcompounder@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/lodash._createcompounder/-/lodash._createcompounder-3.0.0.tgz#5dd2cb55372d6e70e0e2392fb2304d6631091075" - dependencies: - lodash.deburr "^3.0.0" - lodash.words "^3.0.0" - -lodash._getnative@^3.0.0: - version "3.9.1" - resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" - -lodash._isiterateecall@^3.0.0: - version "3.0.9" - resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c" - -lodash._reinterpolate@~3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" - -lodash._root@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/lodash._root/-/lodash._root-3.0.1.tgz#fba1c4524c19ee9a5f8136b4609f017cf4ded692" - -lodash.assign@^4.0.3, lodash.assign@^4.0.6, lodash.assign@^4.1.0, lodash.assign@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" - -lodash.camelcase@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-3.0.1.tgz#932c8b87f8a4377897c67197533282f97aeac298" - dependencies: - lodash._createcompounder "^3.0.0" - -lodash.create@3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/lodash.create/-/lodash.create-3.1.1.tgz#d7f2849f0dbda7e04682bb8cd72ab022461debe7" - dependencies: - lodash._baseassign "^3.0.0" - lodash._basecreate "^3.0.0" - lodash._isiterateecall "^3.0.0" - -lodash.deburr@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/lodash.deburr/-/lodash.deburr-3.2.0.tgz#6da8f54334a366a7cf4c4c76ef8d80aa1b365ed5" - dependencies: - lodash._root "^3.0.0" - -lodash.find@^4.3.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.find/-/lodash.find-4.6.0.tgz#cb0704d47ab71789ffa0de8b97dd926fb88b13b1" - -lodash.indexof@^4.0.5: - version "4.0.5" - resolved "https://registry.yarnpkg.com/lodash.indexof/-/lodash.indexof-4.0.5.tgz#53714adc2cddd6ed87638f893aa9b6c24e31ef3c" - -lodash.isarguments@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" - -lodash.isarray@^3.0.0: - version "3.0.4" - resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" - -lodash.isequal@^4.0.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.4.0.tgz#6295768e98e14dc15ce8d362ef6340db82852031" - -lodash.keys@^3.0.0: - version "3.1.2" - resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a" - dependencies: - lodash._getnative "^3.0.0" - lodash.isarguments "^3.0.0" - lodash.isarray "^3.0.0" - -lodash.pickby@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.pickby/-/lodash.pickby-4.6.0.tgz#7dea21d8c18d7703a27c704c15d3b84a67e33aff" - -lodash.some@^4.5.1: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d" - -lodash.template@^4.3.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.4.0.tgz#e73a0385c8355591746e020b99679c690e68fba0" - dependencies: - lodash._reinterpolate "~3.0.0" - lodash.templatesettings "^4.0.0" - -lodash.templatesettings@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-4.1.0.tgz#2b4d4e95ba440d915ff08bc899e4553666713316" - dependencies: - lodash._reinterpolate "~3.0.0" - -lodash.unionwith@^4.2.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.unionwith/-/lodash.unionwith-4.6.0.tgz#74d140b5ca8146e6c643c3724f5152538d9ac1f0" - -lodash.words@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/lodash.words/-/lodash.words-3.2.0.tgz#4e2a8649bc08745b17c695b1a3ce8fee596623b3" - dependencies: - lodash._root "^3.0.0" - -lodash@^4.0.0, lodash@^4.1.0, lodash@^4.11.1, lodash@^4.13.1, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0, lodash@^4.8.0: - version "4.17.2" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.2.tgz#34a3055babe04ce42467b607d700072c7ff6bf42" - -lodash@~4.16.0: - version "4.16.6" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.16.6.tgz#d22c9ac660288f3843e16ba7d2b5d06cca27d777" - -log-symbols@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-1.0.2.tgz#376ff7b58ea3086a0f09facc74617eca501e1a18" - dependencies: - chalk "^1.0.0" - -log-update@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/log-update/-/log-update-1.0.2.tgz#19929f64c4093d2d2e7075a1dad8af59c296b8d1" - dependencies: - ansi-escapes "^1.0.0" - cli-cursor "^1.0.2" - -longest-streak@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-1.0.0.tgz#d06597c4d4c31b52ccb1f5d8f8fe7148eafd6965" - -longest@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" - -loose-envify@^1.0.0, loose-envify@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.0.tgz#6b26248c42f6d4fa4b0d8542f78edfcde35642a8" - dependencies: - js-tokens "^2.0.0" - -loud-rejection@^1.0.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" - dependencies: - currently-unhandled "^0.4.1" - signal-exit "^3.0.0" - -lowercase-keys@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306" - -lru-cache@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.0.1.tgz#1343955edaf2e37d9b9e7ee7241e27c4b9fb72be" - dependencies: - pseudomap "^1.0.1" - yallist "^2.0.0" - -lru-cache@2: - version "2.7.3" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.7.3.tgz#6d4524e8b955f95d4f5b58851ce21dd72fb4e952" - -macaddress@^0.2.8: - version "0.2.8" - resolved "https://registry.yarnpkg.com/macaddress/-/macaddress-0.2.8.tgz#5904dc537c39ec6dbefeae902327135fa8511f12" - -map-cache@^0.2.0: - version "0.2.2" - resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" - -map-obj@^1.0.0, map-obj@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" - -markdown-table@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/markdown-table/-/markdown-table-0.4.0.tgz#890c2c1b3bfe83fb00e4129b8e4cfe645270f9d1" - -math-expression-evaluator@^1.2.14: - version "1.2.14" - resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-1.2.14.tgz#39511771ed9602405fba9affff17eb4d2a3843ab" - dependencies: - lodash.indexof "^4.0.5" - -md5@^2.1.0, md5@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/md5/-/md5-2.2.1.tgz#53ab38d5fe3c8891ba465329ea23fac0540126f9" - dependencies: - charenc "~0.0.1" - crypt "~0.0.1" - is-buffer "~1.1.1" - -mdast-util-inject@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/mdast-util-inject/-/mdast-util-inject-1.1.0.tgz#db06b8b585be959a2dcd2f87f472ba9b756f3675" - dependencies: - mdast-util-to-string "^1.0.0" - -mdast-util-to-string@^1.0.0, mdast-util-to-string@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-1.0.2.tgz#dc996a24d2b521178d3fac3993680c03a683e1dd" - -mdast-util-toc@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/mdast-util-toc/-/mdast-util-toc-2.0.0.tgz#23dd7e6ca7a66aa648df6ce40efc7bccfc733bff" - dependencies: - github-slugger "^1.1.1" - mdast-util-to-string "^1.0.2" - unist-util-visit "^1.1.0" - -media-typer@0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" - -memory-fs@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.2.0.tgz#f2bb25368bc121e391c2520de92969caee0a0290" - -memory-fs@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.3.0.tgz#7bcc6b629e3a43e871d7e29aca6ae8a7f15cbb20" - dependencies: - errno "^0.1.3" - readable-stream "^2.0.1" - -meow@^3.3.0, meow@^3.7.0: - version "3.7.0" - resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" - dependencies: - camelcase-keys "^2.0.0" - decamelize "^1.1.2" - loud-rejection "^1.0.0" - map-obj "^1.0.1" - minimist "^1.1.3" - normalize-package-data "^2.3.4" - object-assign "^4.0.1" - read-pkg-up "^1.0.1" - redent "^1.0.0" - trim-newlines "^1.0.0" - -merge-descriptors@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" - -merge-stream@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-1.0.0.tgz#9cfd156fef35421e2b5403ce11dc6eb1962b026e" - dependencies: - readable-stream "^2.0.1" - -methods@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" - -micromatch@^2.1.5, micromatch@^2.1.6, micromatch@^2.3.7: - version "2.3.11" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" - dependencies: - arr-diff "^2.0.0" - array-unique "^0.2.1" - braces "^1.8.2" - expand-brackets "^0.1.4" - extglob "^0.3.1" - filename-regex "^2.0.0" - is-extglob "^1.0.0" - is-glob "^2.0.1" - kind-of "^3.0.2" - normalize-path "^2.0.1" - object.omit "^2.0.0" - parse-glob "^3.0.4" - regex-cache "^0.4.2" - -mime-db@~1.24.0: - version "1.24.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.24.0.tgz#e2d13f939f0016c6e4e9ad25a8652f126c467f0c" - -mime-types@^2.1.12, mime-types@~2.1.11, mime-types@~2.1.7: - version "2.1.12" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.12.tgz#152ba256777020dd4663f54c2e7bc26381e71729" - dependencies: - mime-db "~1.24.0" - -mime@^1.3.4, mime@1.3.4: - version "1.3.4" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.3.4.tgz#115f9e3b6b3daf2959983cb38f149a2d40eb5d53" - -minimatch@^3.0.0, minimatch@^3.0.2, "minimatch@2 || 3", minimatch@3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.3.tgz#2a4e4090b96b2db06a9d7df01055a62a77c9b774" - dependencies: - brace-expansion "^1.0.0" - -minimatch@0.3: - version "0.3.0" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-0.3.0.tgz#275d8edaac4f1bb3326472089e7949c8394699dd" - dependencies: - lru-cache "2" - sigmund "~1.0.0" - -minimist@^1.1.0, minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" - -minimist@~0.0.1: - version "0.0.10" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" - -minimist@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" - -mkdirp@^0.5.0, mkdirp@^0.5.1, "mkdirp@>=0.5 0", mkdirp@~0.5.0, mkdirp@~0.5.1, mkdirp@0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" - dependencies: - minimist "0.0.8" - -mkdirp@0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.3.0.tgz#1bbf5ab1ba827af23575143490426455f481fe1e" - -mocha-circleci-reporter@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/mocha-circleci-reporter/-/mocha-circleci-reporter-0.0.1.tgz#9751273e919e8ea7c9e2d2128e18c374b0f4a817" - dependencies: - mocha "^2.2.5" - mocha-junit-reporter "^1.6.1" - -mocha-junit-reporter@^1.6.1: - version "1.12.1" - resolved "https://registry.yarnpkg.com/mocha-junit-reporter/-/mocha-junit-reporter-1.12.1.tgz#4d512ac03a55a20159d019abb5838f07ef3daee9" - dependencies: - debug "^2.2.0" - md5 "^2.1.0" - mkdirp "~0.5.1" - xml "^1.0.0" - -mocha@^2.2.5: - version "2.5.3" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-2.5.3.tgz#161be5bdeb496771eb9b35745050b622b5aefc58" - dependencies: - commander "2.3.0" - debug "2.2.0" - diff "1.4.0" - escape-string-regexp "1.0.2" - glob "3.2.11" - growl "1.9.2" - jade "0.26.3" - mkdirp "0.5.1" - supports-color "1.2.0" - to-iso-string "0.0.2" - -mocha@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-3.1.2.tgz#51f93b432bf7e1b175ffc22883ccd0be32dba6b5" - dependencies: - browser-stdout "1.3.0" - commander "2.9.0" - debug "2.2.0" - diff "1.4.0" - escape-string-regexp "1.0.5" - glob "7.0.5" - growl "1.9.2" - json3 "3.3.2" - lodash.create "3.1.1" - mkdirp "0.5.1" - supports-color "3.1.2" - -mock-require@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/mock-require/-/mock-require-2.0.0.tgz#bdc13e1f27e4bfd27d913d72770027d2b6cefd40" - dependencies: - caller-id "^0.1.0" - -module-deps-sortable@4.0.6: - version "4.0.6" - resolved "https://registry.yarnpkg.com/module-deps-sortable/-/module-deps-sortable-4.0.6.tgz#1251a4ba2c44a92df6989bd029da121a4f2109b0" - dependencies: - browser-resolve "^1.7.0" - concat-stream "~1.5.0" - defined "^1.0.0" - detective "^4.0.0" - duplexer2 "^0.1.2" - inherits "^2.0.1" - JSONStream "^1.0.3" - parents "^1.0.0" - readable-stream "^2.0.2" - resolve "^1.1.3" - stream-combiner2 "^1.1.1" - subarg "^1.0.0" - through2 "^2.0.0" - xtend "^4.0.0" - -mout@^0.11.0: - version "0.11.1" - resolved "https://registry.yarnpkg.com/mout/-/mout-0.11.1.tgz#ba3611df5f0e5b1ffbfd01166b8f02d1f5fa2b99" - -ms@0.7.1: - version "0.7.1" - resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098" - -ms@0.7.2: - version "0.7.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.2.tgz#ae25cf2512b3885a1d95d7f037868d8431124765" - -multimatch@^2.0.0, multimatch@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-2.1.0.tgz#9c7906a22fb4c02919e2f5f75161b4cdbd4b2a2b" - dependencies: - array-differ "^1.0.0" - array-union "^1.0.1" - arrify "^1.0.0" - minimatch "^3.0.0" - -mustache@^2.2.1: - version "2.3.0" - resolved "https://registry.yarnpkg.com/mustache/-/mustache-2.3.0.tgz#4028f7778b17708a489930a6e52ac3bca0da41d0" - -mute-stream@0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.5.tgz#8fbfabb0a98a253d3184331f9e8deb7372fac6c0" - -nan@^2.3.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.4.0.tgz#fb3c59d45fe4effe215f0b890f8adf6eb32d2232" - -natural-compare@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - -negotiator@0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" - -node-fetch@^1.0.1: - version "1.6.3" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.6.3.tgz#dc234edd6489982d58e8f0db4f695029abcd8c04" - dependencies: - encoding "^0.1.11" - is-stream "^1.0.1" - -node-libs-browser@^0.6.0, "node-libs-browser@>= 0.4.0 <=0.6.0": - version "0.6.0" - resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-0.6.0.tgz#244806d44d319e048bc8607b5cc4eaf9a29d2e3c" - dependencies: - assert "^1.1.1" - browserify-zlib "~0.1.4" - buffer "^4.9.0" - console-browserify "^1.1.0" - constants-browserify "0.0.1" - crypto-browserify "~3.2.6" - domain-browser "^1.1.1" - events "^1.0.0" - http-browserify "^1.3.2" - https-browserify "0.0.0" - os-browserify "~0.1.2" - path-browserify "0.0.0" - process "^0.11.0" - punycode "^1.2.4" - querystring-es3 "~0.2.0" - readable-stream "^1.1.13" - stream-browserify "^1.0.0" - string_decoder "~0.10.25" - timers-browserify "^1.0.1" - tty-browserify "0.0.0" - url "~0.10.1" - util "~0.10.3" - vm-browserify "0.0.4" - -node-pre-gyp@^0.6.29: - version "0.6.31" - resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.31.tgz#d8a00ddaa301a940615dbcc8caad4024d58f6017" - dependencies: - mkdirp "~0.5.1" - nopt "~3.0.6" - npmlog "^4.0.0" - rc "~1.1.6" - request "^2.75.0" - rimraf "~2.5.4" - semver "~5.3.0" - tar "~2.2.1" - tar-pack "~3.3.0" - -node-status-codes@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/node-status-codes/-/node-status-codes-1.0.0.tgz#5ae5541d024645d32a58fcddc9ceecea7ae3ac2f" - -node-uuid@~1.4.7: - version "1.4.7" - resolved "https://registry.yarnpkg.com/node-uuid/-/node-uuid-1.4.7.tgz#6da5a17668c4b3dd59623bda11cf7fa4c1f60a6f" - -nopt@~3.0.6: - version "3.0.6" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" - dependencies: - abbrev "1" - -normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: - version "2.3.5" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.3.5.tgz#8d924f142960e1777e7ffe170543631cc7cb02df" - dependencies: - hosted-git-info "^2.1.4" - is-builtin-module "^1.0.0" - semver "2 || 3 || 4 || 5" - validate-npm-package-license "^3.0.1" - -normalize-path@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-1.0.0.tgz#32d0e472f91ff345701c15a8311018d3b0a90379" - -normalize-path@^2.0.0, normalize-path@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.0.1.tgz#47886ac1662760d4261b7d979d241709d3ce3f7a" - -normalize-range@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" - -normalize-selector@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/normalize-selector/-/normalize-selector-0.2.0.tgz#d0b145eb691189c63a78d201dc4fdb1293ef0c03" - -normalize-uri@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/normalize-uri/-/normalize-uri-1.0.0.tgz#c2407bca400808202a108f6776e335ca03bfa69f" - -normalize-url@^1.4.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-1.8.0.tgz#a9550b079aa3523c85d78df24eef1959fce359ab" - dependencies: - object-assign "^4.0.1" - prepend-http "^1.0.0" - query-string "^4.1.0" - sort-keys "^1.0.0" - -npm-prefix@^1.0.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/npm-prefix/-/npm-prefix-1.2.0.tgz#e619455f7074ba54cc66d6d0d37dd9f1be6bcbc0" - dependencies: - rc "^1.1.0" - shellsubstitute "^1.1.0" - untildify "^2.1.0" - -npmlog@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.0.1.tgz#d14f503b4cd79710375553004ba96e6662fbc0b8" - dependencies: - are-we-there-yet "~1.1.2" - console-control-strings "~1.1.0" - gauge "~2.7.1" - set-blocking "~2.0.0" - -num2fraction@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" - -number-is-nan@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" - -oauth-sign@~0.8.1: - version "0.8.2" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" - -object-assign-sorted@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/object-assign-sorted/-/object-assign-sorted-1.0.0.tgz#e739f698164014ec1f050f38decabad1e9b228bf" - dependencies: - object-assign "^4.0.1" - sorted-object "^2.0.0" - -object-assign@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-2.1.1.tgz#43c36e5d569ff8e4816c4efa8be02d26967c18aa" - -object-assign@^4.0.0, object-assign@^4.0.1, object-assign@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.0.tgz#7a3b3d0e98063d43f4c03f2e8ae6cd51a86883a0" - -object-keys@^1.0.8: - version "1.0.11" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.11.tgz#c54601778ad560f1142ce0e01bcca8b56d13426d" - -object.omit@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" - dependencies: - for-own "^0.1.4" - is-extendable "^0.1.1" - -on-finished@~2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" - dependencies: - ee-first "1.1.1" - -once@^1.3.0, once@^1.4: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - dependencies: - wrappy "1" - -once@~1.3.0, once@~1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/once/-/once-1.3.3.tgz#b2e261557ce4c314ec8304f3fa82663e4297ca20" - dependencies: - wrappy "1" - -onecolor@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/onecolor/-/onecolor-3.0.4.tgz#75a46f80da6c7aaa5b4daae17a47198bd9652494" - -onetime@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" - -optimist@~0.6.0: - version "0.6.1" - resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" - dependencies: - minimist "~0.0.1" - wordwrap "~0.0.2" - -optionator@^0.8.2: - version "0.8.2" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" - dependencies: - deep-is "~0.1.3" - fast-levenshtein "~2.0.4" - levn "~0.3.0" - prelude-ls "~1.1.2" - type-check "~0.3.2" - wordwrap "~1.0.0" - -options@>=0.0.5: - version "0.0.6" - resolved "https://registry.yarnpkg.com/options/-/options-0.0.6.tgz#ec22d312806bb53e731773e7cdaefcf1c643128f" - -ordered-read-streams@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/ordered-read-streams/-/ordered-read-streams-0.3.0.tgz#7137e69b3298bb342247a1bbee3881c80e2fd78b" - dependencies: - is-stream "^1.0.1" - readable-stream "^2.0.1" - -os-browserify@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.1.2.tgz#49ca0293e0b19590a5f5de10c7f265a617d8fe54" - -os-homedir@^1.0.0, os-homedir@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" - -os-locale@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" - dependencies: - lcid "^1.0.0" - -os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - -output-file-sync@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/output-file-sync/-/output-file-sync-1.1.2.tgz#d0a33eefe61a205facb90092e826598d5245ce76" - dependencies: - graceful-fs "^4.1.4" - mkdirp "^0.5.1" - object-assign "^4.1.0" - -pad@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/pad/-/pad-1.0.2.tgz#f6e36ff3ceb468e4ae2ed33ad5ecf25ace920960" - -pako@~0.2.0: - version "0.2.9" - resolved "https://registry.yarnpkg.com/pako/-/pako-0.2.9.tgz#f3f7522f4ef782348da8161bad9ecfd51bf83a75" - -parents@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/parents/-/parents-1.0.1.tgz#fedd4d2bf193a77745fe71e371d73c3307d9c751" - dependencies: - path-platform "~0.11.15" - -parse-entities@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-1.1.0.tgz#4bc58f35fdc8e65dded35a12f2e40223ca24a3f7" - dependencies: - character-entities "^1.0.0" - character-entities-legacy "^1.0.0" - character-reference-invalid "^1.0.0" - has "^1.0.1" - is-alphanumerical "^1.0.0" - is-decimal "^1.0.0" - is-hexadecimal "^1.0.0" - -parse-filepath@^0.6.3: - version "0.6.3" - resolved "https://registry.yarnpkg.com/parse-filepath/-/parse-filepath-0.6.3.tgz#38e17a73e5e4e6776bae9506fc3ccb14bc3a2b80" - dependencies: - is-absolute "^0.2.2" - map-cache "^0.2.0" - -parse-git-config@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/parse-git-config/-/parse-git-config-0.2.0.tgz#272833fdd15fea146fb75d336d236b963b6ff706" - dependencies: - ini "^1.3.3" - -parse-glob@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" - dependencies: - glob-base "^0.3.0" - is-dotfile "^1.0.0" - is-extglob "^1.0.0" - is-glob "^2.0.0" - -parse-json@^2.1.0, parse-json@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" - dependencies: - error-ex "^1.2.0" - -parse-url@^1.3.0: - version "1.3.5" - resolved "https://registry.yarnpkg.com/parse-url/-/parse-url-1.3.5.tgz#c9f27e266bc81691927a417c77d543a11da31b35" - dependencies: - is-ssh "^1.3.0" - protocols "^1.4.0" - -parseurl@~1.3.0, parseurl@~1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.1.tgz#c8ab8c9223ba34888aa64a297b28853bec18da56" - -path-browserify@0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.0.tgz#a0b870729aae214005b7d5032ec2cbbb0fb4451a" - -path-dirname@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" - -path-exists@^2.0.0, path-exists@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" - dependencies: - pinkie-promise "^2.0.0" - -path-exists@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - -path-is-inside@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" - -path-platform@~0.11.15: - version "0.11.15" - resolved "https://registry.yarnpkg.com/path-platform/-/path-platform-0.11.15.tgz#e864217f74c36850f0852b78dc7bf7d4a5721bf2" - -path-to-regexp@0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" - -path-type@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" - dependencies: - graceful-fs "^4.1.2" - pify "^2.0.0" - pinkie-promise "^2.0.0" - -pbkdf2-compat@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pbkdf2-compat/-/pbkdf2-compat-2.0.1.tgz#b6e0c8fa99494d94e0511575802a59a5c142f288" - -pify@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" - -pinkie-promise@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" - dependencies: - pinkie "^2.0.0" - -pinkie@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" - -pipetteur@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/pipetteur/-/pipetteur-2.0.3.tgz#1955760959e8d1a11cb2a50ec83eec470633e49f" - dependencies: - onecolor "^3.0.4" - synesthesia "^1.0.1" - -pkg-dir@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" - dependencies: - find-up "^1.0.0" - -plur@^2.0.0, plur@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/plur/-/plur-2.1.2.tgz#7482452c1a0f508e3e344eaec312c91c29dc655a" - dependencies: - irregular-plurals "^1.0.0" - -pluralize@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-1.2.1.tgz#d1a21483fd22bb41e58a12fa3421823140897c45" - -postcss-calc@^5.2.0: - version "5.3.1" - resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-5.3.1.tgz#77bae7ca928ad85716e2fda42f261bf7c1d65b5e" - dependencies: - postcss "^5.0.2" - postcss-message-helpers "^2.0.0" - reduce-css-calc "^1.2.6" - -postcss-colormin@^2.1.8: - version "2.2.1" - resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-2.2.1.tgz#dc5421b6ae6f779ef6bfd47352b94abe59d0316b" - dependencies: - colormin "^1.0.5" - postcss "^5.0.13" - postcss-value-parser "^3.2.3" - -postcss-convert-values@^2.3.4: - version "2.4.1" - resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-2.4.1.tgz#45dce4d4e33b7d967b97a4d937f270ea98d2fe7a" - dependencies: - postcss "^5.0.11" - postcss-value-parser "^3.1.2" - -postcss-discard-comments@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-2.0.4.tgz#befe89fafd5b3dace5ccce51b76b81514be00e3d" - dependencies: - postcss "^5.0.14" - -postcss-discard-duplicates@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-2.0.2.tgz#02be520e91571ffb10738766a981d5770989bb32" - dependencies: - postcss "^5.0.4" - -postcss-discard-empty@^2.0.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-2.1.0.tgz#d2b4bd9d5ced5ebd8dcade7640c7d7cd7f4f92b5" - dependencies: - postcss "^5.0.14" - -postcss-discard-overridden@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-0.1.1.tgz#8b1eaf554f686fb288cd874c55667b0aa3668d58" - dependencies: - postcss "^5.0.16" - -postcss-discard-unused@^2.2.1: - version "2.2.2" - resolved "https://registry.yarnpkg.com/postcss-discard-unused/-/postcss-discard-unused-2.2.2.tgz#5d72f7d05d11de0a9589e001958067ccae1b4931" - dependencies: - postcss "^5.0.14" - uniqs "^2.0.0" - -postcss-filter-plugins@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/postcss-filter-plugins/-/postcss-filter-plugins-2.0.2.tgz#6d85862534d735ac420e4a85806e1f5d4286d84c" - dependencies: - postcss "^5.0.4" - uniqid "^4.0.0" - -postcss-less@^0.14.0: - version "0.14.0" - resolved "https://registry.yarnpkg.com/postcss-less/-/postcss-less-0.14.0.tgz#c631b089c6cce422b9a10f3a958d2bedd3819324" - dependencies: - postcss "^5.0.21" - -postcss-media-query-parser@^0.2.0: - version "0.2.3" - resolved "https://registry.yarnpkg.com/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz#27b39c6f4d94f81b1a73b8f76351c609e5cef244" - -postcss-merge-idents@^2.1.5: - version "2.1.7" - resolved "https://registry.yarnpkg.com/postcss-merge-idents/-/postcss-merge-idents-2.1.7.tgz#4c5530313c08e1d5b3bbf3d2bbc747e278eea270" - dependencies: - has "^1.0.1" - postcss "^5.0.10" - postcss-value-parser "^3.1.1" - -postcss-merge-longhand@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-2.0.1.tgz#ff59b5dec6d586ce2cea183138f55c5876fa9cdc" - dependencies: - postcss "^5.0.4" - -postcss-merge-rules@^2.0.3: - version "2.0.10" - resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-2.0.10.tgz#54b360be804e7e69a5c7222635247b92a3569e9b" - dependencies: - postcss "^5.0.4" - vendors "^1.0.0" - -postcss-message-helpers@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/postcss-message-helpers/-/postcss-message-helpers-2.0.0.tgz#a4f2f4fab6e4fe002f0aed000478cdf52f9ba60e" - -postcss-minify-font-values@^1.0.2: - version "1.0.5" - resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-1.0.5.tgz#4b58edb56641eba7c8474ab3526cafd7bbdecb69" - dependencies: - object-assign "^4.0.1" - postcss "^5.0.4" - postcss-value-parser "^3.0.2" - -postcss-minify-gradients@^1.0.1: - version "1.0.5" - resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-1.0.5.tgz#5dbda11373703f83cfb4a3ea3881d8d75ff5e6e1" - dependencies: - postcss "^5.0.12" - postcss-value-parser "^3.3.0" - -postcss-minify-params@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-1.0.5.tgz#82d602643b8616a61fb3634d7ede0289836d67f9" - dependencies: - alphanum-sort "^1.0.1" - postcss "^5.0.2" - postcss-value-parser "^3.0.2" - uniqs "^2.0.0" - -postcss-minify-selectors@^2.0.4: - version "2.0.7" - resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-2.0.7.tgz#bfb9248fe14db33770f036572de6b4897c48d81c" - dependencies: - alphanum-sort "^1.0.2" - has "^1.0.1" - postcss "^5.0.14" - postcss-selector-parser "^2.0.0" - -postcss-modules-extract-imports@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.0.1.tgz#8fb3fef9a6dd0420d3f6d4353cf1ff73f2b2a341" - dependencies: - postcss "^5.0.4" - -postcss-modules-local-by-default@^1.0.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.1.1.tgz#29a10673fa37d19251265ca2ba3150d9040eb4ce" - dependencies: - css-selector-tokenizer "^0.6.0" - postcss "^5.0.4" - -postcss-modules-scope@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-1.0.2.tgz#ff977395e5e06202d7362290b88b1e8cd049de29" - dependencies: - css-selector-tokenizer "^0.6.0" - postcss "^5.0.4" - -postcss-modules-values@^1.1.0: - version "1.2.2" - resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-1.2.2.tgz#f0e7d476fe1ed88c5e4c7f97533a3e772ad94ca1" - dependencies: - icss-replace-symbols "^1.0.2" - postcss "^5.0.14" - -postcss-normalize-charset@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-1.1.1.tgz#ef9ee71212d7fe759c78ed162f61ed62b5cb93f1" - dependencies: - postcss "^5.0.5" - -postcss-normalize-url@^3.0.7: - version "3.0.7" - resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-3.0.7.tgz#6bd90d0a4bc5a1df22c26ea65c53257dc3829f4e" - dependencies: - is-absolute-url "^2.0.0" - normalize-url "^1.4.0" - postcss "^5.0.14" - postcss-value-parser "^3.2.3" - -postcss-ordered-values@^2.1.0: - version "2.2.2" - resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-2.2.2.tgz#be8b511741fab2dac8e614a2302e9d10267b0771" - dependencies: - postcss "^5.0.4" - postcss-value-parser "^3.0.1" - -postcss-reduce-idents@^2.2.2: - version "2.3.1" - resolved "https://registry.yarnpkg.com/postcss-reduce-idents/-/postcss-reduce-idents-2.3.1.tgz#024e8e219f52773313408573db9645ba62d2d2fe" - dependencies: - postcss "^5.0.4" - postcss-value-parser "^3.0.2" - -postcss-reduce-initial@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-1.0.0.tgz#8f739b938289ef2e48936d7101783e4741ca9bbb" - dependencies: - postcss "^5.0.4" - -postcss-reduce-transforms@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-1.0.4.tgz#ff76f4d8212437b31c298a42d2e1444025771ae1" - dependencies: - has "^1.0.1" - postcss "^5.0.8" - postcss-value-parser "^3.0.1" - -postcss-reporter@^1.2.1, postcss-reporter@^1.3.0, postcss-reporter@^1.3.3: - version "1.4.1" - resolved "https://registry.yarnpkg.com/postcss-reporter/-/postcss-reporter-1.4.1.tgz#c136f0a5b161915f379dd3765c61075f7e7b9af2" - dependencies: - chalk "^1.0.0" - lodash "^4.1.0" - log-symbols "^1.0.2" - postcss "^5.0.0" - -postcss-resolve-nested-selector@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz#29ccbc7c37dedfac304e9fff0bf1596b3f6a0e4e" - -postcss-scss@^0.3.0: - version "0.3.1" - resolved "https://registry.yarnpkg.com/postcss-scss/-/postcss-scss-0.3.1.tgz#65c610d8e2a7ee0e62b1835b71b8870734816e4b" - dependencies: - postcss "^5.2.4" - -postcss-selector-parser@^2.0.0, postcss-selector-parser@^2.1.1: - version "2.2.2" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-2.2.2.tgz#3d70f5adda130da51c7c0c2fc023f56b1374fe08" - dependencies: - flatten "^1.0.2" - indexes-of "^1.0.1" - uniq "^1.0.1" - -postcss-svgo@^2.1.1: - version "2.1.5" - resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-2.1.5.tgz#46fc0363f01bab6a36a9abb01c229fcc45363094" - dependencies: - is-svg "^2.0.0" - postcss "^5.0.14" - postcss-value-parser "^3.2.3" - svgo "^0.7.0" - -postcss-unique-selectors@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-2.0.2.tgz#981d57d29ddcb33e7b1dfe1fd43b8649f933ca1d" - dependencies: - alphanum-sort "^1.0.1" - postcss "^5.0.4" - uniqs "^2.0.0" - -postcss-value-parser@^3.0.1, postcss-value-parser@^3.0.2, postcss-value-parser@^3.1.1, postcss-value-parser@^3.1.2, postcss-value-parser@^3.2.3, postcss-value-parser@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.0.tgz#87f38f9f18f774a4ab4c8a232f5c5ce8872a9d15" - -postcss-zindex@^2.0.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/postcss-zindex/-/postcss-zindex-2.1.1.tgz#ea3fbe656c9738aa8729e2ee96ec2a46089b720f" - dependencies: - postcss "^5.0.4" - uniqs "^2.0.0" - -postcss@^5.0.0, postcss@^5.0.10, postcss@^5.0.11, postcss@^5.0.12, postcss@^5.0.13, postcss@^5.0.14, postcss@^5.0.16, postcss@^5.0.18, postcss@^5.0.2, postcss@^5.0.20, postcss@^5.0.21, postcss@^5.0.4, postcss@^5.0.5, postcss@^5.0.6, postcss@^5.0.8, postcss@^5.2.4, postcss@^5.2.5: - version "5.2.5" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-5.2.5.tgz#ec428c27dffc7fac65961340a9b022fa4af5f056" - dependencies: - chalk "^1.1.3" - js-base64 "^2.1.9" - source-map "^0.5.6" - supports-color "^3.1.2" - -prelude-ls@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" - -prepend-http@^1.0.0, prepend-http@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" - -preserve@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" - -pretty-fast@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/pretty-fast/-/pretty-fast-0.2.0.tgz#b2a9a4dcc7870dbd747ad66482199862e43c5226" - dependencies: - acorn "~0.11.0" - optimist "~0.6.0" - source-map "~0.1.30" - -private@^0.1.6, private@~0.1.5: - version "0.1.6" - resolved "https://registry.yarnpkg.com/private/-/private-0.1.6.tgz#55c6a976d0f9bafb9924851350fe47b9b5fbb7c1" - -process-nextick-args@~1.0.6: - version "1.0.7" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" - -process@^0.11.0, process@~0.11.0: - version "0.11.9" - resolved "https://registry.yarnpkg.com/process/-/process-0.11.9.tgz#7bd5ad21aa6253e7da8682264f1e11d11c0318c1" - -progress@^1.1.8: - version "1.1.8" - resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be" - -promise@^7.0.3, promise@^7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/promise/-/promise-7.1.1.tgz#489654c692616b8aa55b0724fa809bb7db49c5bf" - dependencies: - asap "~2.0.3" - -protocols@^1.1.0, protocols@^1.4.0: - version "1.4.3" - resolved "https://registry.yarnpkg.com/protocols/-/protocols-1.4.3.tgz#635b1c0785f0b389e8a012df1b1afffda9608b76" - -proxy-addr@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-1.1.2.tgz#b4cc5f22610d9535824c123aef9d3cf73c40ba37" - dependencies: - forwarded "~0.1.0" - ipaddr.js "1.1.1" - -prr@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/prr/-/prr-0.0.0.tgz#1a84b85908325501411853d0081ee3fa86e2926a" - -pseudomap@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" - -punycode@^1.2.4, punycode@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" - -punycode@1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" - -q@^1.1.2: - version "1.4.1" - resolved "https://registry.yarnpkg.com/q/-/q-1.4.1.tgz#55705bcd93c5f3673530c2c2cbc0c2b3addc286e" - -qs@~5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-5.1.0.tgz#4d932e5c7ea411cca76a312d39a606200fd50cd9" - -qs@~6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.3.0.tgz#f403b264f23bc01228c74131b407f18d5ea5d442" - -qs@5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-5.2.0.tgz#a9f31142af468cb72b25b30136ba2456834916be" - -qs@6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.2.0.tgz#3b7848c03c2dece69a9522b0fae8c4126d745f3b" - -query-string@^4.1.0: - version "4.2.3" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-4.2.3.tgz#9f27273d207a25a8ee4c7b8c74dcd45d556db822" - dependencies: - object-assign "^4.1.0" - strict-uri-encode "^1.0.0" - -querystring-es3@~0.2.0: - version "0.2.1" - resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" - -querystring@^0.2.0, querystring@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" - -randomatic@^1.1.3: - version "1.1.5" - resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.5.tgz#5e9ef5f2d573c67bd2b8124ae90b5156e457840b" - dependencies: - is-number "^2.0.2" - kind-of "^3.0.2" - -range-parser@^1.0.3, range-parser@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" - -raw-body@~2.1.5, raw-body@~2.1.7: - version "2.1.7" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.1.7.tgz#adfeace2e4fb3098058014d08c072dcc59758774" - dependencies: - bytes "2.4.0" - iconv-lite "0.4.13" - unpipe "1.0.0" - -rc@^1.1.0, rc@~1.1.6: - version "1.1.6" - resolved "https://registry.yarnpkg.com/rc/-/rc-1.1.6.tgz#43651b76b6ae53b5c802f1151fa3fc3b059969c9" - dependencies: - deep-extend "~0.4.0" - ini "~1.3.0" - minimist "^1.2.0" - strip-json-comments "~1.0.4" - -react-dom@=0.14.7: - version "0.14.7" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-0.14.7.tgz#973c302110b3a680c9afe69d07c623b9c0952d82" - -react-dom@15.3.1: - version "15.3.1" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-15.3.1.tgz#6d42cd2b64c8c5e0b693f3ffaec301e6e627e24e" - -react-hot-api@^0.4.5: - version "0.4.7" - resolved "https://registry.yarnpkg.com/react-hot-api/-/react-hot-api-0.4.7.tgz#a7e22a56d252e11abd9366b61264cf4492c58171" - -react-hot-loader@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/react-hot-loader/-/react-hot-loader-1.3.0.tgz#7701658d02108b5bbc407e200dde591cb7a6ed69" - dependencies: - react-hot-api "^0.4.5" - source-map "^0.4.4" - -react-immutable-proptypes@^1.7.1: - version "1.7.2" - resolved "https://registry.yarnpkg.com/react-immutable-proptypes/-/react-immutable-proptypes-1.7.2.tgz#fb1fdca24e30501617732781f4341b704ef7c320" - -react-inlinesvg@^0.5.3: - version "0.5.4" - resolved "https://registry.yarnpkg.com/react-inlinesvg/-/react-inlinesvg-0.5.4.tgz#f1c0ee10389a2d9928fc87dca8b8dba6093cd790" - dependencies: - fbjs "^0.8" - httpplease "^0.16" - once "^1.4" - -react-redux@4.4.5: - version "4.4.5" - resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-4.4.5.tgz#f509a2981be2252d10c629ef7c559347a4aec457" - dependencies: - hoist-non-react-statics "^1.0.3" - invariant "^2.0.0" - lodash "^4.2.0" - loose-envify "^1.1.0" - -react@=0.14.7: - version "0.14.7" - resolved "https://registry.yarnpkg.com/react/-/react-0.14.7.tgz#76c4e5cfa204caa5aaf42b13008f0d3f6d58a133" - dependencies: - envify "^3.0.0" - fbjs "^0.6.1" - -react@15.3.1: - version "15.3.1" - resolved "https://registry.yarnpkg.com/react/-/react-15.3.1.tgz#f78501ed8c2ec6e6e31c3223652e97f1369d2bd6" - dependencies: - fbjs "^0.8.4" - loose-envify "^1.1.0" - object-assign "^4.1.0" - -read-all-stream@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/read-all-stream/-/read-all-stream-3.1.0.tgz#35c3e177f2078ef789ee4bfafa4373074eaef4fa" - dependencies: - pinkie-promise "^2.0.0" - readable-stream "^2.0.0" - -read-cmd-shim@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/read-cmd-shim/-/read-cmd-shim-1.0.1.tgz#2d5d157786a37c055d22077c32c53f8329e91c7b" - dependencies: - graceful-fs "^4.1.2" - -read-file-stdin@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/read-file-stdin/-/read-file-stdin-0.2.1.tgz#25eccff3a153b6809afacb23ee15387db9e0ee61" - dependencies: - gather-stream "^1.0.0" - -read-pkg-up@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" - dependencies: - find-up "^1.0.0" - read-pkg "^1.0.0" - -read-pkg@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" - dependencies: - load-json-file "^1.0.0" - normalize-package-data "^2.3.2" - path-type "^1.0.0" - -readable-stream@^1.0.27-1, readable-stream@^1.0.33, readable-stream@^1.1.13, readable-stream@~1.1.9: - version "1.1.14" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "0.0.1" - string_decoder "~0.10.x" - -readable-stream@^2.0.0, "readable-stream@^2.0.0 || ^1.1.13", readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.5: - version "2.2.2" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.2.tgz#a9e6fec3c7dda85f8bb1b3ba7028604556fc825e" - dependencies: - buffer-shims "^1.0.0" - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "~1.0.0" - process-nextick-args "~1.0.6" - string_decoder "~0.10.x" - util-deprecate "~1.0.1" - -"readable-stream@>=1.0.33-1 <1.1.0-0": - version "1.0.34" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "0.0.1" - string_decoder "~0.10.x" - -readable-stream@~2.0.0, readable-stream@~2.0.5: - version "2.0.6" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e" - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "~1.0.0" - process-nextick-args "~1.0.6" - string_decoder "~0.10.x" - util-deprecate "~1.0.1" - -readable-stream@~2.1.0, readable-stream@~2.1.4: - version "2.1.5" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.1.5.tgz#66fa8b720e1438b364681f2ad1a63c618448c9d0" - dependencies: - buffer-shims "^1.0.0" - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "~1.0.0" - process-nextick-args "~1.0.6" - string_decoder "~0.10.x" - util-deprecate "~1.0.1" - -readdirp@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78" - dependencies: - graceful-fs "^4.1.2" - minimatch "^3.0.2" - readable-stream "^2.0.2" - set-immediate-shim "^1.0.1" - -readline2@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/readline2/-/readline2-1.0.1.tgz#41059608ffc154757b715d9989d199ffbf372e35" - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - mute-stream "0.0.5" - -recast@^0.10.0: - version "0.10.43" - resolved "https://registry.yarnpkg.com/recast/-/recast-0.10.43.tgz#b95d50f6d60761a5f6252e15d80678168491ce7f" - dependencies: - ast-types "0.8.15" - esprima-fb "~15001.1001.0-dev-harmony-fb" - private "~0.1.5" - source-map "~0.5.0" - -rechoir@^0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" - dependencies: - resolve "^1.1.6" - -redent@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" - dependencies: - indent-string "^2.1.0" - strip-indent "^1.0.1" - -reduce-css-calc@^1.2.6: - version "1.3.0" - resolved "https://registry.yarnpkg.com/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz#747c914e049614a4c9cfbba629871ad1d2927716" - dependencies: - balanced-match "^0.4.2" - math-expression-evaluator "^1.2.14" - reduce-function-call "^1.0.1" - -reduce-function-call@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/reduce-function-call/-/reduce-function-call-1.0.1.tgz#fa02e126e695824263cab91d3a5b0fdc1dd27a9a" - dependencies: - balanced-match "~0.1.0" - -redux@3.5.2: - version "3.5.2" - resolved "https://registry.yarnpkg.com/redux/-/redux-3.5.2.tgz#4533745e970b647ec26066a83aa30e9e26faf843" - dependencies: - lodash "^4.2.1" - lodash-es "^4.2.1" - loose-envify "^1.1.0" - symbol-observable "^0.2.3" - -regenerate@^1.2.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.2.tgz#d1941c67bad437e1be76433add5b385f95b19260" - -regenerator-runtime@^0.9.5: - version "0.9.6" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.9.6.tgz#d33eb95d0d2001a4be39659707c51b0cb71ce029" - -regex-cache@^0.4.2: - version "0.4.3" - resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.3.tgz#9b1a6c35d4d0dfcef5711ae651e8e9d3d7114145" - dependencies: - is-equal-shallow "^0.1.3" - is-primitive "^2.0.0" - -regexpu-core@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-1.0.0.tgz#86a763f58ee4d7c2f6b102e4764050de7ed90c6b" - dependencies: - regenerate "^1.2.1" - regjsgen "^0.2.0" - regjsparser "^0.1.4" - -regexpu-core@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" - dependencies: - regenerate "^1.2.1" - regjsgen "^0.2.0" - regjsparser "^0.1.4" - -regjsgen@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" - -regjsparser@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" - dependencies: - jsesc "~0.5.0" - -remark-html@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/remark-html/-/remark-html-3.0.0.tgz#ce2f7cb8ecebae737a91aa3e3e906e20da488d2d" - dependencies: - collapse-white-space "^1.0.0" - detab "^1.0.0" - normalize-uri "^1.0.0" - object-assign "^4.0.1" - trim "0.0.1" - trim-lines "^1.0.0" - unist-util-visit "^1.0.0" - -remark-slug@^4.0.0: - version "4.2.2" - resolved "https://registry.yarnpkg.com/remark-slug/-/remark-slug-4.2.2.tgz#3cfaa02e2e24d98405b296072f2ebbdfad279eb6" - dependencies: - github-slugger "^1.0.0" - mdast-util-to-string "^1.0.0" - unist-util-visit "^1.0.0" - -remark-toc@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/remark-toc/-/remark-toc-3.1.0.tgz#fa978107005d868753001134b39690dcb2e3eb62" - dependencies: - mdast-util-toc "^2.0.0" - remark-slug "^4.0.0" - -remark@^4.1.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/remark/-/remark-4.2.2.tgz#42dc5d0b3a6a2d5443e7cbdbb2a3202854be698f" - dependencies: - camelcase "^2.0.0" - ccount "^1.0.0" - chalk "^1.0.0" - chokidar "^1.0.5" - collapse-white-space "^1.0.0" - commander "^2.0.0" - concat-stream "^1.0.0" - debug "^2.0.0" - elegant-spinner "^1.0.0" - extend "^3.0.0" - glob "^7.0.0" - globby "^4.0.0" - log-update "^1.0.1" - longest-streak "^1.0.0" - markdown-table "^0.4.0" - minimatch "^3.0.0" - npm-prefix "^1.0.1" - parse-entities "^1.0.0" - repeat-string "^1.5.0" - stringify-entities "^1.0.0" - to-vfile "^1.0.0" - trim "^0.0.1" - trim-trailing-lines "^1.0.0" - unified "^3.0.0" - unist-util-remove-position "^1.0.0" - user-home "^2.0.0" - vfile "^1.1.0" - vfile-find-down "^1.0.0" - vfile-find-up "^1.0.0" - vfile-location "^2.0.0" - vfile-reporter "^1.5.0" - ware "^1.3.0" - -remote-origin-url@0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/remote-origin-url/-/remote-origin-url-0.4.0.tgz#4d3e2902f34e2d37d1c263d87710b77eb4086a30" - dependencies: - parse-git-config "^0.2.0" - -repeat-element@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" - -repeat-string@^1.5.0, repeat-string@^1.5.2, repeat-string@^1.5.4: - version "1.6.1" - resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" - -repeating@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" - dependencies: - is-finite "^1.0.0" - -replace-ext@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-0.0.1.tgz#29bbd92078a739f0bcce2b4ee41e837953522924" - -request@^2.75.0: - version "2.78.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.78.0.tgz#e1c8dec346e1c81923b24acdb337f11decabe9cc" - dependencies: - aws-sign2 "~0.6.0" - aws4 "^1.2.1" - caseless "~0.11.0" - combined-stream "~1.0.5" - extend "~3.0.0" - forever-agent "~0.6.1" - form-data "~2.1.1" - har-validator "~2.0.6" - hawk "~3.1.3" - http-signature "~1.1.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.7" - node-uuid "~1.4.7" - oauth-sign "~0.8.1" - qs "~6.3.0" - stringstream "~0.0.4" - tough-cookie "~2.3.0" - tunnel-agent "~0.4.1" - -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - -require-from-string@^1.1.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-1.2.1.tgz#529c9ccef27380adfec9a2f965b649bbee636418" - -require-main-filename@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" - -require-uncached@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" - dependencies: - caller-path "^0.1.0" - resolve-from "^1.0.0" - -resolve-from@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" - -resolve-from@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-2.0.0.tgz#9480ab20e94ffa1d9e80a804c7ea147611966b57" - -resolve@^1.1.3, resolve@^1.1.6, resolve@^1.1.7, resolve@1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" - -restore-cursor@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541" - dependencies: - exit-hook "^1.0.0" - onetime "^1.0.0" - -right-align@^0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" - dependencies: - align-text "^0.1.1" - -rimraf@^2.2.8, rimraf@^2.4.4, rimraf@^2.5.4, rimraf@~2.5.1, rimraf@~2.5.4, rimraf@2: - version "2.5.4" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.5.4.tgz#96800093cbf1a0c86bd95b4625467535c29dfa04" - dependencies: - glob "^7.0.5" - -rimraf@~2.2.6: - version "2.2.8" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.2.8.tgz#e439be2aaee327321952730f99a8929e4fc50582" - -ripemd160@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-0.2.0.tgz#2bf198bde167cacfa51c0a928e84b68bbe171fce" - -run-async@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/run-async/-/run-async-0.1.0.tgz#c8ad4a5e110661e402a7d21b530e009f25f8e389" - dependencies: - once "^1.3.0" - -run-parallel@^1.1.4: - version "1.1.6" - resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.1.6.tgz#29003c9a2163e01e2d2dfc90575f2c6c1d61a039" - -rx-lite@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102" - -sax@^1.1.4, sax@>=0.6.0, sax@~1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.1.tgz#7b8e656190b228e81a66aea748480d828cd2d37a" - -selenium-webdriver@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-3.0.1.tgz#a2dea5da4a97f6672e89e7ca7276cefa365147a7" - dependencies: - adm-zip "^0.4.7" - rimraf "^2.5.4" - tmp "0.0.30" - xml2js "^0.4.17" - -semver@^5.0.3, semver@^5.1.0, semver@~5.3.0, "semver@2 || 3 || 4 || 5": - version "5.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" - -send@0.14.1: - version "0.14.1" - resolved "https://registry.yarnpkg.com/send/-/send-0.14.1.tgz#a954984325392f51532a7760760e459598c89f7a" - dependencies: - debug "~2.2.0" - depd "~1.1.0" - destroy "~1.0.4" - encodeurl "~1.0.1" - escape-html "~1.0.3" - etag "~1.7.0" - fresh "0.3.0" - http-errors "~1.5.0" - mime "1.3.4" - ms "0.7.1" - on-finished "~2.3.0" - range-parser "~1.2.0" - statuses "~1.3.0" - -serve-index@^1.8.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.8.0.tgz#7c5d96c13fb131101f93c1c5774f8516a1e78d3b" - dependencies: - accepts "~1.3.3" - batch "0.5.3" - debug "~2.2.0" - escape-html "~1.0.3" - http-errors "~1.5.0" - mime-types "~2.1.11" - parseurl "~1.3.1" - -serve-static@~1.11.1: - version "1.11.1" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.11.1.tgz#d6cce7693505f733c759de57befc1af76c0f0805" - dependencies: - encodeurl "~1.0.1" - escape-html "~1.0.3" - parseurl "~1.3.1" - send "0.14.1" - -set-blocking@^2.0.0, set-blocking@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - -set-immediate-shim@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" - -setprototypeof@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.0.2.tgz#81a552141ec104b88e89ce383103ad5c66564d08" - -sha.js@2.2.6: - version "2.2.6" - resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.2.6.tgz#17ddeddc5f722fb66501658895461977867315ba" - -shelljs@^0.7.5: - version "0.7.5" - resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.5.tgz#2eef7a50a21e1ccf37da00df767ec69e30ad0675" - dependencies: - glob "^7.0.0" - interpret "^1.0.0" - rechoir "^0.6.2" - -shellsubstitute@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/shellsubstitute/-/shellsubstitute-1.2.0.tgz#e4f702a50c518b0f6fe98451890d705af29b6b70" - -sigmund@~1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" - -signal-exit@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-2.1.2.tgz#375879b1f92ebc3b334480d038dc546a6d558564" - -signal-exit@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.1.tgz#5a4c884992b63a7acd9badb7894c3ee9cfccad81" - -simple-html-tokenizer@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/simple-html-tokenizer/-/simple-html-tokenizer-0.1.1.tgz#05c2eec579ffffe145a030ac26cfea61b980fabe" - -slash@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" - -slice-ansi@0.0.4: - version "0.0.4" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" - -sntp@1.x.x: - version "1.0.9" - resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198" - dependencies: - hoek "2.x.x" - -sort-keys@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad" - dependencies: - is-plain-obj "^1.0.0" - -sorted-object@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/sorted-object/-/sorted-object-2.0.1.tgz#7d631f4bd3a798a24af1dffcfbfe83337a5df5fc" - -source-list-map@^0.1.4, source-list-map@~0.1.0: - version "0.1.6" - resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-0.1.6.tgz#e1e6f94f0b40c4d28dcf8f5b8766e0e45636877f" - -source-map-support@^0.4.2: - version "0.4.6" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.6.tgz#32552aa64b458392a85eab3b0b5ee61527167aeb" - dependencies: - source-map "^0.5.3" - -source-map@^0.4.2, source-map@^0.4.4, source-map@~0.4.1: - version "0.4.4" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" - dependencies: - amdefine ">=0.0.4" - -source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.0, source-map@~0.5.1, source-map@~0.5.3: - version "0.5.6" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" - -source-map@~0.1.30: - version "0.1.43" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346" - dependencies: - amdefine ">=0.0.4" - -spdx-correct@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-1.0.2.tgz#4b3073d933ff51f3912f03ac5519498a4150db40" - dependencies: - spdx-license-ids "^1.0.2" - -spdx-expression-parse@~1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz#9bdf2f20e1f40ed447fbe273266191fced51626c" - -spdx-license-ids@^1.0.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz#c9df7a3424594ade6bd11900d596696dc06bac57" - -specificity@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/specificity/-/specificity-0.3.0.tgz#332472d4e5eb5af20821171933998a6bc3b1ce6f" - -split2@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/split2/-/split2-0.2.1.tgz#02ddac9adc03ec0bb78c1282ec079ca6e85ae900" - dependencies: - through2 "~0.6.1" - -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - -sshpk@^1.7.0: - version "1.10.1" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.10.1.tgz#30e1a5d329244974a1af61511339d595af6638b0" - dependencies: - asn1 "~0.2.3" - assert-plus "^1.0.0" - dashdash "^1.12.0" - getpass "^0.1.1" - optionalDependencies: - bcrypt-pbkdf "^1.0.0" - ecc-jsbn "~0.1.1" - jodid25519 "^1.0.0" - jsbn "~0.1.0" - tweetnacl "~0.14.0" - -stack-trace@~0.0.7: - version "0.0.9" - resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.9.tgz#a8f6eaeca90674c333e7c43953f275b451510695" - -"statuses@>= 1.3.1 < 2", statuses@~1.3.0, statuses@1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e" - -stream-array@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/stream-array/-/stream-array-1.1.2.tgz#9e5f7345f2137c30ee3b498b9114e80b52bb7eb5" - dependencies: - readable-stream "~2.1.0" - -stream-browserify@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-1.0.0.tgz#bf9b4abfb42b274d751479e44e0ff2656b6f1193" - dependencies: - inherits "~2.0.1" - readable-stream "^1.0.27-1" - -stream-combiner@^0.2.1: - version "0.2.2" - resolved "https://registry.yarnpkg.com/stream-combiner/-/stream-combiner-0.2.2.tgz#aec8cbac177b56b6f4fa479ced8c1912cee52858" - dependencies: - duplexer "~0.1.1" - through "~2.3.4" - -stream-combiner2@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/stream-combiner2/-/stream-combiner2-1.1.1.tgz#fb4d8a1420ea362764e21ad4780397bebcb41cbe" - dependencies: - duplexer2 "~0.1.0" - readable-stream "^2.0.2" - -stream-shift@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" - -strict-uri-encode@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" - -string_decoder@~0.10.25, string_decoder@~0.10.x: - version "0.10.31" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" - -string-width@^1.0.0, string-width@^1.0.1, string-width@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - strip-ansi "^3.0.0" - -string-width@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.0.0.tgz#635c5436cc72a6e0c387ceca278d4e2eec52687e" - dependencies: - is-fullwidth-code-point "^2.0.0" - strip-ansi "^3.0.0" - -stringify-entities@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/stringify-entities/-/stringify-entities-1.2.0.tgz#b53ab7fc33972cab0d7a1006a82f1318af4572e1" - dependencies: - character-entities-html4 "^1.0.0" - character-entities-legacy "^1.0.0" - -stringstream@~0.0.4: - version "0.0.5" - resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" - -strip-ansi@^3.0.0, strip-ansi@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - dependencies: - ansi-regex "^2.0.0" - -strip-bom-stream@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-bom-stream/-/strip-bom-stream-1.0.0.tgz#e7144398577d51a6bed0fa1994fa05f43fd988ee" - dependencies: - first-chunk-stream "^1.0.0" - strip-bom "^2.0.0" - -strip-bom@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" - dependencies: - is-utf8 "^0.2.0" - -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - -strip-indent@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" - dependencies: - get-stdin "^4.0.1" - -strip-json-comments@^2.0.0, strip-json-comments@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - -strip-json-comments@~1.0.1, strip-json-comments@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-1.0.4.tgz#1e15fbcac97d3ee99bf2d73b4c656b082bbafb91" - -style-loader@^0.13.1: - version "0.13.1" - resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-0.13.1.tgz#468280efbc0473023cd3a6cd56e33b5a1d7fc3a9" - dependencies: - loader-utils "^0.2.7" - -style-search@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/style-search/-/style-search-0.1.0.tgz#7958c793e47e32e07d2b5cafe5c0bf8e12e77902" - -stylehacks@^2.3.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-2.3.1.tgz#de49e8baa2e12b29c35b416b337094839bc97b35" - dependencies: - browserslist "^1.1.3" - chalk "^1.1.1" - log-symbols "^1.0.2" - minimist "^1.2.0" - plur "^2.1.2" - postcss "^5.0.18" - postcss-reporter "^1.3.3" - postcss-selector-parser "^2.0.0" - read-file-stdin "^0.2.1" - text-table "^0.2.0" - write-file-stdout "0.0.2" - -stylelint@^7.4.2: - version "7.5.0" - resolved "https://registry.yarnpkg.com/stylelint/-/stylelint-7.5.0.tgz#fe19a22e793c419d4fc31d58f3948d599fdb81fb" - dependencies: - autoprefixer "^6.0.0" - balanced-match "^0.4.0" - chalk "^1.1.1" - colorguard "^1.2.0" - cosmiconfig "^2.0.0" - doiuse "^2.4.1" - execall "^1.0.0" - get-stdin "^5.0.0" - globby "^6.0.0" - globjoin "^0.1.4" - html-tags "^1.1.1" - ignore "^3.2.0" - known-css-properties "^0.0.5" - lodash "^4.0.0" - log-symbols "^1.0.2" - meow "^3.3.0" - multimatch "^2.1.0" - normalize-selector "^0.2.0" - postcss "^5.0.20" - postcss-less "^0.14.0" - postcss-media-query-parser "^0.2.0" - postcss-reporter "^1.3.0" - postcss-resolve-nested-selector "^0.1.1" - postcss-scss "^0.3.0" - postcss-selector-parser "^2.1.1" - postcss-value-parser "^3.1.1" - resolve-from "^2.0.0" - specificity "^0.3.0" - string-width "^2.0.0" - style-search "^0.1.0" - stylehacks "^2.3.0" - sugarss "^0.2.0" - svg-tags "^1.0.0" - table "^3.7.8" - -subarg@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/subarg/-/subarg-1.0.0.tgz#f62cf17581e996b48fc965699f54c06ae268b8d2" - dependencies: - minimist "^1.1.0" - -sugarss@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/sugarss/-/sugarss-0.2.0.tgz#ac34237563327c6ff897b64742bf6aec190ad39e" - dependencies: - postcss "^5.2.4" - -supports-color@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" - -supports-color@^3.1.0, supports-color@^3.1.2, supports-color@3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.1.2.tgz#72a262894d9d408b956ca05ff37b2ed8a6e2a2d5" - dependencies: - has-flag "^1.0.0" - -supports-color@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-1.2.0.tgz#ff1ed1e61169d06b3cf2d588e188b18d8847e17e" - -svg-inline-loader@^0.7.1: - version "0.7.1" - resolved "https://registry.yarnpkg.com/svg-inline-loader/-/svg-inline-loader-0.7.1.tgz#6d0e2728b7ec3414c2180b3f780bc3f7154ef226" - dependencies: - loader-utils "^0.2.11" - object-assign "^4.0.1" - simple-html-tokenizer "^0.1.1" - -svg-inline-react@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/svg-inline-react/-/svg-inline-react-1.0.2.tgz#138dfd0eb7ac52d689c3aa0a10d1d0b134a7d081" - -svg-tags@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/svg-tags/-/svg-tags-1.0.0.tgz#58f71cee3bd519b59d4b2a843b6c7de64ac04764" - -svgo@^0.7.0: - version "0.7.1" - resolved "https://registry.yarnpkg.com/svgo/-/svgo-0.7.1.tgz#287320fed972cb097e72c2bb1685f96fe08f8034" - dependencies: - coa "~1.0.1" - colors "~1.1.2" - csso "~2.2.1" - js-yaml "~3.6.1" - mkdirp "~0.5.1" - sax "~1.2.1" - whet.extend "~0.9.9" - -symbol-observable@^0.2.3: - version "0.2.4" - resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-0.2.4.tgz#95a83db26186d6af7e7a18dbd9760a2f86d08f40" - -sync-exec@^0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/sync-exec/-/sync-exec-0.6.2.tgz#717d22cc53f0ce1def5594362f3a89a2ebb91105" - -synesthesia@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/synesthesia/-/synesthesia-1.0.1.tgz#5ef95ea548c0d5c6e6f9bb4b0d0731dff864a777" - dependencies: - css-color-names "0.0.3" - -table@^3.7.8: - version "3.8.3" - resolved "https://registry.yarnpkg.com/table/-/table-3.8.3.tgz#2bbc542f0fda9861a755d3947fefd8b3f513855f" - dependencies: - ajv "^4.7.0" - ajv-keywords "^1.0.0" - chalk "^1.1.1" - lodash "^4.0.0" - slice-ansi "0.0.4" - string-width "^2.0.0" - -tapable@^0.1.8, tapable@~0.1.8: - version "0.1.10" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-0.1.10.tgz#29c35707c2b70e50d07482b5d202e8ed446dafd4" - -tar-pack@~3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/tar-pack/-/tar-pack-3.3.0.tgz#30931816418f55afc4d21775afdd6720cee45dae" - dependencies: - debug "~2.2.0" - fstream "~1.0.10" - fstream-ignore "~1.0.5" - once "~1.3.3" - readable-stream "~2.1.4" - rimraf "~2.5.1" - tar "~2.2.1" - uid-number "~0.0.6" - -tar-stream@^1.5.0: - version "1.5.2" - resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.5.2.tgz#fbc6c6e83c1a19d4cb48c7d96171fc248effc7bf" - dependencies: - bl "^1.0.0" - end-of-stream "^1.0.0" - readable-stream "^2.0.0" - xtend "^4.0.0" - -tar.gz@1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/tar.gz/-/tar.gz-1.0.5.tgz#e1ada7e45ef2241b4b1ee58123c8f40b5d3c1bc4" - dependencies: - bluebird "^2.9.34" - commander "^2.8.1" - fstream "^1.0.8" - mout "^0.11.0" - tar "^2.1.1" - -tar@^2.1.1, tar@~2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1" - dependencies: - block-stream "*" - fstream "^1.0.2" - inherits "2" - -tcomb@^3.1.0: - version "3.2.15" - resolved "https://registry.yarnpkg.com/tcomb/-/tcomb-3.2.15.tgz#09e40f447976d1d9c07ff465b8377342a8fe67e1" - -temp@0.8.3: - version "0.8.3" - resolved "https://registry.yarnpkg.com/temp/-/temp-0.8.3.tgz#e0c6bc4d26b903124410e4fed81103014dfc1f59" - dependencies: - os-tmpdir "^1.0.0" - rimraf "~2.2.6" - -terminal-table@0.0.12: - version "0.0.12" - resolved "https://registry.yarnpkg.com/terminal-table/-/terminal-table-0.0.12.tgz#7b56d009aa6828dfdd10f11b654e79c062965fa2" - dependencies: - colors "^1.0.3" - eastasianwidth "^0.1.0" - -text-table@^0.2.0, text-table@~0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - -through@^2.3.6, "through@>=2.2.7 <3", through@~2.3.4: - version "2.3.8" - resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - -through2-filter@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/through2-filter/-/through2-filter-2.0.0.tgz#60bc55a0dacb76085db1f9dae99ab43f83d622ec" - dependencies: - through2 "~2.0.0" - xtend "~4.0.0" - -through2@^0.6.0, through2@^0.6.1, through2@^0.6.3, through2@~0.6.1: - version "0.6.5" - resolved "https://registry.yarnpkg.com/through2/-/through2-0.6.5.tgz#41ab9c67b29d57209071410e1d7a7a968cd3ad48" - dependencies: - readable-stream ">=1.0.33-1 <1.1.0-0" - xtend ">=4.0.0 <4.1.0-0" - -through2@^2.0.0, through2@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.1.tgz#384e75314d49f32de12eebb8136b8eb6b5d59da9" - dependencies: - readable-stream "~2.0.0" - xtend "~4.0.0" - -timed-out@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-2.0.0.tgz#f38b0ae81d3747d628001f41dafc652ace671c0a" - -timers-browserify@^1.0.1: - version "1.4.2" - resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-1.4.2.tgz#c9c58b575be8407375cb5e2462dacee74359f41d" - dependencies: - process "~0.11.0" - -tiny-lr@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/tiny-lr/-/tiny-lr-0.2.1.tgz#b3fdba802e5d56a33c2f6f10794b32e477ac729d" - dependencies: - body-parser "~1.14.0" - debug "~2.2.0" - faye-websocket "~0.10.0" - livereload-js "^2.2.0" - parseurl "~1.3.0" - qs "~5.1.0" - -tmp@0.0.30: - version "0.0.30" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.30.tgz#72419d4a8be7d6ce75148fd8b324e593a711c2ed" - dependencies: - os-tmpdir "~1.0.1" - -to-absolute-glob@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/to-absolute-glob/-/to-absolute-glob-0.1.1.tgz#1cdfa472a9ef50c239ee66999b662ca0eb39937f" - dependencies: - extend-shallow "^2.0.1" - -to-fast-properties@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.2.tgz#f3f5c0c3ba7299a7ef99427e44633257ade43320" - -to-iso-string@0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/to-iso-string/-/to-iso-string-0.0.2.tgz#4dc19e664dfccbe25bd8db508b00c6da158255d1" - -to-vfile@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/to-vfile/-/to-vfile-1.0.0.tgz#88defecd43adb2ef598625f0e3d59f7f342941ba" - dependencies: - vfile "^1.0.0" - -tough-cookie@~2.3.0: - version "2.3.2" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.2.tgz#f081f76e4c85720e6c37a5faced737150d84072a" - dependencies: - punycode "^1.4.1" - -trim-lines@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/trim-lines/-/trim-lines-1.0.0.tgz#c30caf5d15513443f44ce86e5cf338ec3b1fb25d" - -trim-newlines@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" - -trim-trailing-lines@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/trim-trailing-lines/-/trim-trailing-lines-1.0.0.tgz#dbb638247a2232f669121c458fccd48fc2670c8e" - -trim@^0.0.1, trim@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/trim/-/trim-0.0.1.tgz#5858547f6b290757ee95cccc666fb50084c460dd" - -tryit@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/tryit/-/tryit-1.0.3.tgz#393be730a9446fd1ead6da59a014308f36c289cb" - -tty-browserify@0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" - -tunnel-agent@~0.4.1: - version "0.4.3" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.4.3.tgz#6373db76909fe570e08d73583365ed828a74eeeb" - -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.3" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.3.tgz#3da382f670f25ded78d7b3d1792119bca0b7132d" - -type-check@~0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" - dependencies: - prelude-ls "~1.1.2" - -type-is@~1.6.10, type-is@~1.6.13: - version "1.6.13" - resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.13.tgz#6e83ba7bc30cd33a7bb0b7fb00737a2085bf9d08" - dependencies: - media-typer "0.3.0" - mime-types "~2.1.11" - -typedarray@~0.0.5: - version "0.0.6" - resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" - -ua-parser-js@^0.7.9: - version "0.7.12" - resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.12.tgz#04c81a99bdd5dc52263ea29d24c6bf8d4818a4bb" - -uglify-js@~2.6.0: - version "2.6.4" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.6.4.tgz#65ea2fb3059c9394692f15fed87c2b36c16b9adf" - dependencies: - async "~0.2.6" - source-map "~0.5.1" - uglify-to-browserify "~1.0.0" - yargs "~3.10.0" - -uglify-js@~2.7.3: - version "2.7.4" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.7.4.tgz#a295a0de12b6a650c031c40deb0dc40b14568bd2" - dependencies: - async "~0.2.6" - source-map "~0.5.1" - uglify-to-browserify "~1.0.0" - yargs "~3.10.0" - -uglify-to-browserify@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" - -uid-number@~0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" - -ultron@1.0.x: - version "1.0.2" - resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.0.2.tgz#ace116ab557cd197386a4e88f4685378c8b2e4fa" - -unc-path-regex@^0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa" - -unherit@^1.0.0, unherit@^1.0.4: - version "1.1.0" - resolved "https://registry.yarnpkg.com/unherit/-/unherit-1.1.0.tgz#6b9aaedfbf73df1756ad9e316dd981885840cd7d" - dependencies: - inherits "^2.0.1" - xtend "^4.0.1" - -unified@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/unified/-/unified-3.0.0.tgz#85ce4169b09ee9f084d07f4d0a1fbe3939518712" - dependencies: - attach-ware "^2.0.0" - bail "^1.0.0" - extend "^3.0.0" - unherit "^1.0.4" - vfile "^1.0.0" - ware "^1.3.0" - -uniq@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" - -uniqid@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/uniqid/-/uniqid-4.1.0.tgz#33d9679f65022f48988a03fd24e7dcaf8f109eca" - dependencies: - macaddress "^0.2.8" - -uniqs@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/uniqs/-/uniqs-2.0.0.tgz#ffede4b36b25290696e6e165d4a59edb998e6b02" - -unique-stream@^2.0.2: - version "2.2.1" - resolved "https://registry.yarnpkg.com/unique-stream/-/unique-stream-2.2.1.tgz#5aa003cfbe94c5ff866c4e7d668bb1c4dbadb369" - dependencies: - json-stable-stringify "^1.0.0" - through2-filter "^2.0.0" - -unist-builder@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/unist-builder/-/unist-builder-1.0.2.tgz#8c3b9903ef64bcfb117dd7cf6a5d98fc1b3b27b6" - dependencies: - object-assign "^4.1.0" - -unist-util-remove-position@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/unist-util-remove-position/-/unist-util-remove-position-1.1.0.tgz#2444fedc344bc5f540dab6353e013b6d78101dc2" - dependencies: - unist-util-visit "^1.1.0" - -unist-util-visit@^1.0.0, unist-util-visit@^1.0.1, unist-util-visit@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-1.1.0.tgz#2029869661db425ee082a82e2e02dd6cfc95db99" - -unpipe@~1.0.0, unpipe@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" - -untildify@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/untildify/-/untildify-2.1.0.tgz#17eb2807987f76952e9c0485fc311d06a826a2e0" - dependencies: - os-homedir "^1.0.0" - -unzip-response@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-1.0.2.tgz#b984f0877fc0a89c2c773cc1ef7b5b232b5b06fe" - -url-parse-lax@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" - dependencies: - prepend-http "^1.0.1" - -url@~0.10.1: - version "0.10.3" - resolved "https://registry.yarnpkg.com/url/-/url-0.10.3.tgz#021e4d9c7705f21bbf37d03ceb58767402774c64" - dependencies: - punycode "1.3.2" - querystring "0.2.0" - -urllite@~0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/urllite/-/urllite-0.5.0.tgz#1b7bb9ca3fb0db9520de113466bbcf7cc341451a" - dependencies: - xtend "~4.0.0" - -user-home@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/user-home/-/user-home-1.1.1.tgz#2b5be23a32b63a7c9deb8d0f28d485724a3df190" - -user-home@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/user-home/-/user-home-2.0.0.tgz#9c70bfd8169bc1dcbf48604e0f04b8b49cde9e9f" - dependencies: - os-homedir "^1.0.0" - -util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - -util@~0.10.3, util@0.10.3: - version "0.10.3" - resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" - dependencies: - inherits "2.0.1" - -utils-merge@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.0.tgz#0294fb922bb9375153541c4f7096231f287c8af8" - -v8flags@^2.0.10: - version "2.0.11" - resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-2.0.11.tgz#bca8f30f0d6d60612cc2c00641e6962d42ae6881" - dependencies: - user-home "^1.1.1" - -vali-date@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/vali-date/-/vali-date-1.0.0.tgz#1b904a59609fb328ef078138420934f6b86709a6" - -validate-npm-package-license@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz#2804babe712ad3379459acfbe24746ab2c303fbc" - dependencies: - spdx-correct "~1.0.0" - spdx-expression-parse "~1.0.0" - -vary@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.0.tgz#e1e5affbbd16ae768dd2674394b9ad3022653140" - -vendors@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/vendors/-/vendors-1.0.1.tgz#37ad73c8ee417fb3d580e785312307d274847f22" - -verror@1.3.6: - version "1.3.6" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.3.6.tgz#cff5df12946d297d2baaefaa2689e25be01c005c" - dependencies: - extsprintf "1.0.2" - -vfile-find-down@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/vfile-find-down/-/vfile-find-down-1.0.0.tgz#84a4d66d03513f6140a84e0776ef0848d4f0ad95" - dependencies: - to-vfile "^1.0.0" - -vfile-find-up@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/vfile-find-up/-/vfile-find-up-1.0.0.tgz#5604da6fe453b34350637984eb5fe4909e280390" - dependencies: - to-vfile "^1.0.0" - -vfile-location@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/vfile-location/-/vfile-location-2.0.1.tgz#0bf8816f732b0f8bd902a56fda4c62c8e935dc52" - -vfile-reporter@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/vfile-reporter/-/vfile-reporter-1.5.0.tgz#21a7009bfe55e24df8ff432aa5bf6f6efa74e418" - dependencies: - chalk "^1.1.0" - log-symbols "^1.0.2" - plur "^2.0.0" - repeat-string "^1.5.0" - string-width "^1.0.0" - text-table "^0.2.0" - vfile-sort "^1.0.0" - -vfile-reporter@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/vfile-reporter/-/vfile-reporter-2.1.0.tgz#e492482a5d46ebb5bfd24cf11258ca689303ca8c" - dependencies: - chalk "^1.1.0" - log-symbols "^1.0.2" - plur "^2.0.0" - repeat-string "^1.5.0" - string-width "^1.0.0" - strip-ansi "^3.0.1" - text-table "^0.2.0" - vfile-sort "^1.0.0" - -vfile-sort@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/vfile-sort/-/vfile-sort-1.0.0.tgz#17ee491ba43e8951bb22913fcff32a7dc4d234d4" - -vfile@^1.0.0, vfile@^1.1.0, vfile@^1.1.2: - version "1.4.0" - resolved "https://registry.yarnpkg.com/vfile/-/vfile-1.4.0.tgz#c0fd6fa484f8debdb771f68c31ed75d88da97fe7" - -vinyl-fs@^2.3.1: - version "2.4.4" - resolved "https://registry.yarnpkg.com/vinyl-fs/-/vinyl-fs-2.4.4.tgz#be6ff3270cb55dfd7d3063640de81f25d7532239" - dependencies: - duplexify "^3.2.0" - glob-stream "^5.3.2" - graceful-fs "^4.0.0" - gulp-sourcemaps "1.6.0" - is-valid-glob "^0.3.0" - lazystream "^1.0.0" - lodash.isequal "^4.0.0" - merge-stream "^1.0.0" - mkdirp "^0.5.0" - object-assign "^4.0.0" - readable-stream "^2.0.4" - strip-bom "^2.0.0" - strip-bom-stream "^1.0.0" - through2 "^2.0.0" - through2-filter "^2.0.0" - vali-date "^1.0.0" - vinyl "^1.0.0" - -vinyl@^1.0.0, vinyl@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-1.2.0.tgz#5c88036cf565e5df05558bfc911f8656df218884" - dependencies: - clone "^1.0.0" - clone-stats "^0.0.1" - replace-ext "0.0.1" - -vm-browserify@0.0.4: - version "0.0.4" - resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-0.0.4.tgz#5d7ea45bbef9e4a6ff65f95438e0a87c357d5a73" - dependencies: - indexof "0.0.1" - -ware@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/ware/-/ware-1.3.0.tgz#d1b14f39d2e2cb4ab8c4098f756fe4b164e473d4" - dependencies: - wrap-fn "^0.1.0" - -watchpack@^0.2.1: - version "0.2.9" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-0.2.9.tgz#62eaa4ab5e5ba35fdfc018275626e3c0f5e3fb0b" - dependencies: - async "^0.9.0" - chokidar "^1.0.0" - graceful-fs "^4.1.2" - -webpack-core@~0.6.0: - version "0.6.8" - resolved "https://registry.yarnpkg.com/webpack-core/-/webpack-core-0.6.8.tgz#edf9135de00a6a3c26dd0f14b208af0aa4af8d0a" - dependencies: - source-list-map "~0.1.0" - source-map "~0.4.1" - -webpack-dev-middleware@^1.6.1: - version "1.8.4" - resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-1.8.4.tgz#e8765c9122887ce9e3abd4cc9c3eb31b61e0948d" - dependencies: - memory-fs "~0.3.0" - mime "^1.3.4" - path-is-absolute "^1.0.0" - range-parser "^1.0.3" - -webpack-env-loader-plugin@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/webpack-env-loader-plugin/-/webpack-env-loader-plugin-0.1.4.tgz#a9d1c460fa4c306fa1c8bec5c65f9ef2e38d720c" - dependencies: - colors "^1.1.2" - strip-json-comments "^2.0.1" - webpack "^1.12.14" - yaml "^0.3.0" - yamljs "^0.2.6" - -webpack-hot-middleware@^2.12.0: - version "2.13.2" - resolved "https://registry.yarnpkg.com/webpack-hot-middleware/-/webpack-hot-middleware-2.13.2.tgz#6500b15e6d4f1a9590f8df708183f4d2ac2c3e9e" - dependencies: - ansi-html "0.0.6" - html-entities "^1.2.0" - querystring "^0.2.0" - strip-ansi "^3.0.0" - -webpack-sources@^0.1.0: - version "0.1.3" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-0.1.3.tgz#15ce2fb79d0a1da727444ba7c757bf164294f310" - dependencies: - source-list-map "~0.1.0" - source-map "~0.5.3" - -webpack@^1.12.14: - version "1.13.3" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-1.13.3.tgz#e79c46fe5a37c5ca70084ba0894c595cdcb42815" - dependencies: - acorn "^3.0.0" - async "^1.3.0" - clone "^1.0.2" - enhanced-resolve "~0.9.0" - interpret "^0.6.4" - loader-utils "^0.2.11" - memory-fs "~0.3.0" - mkdirp "~0.5.0" - node-libs-browser "^0.6.0" - optimist "~0.6.0" - supports-color "^3.1.0" - tapable "~0.1.8" - uglify-js "~2.7.3" - watchpack "^0.2.1" - webpack-core "~0.6.0" - -webpack@1.13.1: - version "1.13.1" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-1.13.1.tgz#0a69e88e5bdc593939352d5d77de0f9ac9d0871e" - dependencies: - acorn "^3.0.0" - async "^1.3.0" - clone "^1.0.2" - enhanced-resolve "~0.9.0" - interpret "^0.6.4" - loader-utils "^0.2.11" - memory-fs "~0.3.0" - mkdirp "~0.5.0" - node-libs-browser ">= 0.4.0 <=0.6.0" - optimist "~0.6.0" - supports-color "^3.1.0" - tapable "~0.1.8" - uglify-js "~2.6.0" - watchpack "^0.2.1" - webpack-core "~0.6.0" - -websocket-driver@>=0.5.1: - version "0.6.5" - resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.6.5.tgz#5cb2556ceb85f4373c6d8238aa691c8454e13a36" - dependencies: - websocket-extensions ">=0.1.1" - -websocket-extensions@>=0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.1.tgz#76899499c184b6ef754377c2dbb0cd6cb55d29e7" - -whatwg-fetch@^0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-0.9.0.tgz#0e3684c6cb9995b43efc9df03e4c365d95fd9cc0" - -whatwg-fetch@>=0.10.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.1.tgz#078b9461bbe91cea73cbce8bb122a05f9e92b772" - -whet.extend@~0.9.9: - version "0.9.9" - resolved "https://registry.yarnpkg.com/whet.extend/-/whet.extend-0.9.9.tgz#f877d5bf648c97e5aa542fadc16d6a259b9c11a1" - -which-module@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" - -which@^1.2.9: - version "1.2.12" - resolved "https://registry.yarnpkg.com/which/-/which-1.2.12.tgz#de67b5e450269f194909ef23ece4ebe416fa1192" - dependencies: - isexe "^1.1.1" - -wide-align@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.0.tgz#40edde802a71fea1f070da3e62dcda2e7add96ad" - dependencies: - string-width "^1.0.1" - -window-size@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.4.tgz#f8e1aa1ee5a53ec5bf151ffa09742a6ad7697876" - -window-size@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.2.0.tgz#b4315bb4214a3d7058ebeee892e13fa24d98b075" - -window-size@0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" - -wordwrap@~0.0.2: - version "0.0.3" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" - -wordwrap@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" - -wordwrap@0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" - -"workerjs@github:jlongster/workerjs": - version "0.1.1" - resolved "https://codeload.github.com/jlongster/workerjs/tar.gz/918a1aff3728751143f806bfb464f7d71002e7f0" - -wrap-ansi@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.0.0.tgz#7d30f8f873f9a5bbc3a64dabc8d177e071ae426f" - dependencies: - string-width "^1.0.1" - -wrap-fn@^0.1.0: - version "0.1.5" - resolved "https://registry.yarnpkg.com/wrap-fn/-/wrap-fn-0.1.5.tgz#f21b6e41016ff4a7e31720dbc63a09016bdf9845" - dependencies: - co "3.1.0" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - -write-file-stdout@0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/write-file-stdout/-/write-file-stdout-0.0.2.tgz#c252d7c7c5b1b402897630e3453c7bfe690d9ca1" - -write@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" - dependencies: - mkdirp "^0.5.1" - -ws@^1.0.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ws/-/ws-1.1.1.tgz#082ddb6c641e85d4bb451f03d52f06eabdb1f018" - dependencies: - options ">=0.0.5" - ultron "1.0.x" - -xml@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/xml/-/xml-1.0.1.tgz#78ba72020029c5bc87b8a81a3cfcd74b4a2fc1e5" - -xml2js@^0.4.17, xml2js@~0.4.4: - version "0.4.17" - resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.17.tgz#17be93eaae3f3b779359c795b419705a8817e868" - dependencies: - sax ">=0.6.0" - xmlbuilder "^4.1.0" - -xmlbuilder@^4.1.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-4.2.1.tgz#aa58a3041a066f90eaa16c2f5389ff19f3f461a5" - dependencies: - lodash "^4.0.0" - -xmlhttprequest@*: - version "1.8.0" - resolved "https://registry.yarnpkg.com/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz#67fe075c5c24fef39f9d65f5f7b7fe75171968fc" - -xtend@^4.0.0, xtend@^4.0.1, "xtend@>=4.0.0 <4.1.0-0", xtend@~4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" - -xtend@~3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-3.0.0.tgz#5cce7407baf642cba7becda568111c493f59665a" - -y18n@^3.2.0, y18n@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" - -yallist@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.0.0.tgz#306c543835f09ee1a4cb23b7bce9ab341c91cdd4" - -yaml@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-0.3.0.tgz#c31a616d07acdbc2012d73a6ba5b1b0bdd185a7f" - -yamljs@^0.2.6: - version "0.2.8" - resolved "https://registry.yarnpkg.com/yamljs/-/yamljs-0.2.8.tgz#ef23fb006e62f6ae07b406aa2a949561f336ea5c" - dependencies: - argparse "^1.0.7" - glob "^7.0.5" - -yargs-parser@^2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-2.4.1.tgz#85568de3cf150ff49fa51825f03a8c880ddcc5c4" - dependencies: - camelcase "^3.0.0" - lodash.assign "^4.0.6" - -yargs-parser@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-3.2.0.tgz#5081355d19d9d0c8c5d81ada908cb4e6d186664f" - dependencies: - camelcase "^3.0.0" - lodash.assign "^4.1.0" - -yargs@^1.2.6: - version "1.3.3" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-1.3.3.tgz#054de8b61f22eefdb7207059eaef9d6b83fb931a" - -yargs@^3.5.4: - version "3.32.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.32.0.tgz#03088e9ebf9e756b69751611d2a5ef591482c995" - dependencies: - camelcase "^2.0.1" - cliui "^3.0.3" - decamelize "^1.1.1" - os-locale "^1.4.0" - string-width "^1.0.1" - window-size "^0.1.4" - y18n "^3.2.0" - -yargs@^4.3.1: - version "4.8.1" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-4.8.1.tgz#c0c42924ca4aaa6b0e6da1739dfb216439f9ddc0" - dependencies: - cliui "^3.2.0" - decamelize "^1.1.1" - get-caller-file "^1.0.1" - lodash.assign "^4.0.3" - os-locale "^1.4.0" - read-pkg-up "^1.0.1" - require-directory "^2.1.1" - require-main-filename "^1.0.1" - set-blocking "^2.0.0" - string-width "^1.0.1" - which-module "^1.0.0" - window-size "^0.2.0" - y18n "^3.2.1" - yargs-parser "^2.4.1" - -yargs@~3.10.0: - version "3.10.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" - dependencies: - camelcase "^1.0.2" - cliui "^2.1.0" - decamelize "^1.0.0" - window-size "0.1.0" - -yargs@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-5.0.0.tgz#3355144977d05757dbb86d6e38ec056123b3a66e" - dependencies: - cliui "^3.2.0" - decamelize "^1.1.1" - get-caller-file "^1.0.1" - lodash.assign "^4.2.0" - os-locale "^1.4.0" - read-pkg-up "^1.0.1" - require-directory "^2.1.1" - require-main-filename "^1.0.1" - set-blocking "^2.0.0" - string-width "^1.0.2" - which-module "^1.0.0" - window-size "^0.2.0" - y18n "^3.2.1" - yargs-parser "^3.2.0" - -zip-stream@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/zip-stream/-/zip-stream-1.1.0.tgz#2ad479fffc168e05a888e8c348ff6813b3f13733" - dependencies: - archiver-utils "^1.3.0" - compress-commons "^1.1.0" - lodash "^4.8.0" - readable-stream "^2.0.0" -