Socket
Socket
Sign inDemoInstall

@khanacademy/wonder-blocks-link

Package Overview
Dependencies
Maintainers
1
Versions
287
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@khanacademy/wonder-blocks-link - npm Package Compare versions

Comparing version 3.6.3 to 3.7.0

4

components/link-core.js

@@ -10,3 +10,3 @@ // @flow

import type {
ClickableHandlers,
ChildrenProps,
ClickableState,

@@ -19,3 +19,3 @@ } from "@khanacademy/wonder-blocks-clickable";

...SharedProps,
...ClickableHandlers,
...ChildrenProps,
...ClickableState,

@@ -22,0 +22,0 @@ href: string,

@@ -10,3 +10,3 @@ // @flow

export type SharedProps = {|
type CommonProps = {|
...AriaProps,

@@ -46,24 +46,8 @@

/**
* A target destination window for a link to open in.
*/
target?: string,
/**
* Specifies the type of relationship between the current document and the
* linked document. Should only be used when `href` is specified.
* linked document. Should only be used when `href` is specified. This
* defaults to "noopener noreferrer" when `target="_blank"`, but can be
* overridden by setting this prop to something else.
*/
rel?:
| "alternate"
| "author"
| "bookmark"
| "external"
| "help"
| "license"
| "next"
| "nofollow"
| "noreferrer"
| "noopener"
| "prev"
| "search"
| "tag",
rel?: string,

@@ -130,11 +114,2 @@ /**

/**
* Run async code before navigating to the URL passed to `href`. If the
* promise returned rejects then navigation will not occur.
*
* If both safeWithNav and beforeNav are provided, beforeNav will be run
* first and safeWithNav will only be run if beforeNav does not reject.
*/
beforeNav?: () => Promise<mixed>,
/**
* Run async code in the background while client-side navigating. If the

@@ -158,2 +133,31 @@ * browser does a full page load navigation, the callback promise must be

export type SharedProps =
| {|
...CommonProps,
/**
* A target destination window for a link to open in. We only support
* "_blank" which opens the URL in a new tab.
*/
target?: "_blank",
|}
| {|
...CommonProps,
/**
* Run async code before navigating to the URL passed to `href`. If the
* promise returned rejects then navigation will not occur.
*
* If both safeWithNav and beforeNav are provided, beforeNav will be run
* first and safeWithNav will only be run if beforeNav does not reject.
*
* WARNING: Using this with `target="_blank"` will trigger built-in popup
* blockers in Firefox and Safari. This is because we do navigation
* programmatically and `beforeNav` causes a delay which means that the
* browser can't make a directly link between a user action and the
* navigation.
*/
beforeNav?: () => Promise<mixed>,
|};
/**

@@ -187,3 +191,3 @@ * Reusable link component.

onClick,
beforeNav,
beforeNav = undefined,
safeWithNav,

@@ -196,3 +200,3 @@ href,

onKeyUp,
target,
target = undefined,
...sharedProps

@@ -207,35 +211,74 @@ } = this.props;

return (
<ClickableBehavior
disabled={false}
href={href}
role="link"
onClick={onClick}
beforeNav={beforeNav}
safeWithNav={safeWithNav}
target={target}
onKeyDown={onKeyDown}
onKeyUp={onKeyUp}
>
{(state, {tabIndex: clickableTabIndex, ...handlers}) => {
return (
<LinkCore
{...sharedProps}
{...state}
{...handlers}
skipClientNav={skipClientNav}
href={href}
target={target}
// If tabIndex is provide to the component we allow
// it to override the tabIndex provide to use by
// ClickableBehavior.
tabIndex={tabIndex || clickableTabIndex}
>
{children}
</LinkCore>
);
}}
</ClickableBehavior>
);
if (beforeNav) {
return (
<ClickableBehavior
disabled={false}
href={href}
role="link"
onClick={onClick}
beforeNav={beforeNav}
safeWithNav={safeWithNav}
onKeyDown={onKeyDown}
onKeyUp={onKeyUp}
>
{(
state,
{tabIndex: clickableTabIndex, ...childrenProps},
) => {
return (
<LinkCore
{...sharedProps}
{...state}
{...childrenProps}
skipClientNav={skipClientNav}
href={href}
target={target}
// If tabIndex is provide to the component we allow
// it to override the tabIndex provide to use by
// ClickableBehavior.
tabIndex={tabIndex || clickableTabIndex}
>
{children}
</LinkCore>
);
}}
</ClickableBehavior>
);
} else {
return (
<ClickableBehavior
disabled={false}
href={href}
role="link"
onClick={onClick}
safeWithNav={safeWithNav}
target={target}
onKeyDown={onKeyDown}
onKeyUp={onKeyUp}
>
{(
state,
{tabIndex: clickableTabIndex, ...childrenProps},
) => {
return (
<LinkCore
{...sharedProps}
{...state}
{...childrenProps}
skipClientNav={skipClientNav}
href={href}
target={target}
// If tabIndex is provide to the component we allow
// it to override the tabIndex provide to use by
// ClickableBehavior.
tabIndex={tabIndex || clickableTabIndex}
>
{children}
</LinkCore>
);
}}
</ClickableBehavior>
);
}
}
}

@@ -363,3 +363,4 @@ import { createElement, Component } from 'react';

onClick = _this$props.onClick,
beforeNav = _this$props.beforeNav,
_this$props$beforeNav = _this$props.beforeNav,
beforeNav = _this$props$beforeNav === void 0 ? undefined : _this$props$beforeNav,
safeWithNav = _this$props.safeWithNav,

@@ -372,30 +373,57 @@ href = _this$props.href,

onKeyUp = _this$props.onKeyUp,
target = _this$props.target,
_this$props$target = _this$props.target,
target = _this$props$target === void 0 ? undefined : _this$props$target,
sharedProps = _objectWithoutProperties(_this$props, ["onClick", "beforeNav", "safeWithNav", "href", "skipClientNav", "children", "tabIndex", "onKeyDown", "onKeyUp", "target"]);
var ClickableBehavior = getClickableBehavior(href, skipClientNav, this.context.router);
return /*#__PURE__*/createElement(ClickableBehavior, {
disabled: false,
href: href,
role: "link",
onClick: onClick,
beforeNav: beforeNav,
safeWithNav: safeWithNav,
target: target,
onKeyDown: onKeyDown,
onKeyUp: onKeyUp
}, function (state, _ref) {
var clickableTabIndex = _ref.tabIndex,
handlers = _objectWithoutProperties(_ref, ["tabIndex"]);
return /*#__PURE__*/createElement(LinkCore, _extends({}, sharedProps, state, handlers, {
skipClientNav: skipClientNav,
if (beforeNav) {
return /*#__PURE__*/createElement(ClickableBehavior, {
disabled: false,
href: href,
target: target // If tabIndex is provide to the component we allow
// it to override the tabIndex provide to use by
// ClickableBehavior.
,
tabIndex: tabIndex || clickableTabIndex
}), children);
});
role: "link",
onClick: onClick,
beforeNav: beforeNav,
safeWithNav: safeWithNav,
onKeyDown: onKeyDown,
onKeyUp: onKeyUp
}, function (state, _ref) {
var clickableTabIndex = _ref.tabIndex,
childrenProps = _objectWithoutProperties(_ref, ["tabIndex"]);
return /*#__PURE__*/createElement(LinkCore, _extends({}, sharedProps, state, childrenProps, {
skipClientNav: skipClientNav,
href: href,
target: target // If tabIndex is provide to the component we allow
// it to override the tabIndex provide to use by
// ClickableBehavior.
,
tabIndex: tabIndex || clickableTabIndex
}), children);
});
} else {
return /*#__PURE__*/createElement(ClickableBehavior, {
disabled: false,
href: href,
role: "link",
onClick: onClick,
safeWithNav: safeWithNav,
target: target,
onKeyDown: onKeyDown,
onKeyUp: onKeyUp
}, function (state, _ref2) {
var clickableTabIndex = _ref2.tabIndex,
childrenProps = _objectWithoutProperties(_ref2, ["tabIndex"]);
return /*#__PURE__*/createElement(LinkCore, _extends({}, sharedProps, state, childrenProps, {
skipClientNav: skipClientNav,
href: href,
target: target // If tabIndex is provide to the component we allow
// it to override the tabIndex provide to use by
// ClickableBehavior.
,
tabIndex: tabIndex || clickableTabIndex
}), children);
});
}
}

@@ -402,0 +430,0 @@ }]);

@@ -151,2 +151,6 @@ module.exports =

// EXTERNAL MODULE: external "@khanacademy/wonder-blocks-color"
var wonder_blocks_color_ = __webpack_require__(1);
var wonder_blocks_color_default = /*#__PURE__*/__webpack_require__.n(wonder_blocks_color_);
// CONCATENATED MODULE: ./packages/wonder-blocks-clickable/dist/es/index.js

@@ -161,2 +165,3 @@ function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }

function _classCallCheck(instance, Constructor) {

@@ -485,4 +490,4 @@ if (!(instance instanceof Constructor)) {

* `ClickableBehavior` accepts a function as `children` which is passed state
* and an object containing event handlers. The `children` function should
* return a clickable React Element of some sort.
* and an object containing event handlers and some other props. The `children`
* function should return a clickable React Element of some sort.
*

@@ -499,7 +504,7 @@ * Example:

* >
* {({hovered}, handlers) =>
* {({hovered}, childrenProps) =>
* <RoundRect
* textcolor='white'
* backgroundColor={hovered ? 'red' : 'blue'}}
* {...handlers}
* {...childrenProps}
* >

@@ -741,6 +746,12 @@ * {this.props.children}

skipClientNav = _this$props4.skipClientNav,
target = _this$props4.target;
_this$props4$target = _this$props4.target,
target = _this$props4$target === void 0 ? undefined : _this$props4$target;
if (href) {
if (history && !skipClientNav) {
if (target === "_blank") {
window.open(href, "_blank");
this.setState({
waiting: false
});
} else if (history && !skipClientNav) {
history.push(href);

@@ -751,9 +762,4 @@ this.setState({

} else {
if (target === "_blank") {
window.open(href, "_blank");
} else {
window.location.assign(href);
} // We don't bother clearing the waiting state, the full page
window.location.assign(href); // We don't bother clearing the waiting state, the full page
// load navigation will do that for us by loading a new page.
}

@@ -776,3 +782,3 @@ }

if (history && !skipClientNav) {
if (history && !skipClientNav || this.props.target === "_blank") {
// client-side nav

@@ -878,3 +884,3 @@ safeWithNav();

value: function render() {
var handlers = this.props.disabled ? disabledHandlers : {
var childrenProps = this.props.disabled ? disabledHandlers : {
onClick: this.handleClick,

@@ -896,5 +902,10 @@ onMouseEnter: this.handleMouseEnter,

tabIndex: 0
};
}; // When the link is set to open in a new window, we want to append some
// `rel` attributes. This is to ensure that the links we're sending folks
// to can't hijack the existing page.
// More info: https://www.jitbit.com/alexblog/256-targetblank---the-most-underestimated-vulnerability-ever/
childrenProps.rel = this.props.rel || (this.props.target === "_blank" ? "noopener noreferrer" : undefined);
var children = this.props.children;
return children && children(this.state, handlers);
return children && children(this.state, childrenProps);
}

@@ -1005,3 +1016,3 @@ }]);

role: _this.props.role,
target: _this.props.target,
target: _this.props.target || undefined,
"aria-disabled": _this.props.disabled ? "true" : undefined

@@ -1013,3 +1024,3 @@ }), _this.props.children(clickableState));

role: _this.props.role,
target: _this.props.target,
target: _this.props.target || undefined,
"aria-disabled": _this.props.disabled ? "true" : undefined

@@ -1042,23 +1053,45 @@ }), _this.props.children(clickableState));

style = _this$props.style,
target = _this$props.target,
_this$props$target = _this$props.target,
target = _this$props$target === void 0 ? undefined : _this$props$target,
testId = _this$props.testId,
onKeyDown = _this$props.onKeyDown,
onKeyUp = _this$props.onKeyUp,
restProps = _objectWithoutProperties(_this$props, ["href", "onClick", "skipClientNav", "beforeNav", "safeWithNav", "style", "target", "testId", "onKeyDown", "onKeyUp"]);
hideDefaultFocusRing = _this$props.hideDefaultFocusRing,
restProps = _objectWithoutProperties(_this$props, ["href", "onClick", "skipClientNav", "beforeNav", "safeWithNav", "style", "target", "testId", "onKeyDown", "onKeyUp", "hideDefaultFocusRing"]);
var ClickableBehavior = getClickableBehavior(href, skipClientNav, this.context.router);
return /*#__PURE__*/Object(external_react_["createElement"])(ClickableBehavior, {
href: href,
onClick: onClick,
beforeNav: beforeNav,
safeWithNav: safeWithNav,
target: target,
onKeyDown: onKeyDown,
onKeyUp: onKeyUp
}, function (state, handlers) {
return _this2.getCorrectTag(state, _objectSpread2(_objectSpread2({}, restProps), {}, {
"data-test-id": testId,
style: [styles.reset, style]
}, handlers));
});
var getStyle = function getStyle(state) {
return [styles.reset, styles.link, !hideDefaultFocusRing && state.focused && styles.focused, style];
};
if (beforeNav) {
return /*#__PURE__*/Object(external_react_["createElement"])(ClickableBehavior, {
href: href,
onClick: onClick,
beforeNav: beforeNav,
safeWithNav: safeWithNav,
onKeyDown: onKeyDown,
onKeyUp: onKeyUp
}, function (state, childrenProps) {
return _this2.getCorrectTag(state, _objectSpread2(_objectSpread2({}, restProps), {}, {
"data-test-id": testId,
style: getStyle(state)
}, childrenProps));
});
} else {
return /*#__PURE__*/Object(external_react_["createElement"])(ClickableBehavior, {
href: href,
onClick: onClick,
safeWithNav: safeWithNav,
onKeyDown: onKeyDown,
onKeyUp: onKeyUp,
target: target
}, function (state, childrenProps) {
return _this2.getCorrectTag(state, _objectSpread2(_objectSpread2({}, restProps), {}, {
"data-test-id": testId,
style: getStyle(state)
}, childrenProps));
});
}
}

@@ -1108,2 +1141,8 @@ }]);

MozOsxFontSmoothing: "inherit"
},
link: {
cursor: "pointer"
},
focused: {
outline: "solid 2px ".concat(wonder_blocks_color_default.a.blue)
}

@@ -1113,6 +1152,2 @@ });

// EXTERNAL MODULE: external "@khanacademy/wonder-blocks-color"
var wonder_blocks_color_ = __webpack_require__(1);
var wonder_blocks_color_default = /*#__PURE__*/__webpack_require__.n(wonder_blocks_color_);
// CONCATENATED MODULE: ./packages/wonder-blocks-link/components/link-core.js

@@ -1346,3 +1381,4 @@ function link_core_typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { link_core_typeof = function _typeof(obj) { return typeof obj; }; } else { link_core_typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return link_core_typeof(obj); }

onClick = _this$props.onClick,
beforeNav = _this$props.beforeNav,
_this$props$beforeNav = _this$props.beforeNav,
beforeNav = _this$props$beforeNav === void 0 ? undefined : _this$props$beforeNav,
safeWithNav = _this$props.safeWithNav,

@@ -1355,30 +1391,57 @@ href = _this$props.href,

onKeyUp = _this$props.onKeyUp,
target = _this$props.target,
_this$props$target = _this$props.target,
target = _this$props$target === void 0 ? undefined : _this$props$target,
sharedProps = link_objectWithoutProperties(_this$props, ["onClick", "beforeNav", "safeWithNav", "href", "skipClientNav", "children", "tabIndex", "onKeyDown", "onKeyUp", "target"]);
var ClickableBehavior = getClickableBehavior(href, skipClientNav, this.context.router);
return /*#__PURE__*/external_react_["createElement"](ClickableBehavior, {
disabled: false,
href: href,
role: "link",
onClick: onClick,
beforeNav: beforeNav,
safeWithNav: safeWithNav,
target: target,
onKeyDown: onKeyDown,
onKeyUp: onKeyUp
}, function (state, _ref) {
var clickableTabIndex = _ref.tabIndex,
handlers = link_objectWithoutProperties(_ref, ["tabIndex"]);
return /*#__PURE__*/external_react_["createElement"](link_core_LinkCore, link_extends({}, sharedProps, state, handlers, {
skipClientNav: skipClientNav,
if (beforeNav) {
return /*#__PURE__*/external_react_["createElement"](ClickableBehavior, {
disabled: false,
href: href,
target: target // If tabIndex is provide to the component we allow
// it to override the tabIndex provide to use by
// ClickableBehavior.
,
tabIndex: tabIndex || clickableTabIndex
}), children);
});
role: "link",
onClick: onClick,
beforeNav: beforeNav,
safeWithNav: safeWithNav,
onKeyDown: onKeyDown,
onKeyUp: onKeyUp
}, function (state, _ref) {
var clickableTabIndex = _ref.tabIndex,
childrenProps = link_objectWithoutProperties(_ref, ["tabIndex"]);
return /*#__PURE__*/external_react_["createElement"](link_core_LinkCore, link_extends({}, sharedProps, state, childrenProps, {
skipClientNav: skipClientNav,
href: href,
target: target // If tabIndex is provide to the component we allow
// it to override the tabIndex provide to use by
// ClickableBehavior.
,
tabIndex: tabIndex || clickableTabIndex
}), children);
});
} else {
return /*#__PURE__*/external_react_["createElement"](ClickableBehavior, {
disabled: false,
href: href,
role: "link",
onClick: onClick,
safeWithNav: safeWithNav,
target: target,
onKeyDown: onKeyDown,
onKeyUp: onKeyUp
}, function (state, _ref2) {
var clickableTabIndex = _ref2.tabIndex,
childrenProps = link_objectWithoutProperties(_ref2, ["tabIndex"]);
return /*#__PURE__*/external_react_["createElement"](link_core_LinkCore, link_extends({}, sharedProps, state, childrenProps, {
skipClientNav: skipClientNav,
href: href,
target: target // If tabIndex is provide to the component we allow
// it to override the tabIndex provide to use by
// ClickableBehavior.
,
tabIndex: tabIndex || clickableTabIndex
}), children);
});
}
}

@@ -1385,0 +1448,0 @@ }]);

{
"name": "@khanacademy/wonder-blocks-link",
"version": "3.6.3",
"version": "3.7.0",
"design": "v1",

@@ -19,3 +19,3 @@ "publishConfig": {

"@khanacademy/wonder-blocks-color": "^1.1.15",
"@khanacademy/wonder-blocks-core": "^3.0.0"
"@khanacademy/wonder-blocks-core": "^3.0.1"
},

@@ -31,3 +31,3 @@ "peerDependencies": {

},
"gitHead": "7aa04017e8c20479e33c5c0d6b59f8bd3f6379e9"
"gitHead": "a8993049a08b602a0309155e4a1f4d969ef51c54"
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc