"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.mapLinkState = mapLinkState;
exports.getHref = getHref;
exports.default = void 0;

var _url = _interopRequireDefault(require("url"));

var _path = _interopRequireDefault(require("path"));

var _querystring = _interopRequireDefault(require("querystring"));

var _components = require("@patternplate/components");

var _lodash = require("lodash");

var _reactRedux = require("react-redux");

var _reactRouterRedux = require("react-router-redux");

var _redux = require("redux");

var _actions = require("../actions");

var _item = _interopRequireDefault(require("../selectors/item"));

var _pool = require("../selectors/pool");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }

var _default = (0, _reactRedux.connect)(mapLinkState, mapDispatch)(_components.Link.RawLink);

exports.default = _default;

function mapLinkState(state, own) {
  const location = state.routing.locationBeforeTransitions;

  if (isAbsolute(own.href)) {
    return _extends({}, own, {
      external: true
    });
  }

  return Object.assign({}, own, {
    href: getHref(own, {
      base: state.base,
      location,
      item: (0, _item.default)(state),
      pool: (0, _pool.flat)(state)
    })
  });
}

function mapDispatch(dispatch, ownProps) {
  return (0, _redux.bindActionCreators)({
    onClick(e) {
      if (ownProps.external || isAbsolute(ownProps.href)) {
        return {
          type: null
        };
      }

      e.preventDefault();

      const parsed = _url.default.parse(e.currentTarget.href);

      if (parsed.hash) {
        (0, _actions.scrollTo)(parsed.hash.slice(1));
      }

      return (0, _reactRouterRedux.push)([parsed.path, parsed.hash].join(""));
    }

  }, dispatch);
}

function getHref(props, context) {
  if (props.external === true || !context.location) {
    return props.href;
  }

  const parsed = props.href ? _url.default.parse(props.href) : {
    pathname: context.location.pathname,
    query: _querystring.default.stringify(context.location.query)
  };
  parsed.query = _querystring.default.parse(parsed.query);
  const query = props.query === null ? {} : (0, _lodash.pickBy)(Object.assign({}, context.location.query, parsed.query, props.query || context.location.query), (value, key) => {
    // TODO: deduce this for all keys from reduce config
    // special case "navigation-enabled", invert logic
    if (key === "navigation-enabled") {
      return value !== true && value !== "true";
    } // if the key is not in the current query, add it


    if (!context.location.query.hasOwnProperty(key)) {
      return true;
    } // omit "falsy" values to keep url shorter


    return value !== "false" && value !== "0" && !!value;
  });
  parsed.pathname = parsed.pathname !== null ? replaceExt(parsed.pathname, ".html") : null;

  if (parsed.pathname === "/") {
    return _url.default.format({
      pathname: context.base,
      query,
      hash: props.hash || (parsed.hash || "#").slice(1)
    });
  } // Quirk: Search with prefix in static builds


  if (parsed.pathname && parsed.pathname !== null && (parsed.pathname.startsWith(`.${context.base}pattern/`) || parsed.pathname.startsWith(`.${context.base}doc/`))) {
    const pathname = typeof parsed.pathname === "string" ? parsed.pathname.slice(1) : context.location.pathname;
    return _url.default.format({
      pathname,
      query,
      hash: props.hash || (parsed.hash || "#").slice(1)
    });
  } // Legacy:
  // We used to require users to enter awkward relative/absolute paths
  // - `./doc/:docPath:`
  // - `./pattern/:patternId:`
  //
  // TODO: Deprecate this behaviour with next major version


  if (parsed.pathname && parsed.pathname !== null && ( // Older md documents might use the old linking format
  parsed.pathname.startsWith("./pattern/") || parsed.pathname.startsWith("./doc/") || // Quirk: Search with prefix in static builds
  parsed.pathname.startsWith(`.${context.base}pattern/`) || parsed.pathname.startsWith(`.${context.base}doc/`))) {
    const pathname = typeof parsed.pathname === "string" ? prefix(context.base, parsed.pathname.slice(1)) : context.location.pathname;
    return _url.default.format({
      pathname,
      query,
      hash: props.hash || (parsed.hash || "#").slice(1)
    });
  } // Try to resolve other relative links from the currently selected item


  if (context.item && !(parsed.pathname || "").startsWith("/")) {
    const rawTargetPath = (_path.default.unix || _path.default).join(_path.default.dirname(context.item.path), parsed.pathname || "");

    const targetPath = replaceExt(rawTargetPath, ".md");
    const match = context.pool.find(item => item.contentType === "doc" && item.path === targetPath);

    if (match) {
      const parsedMatch = _url.default.parse(match.href);

      return _url.default.format({
        pathname: replaceExt(parsedMatch.pathname, ".html"),
        query,
        hash: props.hash || (parsedMatch.hash || "#").slice(1)
      });
    }

    const patternTargetPath = replaceExt(rawTargetPath, "");
    const patternMatch = context.pool.find(item => item.contentType === "pattern" && _path.default.dirname(item.path) === patternTargetPath);

    if (patternMatch) {
      const parsedMatch = _url.default.parse(patternMatch.href);

      return _url.default.format({
        pathname: replaceExt(parsedMatch.pathname, ".html"),
        query,
        hash: props.hash || (parsedMatch.hash || "#").slice(1)
      });
    }
  }

  return _url.default.format({
    pathname: parsed.pathname,
    query,
    hash: props.hash || (parsed.hash || "#").slice(1)
  });
}

function prefix(base, pathname) {
  const b = norm(base);
  const p = norm(pathname);

  if (p === "") {
    return `/${b}`;
  }

  if (p.startsWith(b)) {
    return `/${p}`;
  }

  return `/${[norm(base), norm(pathname)].join("/")}`;
}

function norm(p) {
  return p.split("/").filter(Boolean).join("/");
}

function replaceExt(href, ext) {
  const parsed = _url.default.parse(href);

  if (typeof parsed.pathname === "string" && parsed.pathname !== "/") {
    parsed.pathname = [_path.default.dirname(parsed.pathname), `${_path.default.basename(parsed.pathname, _path.default.extname(parsed.path))}${ext}`].join("/");
  }

  return _url.default.format(parsed);
}

function isAbsolute(href) {
  const parsed = _url.default.parse(href || "./");

  if (parsed.protocol) {
    return true;
  }

  if ((parsed.pathname || "").startsWith("/api/static/")) {
    return true;
  }
}
//# sourceMappingURL=link.js.map