<commit_before>/**
 * Copyright (c) 2018 <NAME>
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
import * as React from 'react';
import { connect } from 'react-redux';
import { Dispatch } from 'redux';
import { updateExpressionUI } from '../../redux/Actions';
import { ReduxAction } from '../../typings/ReduxConstants';
interface DispatchProps {
  onUpdateExpression: (payload: Expression) => void;
}

interface OwnProps {
  expression: Expression;
}

class InitialState {
  public cookies: browser.cookies.CookieProperties[] = [];
}

type ExpressionOptionsProps = OwnProps & DispatchProps;

const trimDotAndStar = (str: string) => str.replace(/^[\.\*]+|[\.\*]+$/g, '');

class ExpressionOptions extends React.Component<ExpressionOptionsProps> {
  public state = new InitialState();

  public async componentDidMount() {
    if (!this.props.expression.cleanAllCookies) {
      await this.getAllCookies();
    }
  }

  public async getAllCookies() {
    const { expression } = this.props;
    const cookies = await browser.cookies.getAll({
      domain: trimDotAndStar(expression.expression),
    });
    this.setState({ cookies });
  }

  public createCookieList(
    cookies: browser.cookies.CookieProperties[],
    expression: Expression,
  ) {
    const { onUpdateExpression } = this.props;
    const cookieNames = expression.cookieNames || [];
    return cookies.map(cookie => {
      const checked =
        expression.cookieNames && expression.cookieNames.includes(cookie.name);
      const key = `${checked}-${expression.id}-${cookie.name}`;
      return (
        <div style={{ marginLeft: '20px' }} key={key} className={'checkbox'}>
          <input
            className={'form-check-input addHover'}
            checked={checked}
            type="checkbox"
            id={key}
            onChange={e => {
              if (e.target.checked) {
                onUpdateExpression({
                  ...expression,
                  cookieNames: [...cookieNames, cookie.name],
                });
              } else {
                onUpdateExpression({
                  ...expression,
                  cookieNames: cookieNames.filter(name => name !== cookie.name),
                });
              }
            }}
          />
          <label className={'form-check-label addHover'} htmlFor={key}>
            {cookie.name}
          </label>
        </div>
      );
    });
  }

  public toggleCleanAllCookies(checked: boolean) {
    const { expression, onUpdateExpression } = this.props;
    if (!expression.cleanAllCookies) {
      this.getAllCookies();
    }
    onUpdateExpression({
      ...expression,
      cleanAllCookies: checked,
    });
  }

  public toggleCleanLocalstorage(checked: boolean) {
    const { expression, onUpdateExpression } = this.props;
    onUpdateExpression({
      ...expression,
      cleanLocalStorage: checked,
    });
  }

  public render() {
    const { cookies } = this.state;
    const { expression } = this.props;
    const dropList =
      expression.cleanAllCookies === undefined || !expression.cleanAllCookies;
    const cleanLocalstorageKey = `${expression.id}-localstorage`;
    const keepAllCookiesKey = `${expression.id}-droplist`;
    return (
      <div>
        <div className={'checkbox'}>
          <input
            className={'form-check-input addHover'}
            checked={!expression.cleanLocalStorage}
            type="checkbox"
            onChange={e => this.toggleCleanLocalstorage(!e.target.checked)}
            id={cleanLocalstorageKey}
          />
          <label
            className={'form-check-label addHover'}
            htmlFor={cleanLocalstorageKey}
          >
            {'Keep Localstorage'}
          </label>
        </div>
        {}
        <div className={'checkbox'}>
          <input
            className={'form-check-input addHover'}
            checked={
              expression.cleanAllCookies === undefined ||
              expression.cleanAllCookies
            }
            type="checkbox"
            onChange={e => this.toggleCleanAllCookies(e.target.checked)}
            id={keepAllCookiesKey}
          />
          <label
            className={'form-check-label addHover'}
            htmlFor={keepAllCookiesKey}
          >
            {'Keep all cookies'}
          </label>
        </div>
        {dropList && this.createCookieList(cookies, expression)}
      </div>
    );
  }
}

const mapDispatchToProps = (dispatch: Dispatch<ReduxAction>) => ({
  onUpdateExpression(payload: Expression) {
    dispatch(updateExpressionUI(payload));
  },
});

export default connect(
  null,
  mapDispatchToProps,
)(ExpressionOptions);<commit_msg>Fix bugs with the list of cookie names<commit_after>/**
 * Copyright (c) 2018 <NAME>
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
import * as React from 'react';
import { connect } from 'react-redux';
import { Dispatch } from 'redux';
import { updateExpressionUI } from '../../redux/Actions';
import { returnOptionalCookieAPIAttributes } from '../../services/Libs';
import { ReduxAction } from '../../typings/ReduxConstants';
interface DispatchProps {
  onUpdateExpression: (payload: Expression) => void;
}
interface StateProps {
  state: State;
}
interface OwnProps {
  expression: Expression;
}

class InitialState {
  public cookies: browser.cookies.CookieProperties[] = [];
}

type ExpressionOptionsProps = OwnProps & DispatchProps & StateProps;

const trimDotAndStar = (str: string) => str.replace(/^[\.\*]+|[\.\*]+$/g, '');

/**
 * cleanAllCookies => droplist
 * undefined => false
 * false => true
 * true => false
 */
const coerceBoolean = (bool: boolean | undefined) => {
  if (bool === undefined) return false;
  return !bool;
};
class ExpressionOptions extends React.Component<ExpressionOptionsProps> {
  public state = new InitialState();

  public async componentDidMount() {
    if (coerceBoolean(this.props.expression.cleanAllCookies)) {
      await this.getAllCookies();
    }
  }
  /** Converts an expression default storeId to the defaults of the browser */
  public toPublicStoreId(storeId: string) {
    const browser: string = this.props.state.cache.browserDetect;
    if (storeId === 'default' && browser === 'Chrome') {
      return '0';
    }
    if (storeId === 'default' && browser === 'Firefox') {
      return 'firefox-default';
    }
    return storeId;
  }

  public async getAllCookies() {
    const { expression } = this.props;
    const cookies = await browser.cookies.getAll(
      returnOptionalCookieAPIAttributes(this.props.state, {
        domain: trimDotAndStar(expression.expression),
        storeId: this.toPublicStoreId(expression.storeId),
      }),
    );
    this.setState({ cookies });
  }

  public createCookieList(
    cookies: browser.cookies.CookieProperties[],
    expression: Expression,
  ) {
    const { onUpdateExpression } = this.props;
    const cookieNames = expression.cookieNames || [];
    return cookies.map(cookie => {
      const checked =
        expression.cookieNames && expression.cookieNames.includes(cookie.name);
      const key = `${checked}-${expression.id}-${cookie.name}`;
      return (
        <div style={{ marginLeft: '20px' }} key={key} className={'checkbox'}>
          <input
            className={'form-check-input addHover'}
            checked={checked}
            type="checkbox"
            id={key}
            onChange={e => {
              if (e.target.checked) {
                onUpdateExpression({
                  ...expression,
                  cookieNames: [...cookieNames, cookie.name],
                });
              } else {
                onUpdateExpression({
                  ...expression,
                  cookieNames: cookieNames.filter(name => name !== cookie.name),
                });
              }
            }}
          />
          <label className={'form-check-label addHover'} htmlFor={key}>
            {cookie.name}
          </label>
        </div>
      );
    });
  }

  public toggleCleanAllCookies(checked: boolean) {
    const { expression, onUpdateExpression } = this.props;
    if (!coerceBoolean(expression.cleanAllCookies)) {
      this.getAllCookies();
    }
    onUpdateExpression({
      ...expression,
      cleanAllCookies: checked,
    });
  }

  public toggleCleanLocalstorage(checked: boolean) {
    const { expression, onUpdateExpression } = this.props;
    onUpdateExpression({
      ...expression,
      cleanLocalStorage: checked,
    });
  }

  public render() {
    const { cookies } = this.state;
    const { expression } = this.props;

    const dropList = coerceBoolean(expression.cleanAllCookies);
    const cleanLocalstorageKey = `${expression.id}-localstorage`;
    const keepAllCookiesKey = `${expression.id}-droplist`;
    return (
      <div>
        <div className={'checkbox'}>
          <input
            className={'form-check-input addHover'}
            checked={!expression.cleanLocalStorage}
            type="checkbox"
            onChange={e => this.toggleCleanLocalstorage(!e.target.checked)}
            id={cleanLocalstorageKey}
          />
          <label
            className={'form-check-label addHover'}
            htmlFor={cleanLocalstorageKey}
          >
            {'Keep Localstorage'}
          </label>
        </div>
        {}
        <div className={'checkbox'}>
          <input
            className={'form-check-input addHover'}
            checked={
              expression.cleanAllCookies === undefined ||
              expression.cleanAllCookies
            }
            type="checkbox"
            onChange={e => this.toggleCleanAllCookies(e.target.checked)}
            id={keepAllCookiesKey}
          />
          <label
            className={'form-check-label addHover'}
            htmlFor={keepAllCookiesKey}
          >
            {'Keep all cookies'}
          </label>
        </div>
        {dropList && this.createCookieList(cookies, expression)}
      </div>
    );
  }
}

const mapStateToProps = (state: State) => {
  return {
    state,
  };
};

const mapDispatchToProps = (dispatch: Dispatch<ReduxAction>) => ({
  onUpdateExpression(payload: Expression) {
    dispatch(updateExpressionUI(payload));
  },
});

export default connect(
  mapStateToProps,
  mapDispatchToProps,
)(ExpressionOptions);
{'fraction_non_alphanumeric': 0.12451849861148437, 'fraction_numerical': 0.0011645614978052494, 'mean_word_length': 2.4234897270775835, 'pattern_counts': {'":': 0, '<': 43, '<?xml version=': 0, '>': 65, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1452249', 'n_tokens_mistral': 3027, 'n_tokens_neox': 2978, 'n_words': 704}