Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

hellosign-embedded

Package Overview
Dependencies
Maintainers
4
Versions
99
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

hellosign-embedded - npm Package Compare versions

Comparing version 2.0.0-0 to 2.0.0-1

setup.js

1

jest.config.js

@@ -21,3 +21,4 @@ const globals = require('./globals');

coverageDirectory: '.coverage',
setupFiles: ['./setup.js'],
globals,
};

2

package.json
{
"name": "hellosign-embedded",
"version": "2.0.0-0",
"version": "2.0.0-1",
"description": "Embed HelloSign signature requests and templates from within your web application.",

@@ -5,0 +5,0 @@ "main": "index.js",

import Emitter from 'tiny-emitter';
import { safeHtml } from 'common-tags';

@@ -7,2 +6,3 @@ import debug from './debug';

import settings from './settings';
import template from './template';

@@ -39,2 +39,10 @@ class HelloSign extends Emitter {

/**
* The base config object which "open" will extend.
*
* @type {?Object}
* @private
*/
_baseConfig = null;
/**
* A reference to the base HelloSign Embedded container

@@ -46,3 +54,3 @@ * element.

*/
_baseEl;
_baseEl = null;

@@ -55,11 +63,11 @@ /**

*/
_closeBtnEl;
_closeBtnEl = null;
/**
* The base config object which "open" will extend.
* The HelloSign Embedded document fragment.
*
* @type {?Object}
* @type {?DocumentFragment}
* @private
*/
_config;
_fragment = null;

@@ -72,3 +80,3 @@ /**

*/
_iFrameURL;
_iFrameURL = null;

@@ -81,3 +89,3 @@ /**

*/
_iFrameEl;
_iFrameEl = null;

@@ -90,3 +98,3 @@ /**

*/
_initTimeout;
_initTimeout = null;

@@ -99,3 +107,3 @@ /**

*/
_isOpen;
_isOpen = false;

@@ -106,3 +114,3 @@ /**

*/
_onCloseButtonClick = this._onCloseButtonClick.bind(this);
_onCloseBtnClick = this._onCloseBtnClick.bind(this);

@@ -133,3 +141,3 @@ /**

if (obj && typeof obj === 'object') {
this._config = { ...obj };
this._baseConfig = { ...obj };
} else {

@@ -386,5 +394,6 @@ throw new TypeError('Configuration must be an object');

* @param {Object} cfg
* @returns {string}
* @private
*/
_setFrameURL(url, cfg) {
_getFrameURL(url, cfg) {
const frameURL = new URL(url);

@@ -395,37 +404,52 @@ const frameParams = this._getFrameParams(frameURL, cfg);

this._iFrameURL = frameURL;
return frameURL;
}
/**
*
*
* @private
*/
_renderFragment() {
const fragment = document.createRange().createContextualFragment(template);
// Obtain element references.
this._baseEl = fragment.querySelector(`.${settings.classNames.BASE}`);
this._iFrameEl = fragment.querySelector(`.${settings.classNames.IFRAME}`);
this._closeBtnEl = fragment.querySelector(`.${settings.classNames.MODAL_CLOSE_BTN}`);
// Update iFrame URL.
this._iFrameEl.setAttribute('src', this._iFrameURL.href);
// Register event listeners.
this._closeBtnEl.addEventListener('click', this._onCloseBtnClick);
return fragment;
}
/**
* Renders HelloSign Embedded into the DOM.
*
* @param {HTMLElement} container
* @param {Object} cfg
* @private
*/
_renderMarkup(container, cfg) {
const { classNames, iframe } = settings;
_attachFragment(cfg) {
const fragment = this._renderFragment();
if (cfg.container) {
container.insertAdjacentHTML('beforeend', safeHtml`
<div class="${classNames.BASE}">
<iframe class="${classNames.IFRAME}" name="${iframe.NAME}" src="${this._iFrameURL.href}" />
</div>
`);
if (cfg.allowCancel) {
this._baseEl.classList.toggle(settings.classNames.BASE_NO_CANCEL, false);
} else {
container.insertAdjacentHTML('beforeend', safeHtml`
<div class="${classNames.BASE} ${classNames.IN_MODAL}">
<div class="${classNames.MODAL_SCREEN}"></div>
<div class="${classNames.MODAL_CONTENT}">
<iframe class="${classNames.IFRAME}" name="${iframe.NAME}" src="${this._iFrameURL.href}" />
</div>
</div>
`);
this._baseEl.classList.toggle(settings.classNames.BASE_NO_CANCEL, true);
}
this._baseEl = document.getElementsByClassName(classNames.BASE).item(0);
this._iFrameEl = document.getElementsByClassName(classNames.IFRAME).item(0);
if (cfg.container) {
this._baseEl.classList.toggle(settings.classNames.BASE_IN_CONTAINER, true);
this._baseEl.classList.toggle(settings.classNames.BASE_IN_MODAL, false);
if (!cfg.container && cfg.allowCancel) {
this._renderCloseButton();
cfg.container.appendChild(fragment);
} else {
this._baseEl.classList.toggle(settings.classNames.BASE_IN_CONTAINER, false);
this._baseEl.classList.toggle(settings.classNames.BASE_IN_MODAL, true);
document.body.appendChild(fragment);
}

@@ -435,27 +459,26 @@ }

/**
* Renders the modal close button.
* Removes the HelloSign Embedded markup from the DOM.
*
*
* @private
*/
_renderCloseButton() {
const { classNames } = settings;
this._baseEl.insertAdjacentHTML('beforeend', safeHtml`
<button class="${classNames.MODAL_CLOSE_BTN}" type="button" title="Close" disabled></div>
`);
this._closeBtnEl = this._baseEl.getElementsByClassName(classNames.MODAL_CLOSE_BTN).item(0);
this._closeBtnEl.addEventListener('click', this._onCloseButtonClick);
_detachFragment() {
this._baseEl.parentElement.removeChild(this._baseEl);
}
/**
* @typedef {Object} HelloSignMessage
* @property {string} type
* @property {Object} [payload]
*/
/**
* Posts a cross-origin window message to the HelloSign
* Embedded iFrame content window.
*
* @param {Object} data
* @param {string} data.type
* @param {HelloSignMessage} msg
* @private
*/
_sendMessage(data) {
debug.info('posting message', data);
_sendMessage(msg) {
debug.info('posting message', msg);

@@ -465,3 +488,3 @@ const targetOrigin = this._iFrameURL.href;

targetWindow.postMessage(data, targetOrigin);
targetWindow.postMessage(msg, targetOrigin);
}

@@ -495,18 +518,2 @@

/**
* Removes the HelloSign Embedded markup from the DOM.
*
*
* @private
*/
_clearMarkup() {
this._baseEl.parentElement.removeChild(this._baseEl);
this._baseEl = null;
if (this._closeBtnEl) {
this._closeBtnEl.addEventListener('click', this._onCloseButtonClick);
this._closeBtnEl = null;
}
}
/**
* @event HelloSign#error

@@ -545,6 +552,2 @@ * @type {Object}

if (this._closeBtnEl) {
this._closeBtnEl.removeAttribute('disabled');
}
this.emit(settings.events.INITIALIZE, payload);

@@ -670,3 +673,3 @@ }

*/
_onCloseButtonClick(evt) {
_onCloseBtnClick(evt) {
evt.preventDefault();

@@ -707,47 +710,61 @@

_onMessage({ data, origin }) {
debug.info('received message', data, origin);
if (/^https:\/\/app\.((dev|qa|staging)-)?hellosign\.com$/.test(origin)) {
debug.info('last message was sent from a known origin');
if (typeof data === 'object') {
const { type, payload } = data;
this._delegateMessage(data);
}
} else {
debug.warn('last message was sent from an unknown origin');
}
}
debug.info('received message', data);
switch (type) {
case settings.messages.APP_ERROR: {
this._appDidError(payload);
break;
}
case settings.messages.APP_INITIALIZE: {
this._appDidInitialize(payload);
break;
}
case settings.messages.USER_CLOSE_REQUEST: {
this._userDidCloseRequest(payload);
break;
}
case settings.messages.USER_CREATE_TEMPLATE: {
this._userDidCreateTemplate(payload);
break;
}
case settings.messages.USER_DECLINE_REQUEST: {
this._userDidDeclineRequest(payload);
break;
}
case settings.messages.USER_REASSIGN_REQUEST: {
this._userDidReassignRequest(payload);
break;
}
case settings.messages.USER_SEND_REQUEST: {
this._userDidSendRequest(payload);
break;
}
case settings.messages.USER_SIGN_REQUEST: {
this._userDidSignRequest(payload);
break;
}
default: {
// Unhandled message.
debug.warn('unhandled cross-origin window message');
}
}
/**
* Called when a message is received by the window.
* Validates the message origin and delegates to the
* appropriate method based on the message type.
*
* @param {HelloSignMessage} msg
* @private
*/
_delegateMessage({ type, payload }) {
switch (type) {
case settings.messages.APP_ERROR: {
this._appDidError(payload);
break;
}
case settings.messages.APP_INITIALIZE: {
this._appDidInitialize(payload);
break;
}
case settings.messages.USER_CLOSE_REQUEST: {
this._userDidCloseRequest(payload);
break;
}
case settings.messages.USER_CREATE_TEMPLATE: {
this._userDidCreateTemplate(payload);
break;
}
case settings.messages.USER_DECLINE_REQUEST: {
this._userDidDeclineRequest(payload);
break;
}
case settings.messages.USER_REASSIGN_REQUEST: {
this._userDidReassignRequest(payload);
break;
}
case settings.messages.USER_SEND_REQUEST: {
this._userDidSendRequest(payload);
break;
}
case settings.messages.USER_SIGN_REQUEST: {
this._userDidSignRequest(payload);
break;
}
default: {
// Unhandled message.
debug.warn('unhandled cross-origin window message');
}
}

@@ -788,2 +805,9 @@ }

const cfg = {
...defaults,
...this._baseConfig,
...opts,
};
// Close if embedded is already open.
if (this._isOpen) {

@@ -793,8 +817,5 @@ this.close();

const cfg = { ...defaults, ...this._config, ...opts };
const container = cfg.container || document.body;
this._iFrameURL = this._getFrameURL(url, cfg);
this._setFrameURL(url, cfg);
this._renderMarkup(container, cfg);
this._attachFragment(cfg);
this._isOpen = true;

@@ -827,14 +848,13 @@

this._iFrameEl = false;
this._detachFragment();
this._clearInitTimeout();
this._closeBtnEl.removeEventListener('click', this._onCloseBtnClick);
this._closeBtnEl = null;
this._baseEl = null;
this._iFrameEl = null;
this._iFrameURL = null;
this._isOpen = false;
this._clearMarkup();
this._clearInitTimeout();
if (this._closeBtnEl) {
this._closeBtnEl.removeEventListener('click', this._onCloseButtonClick);
this._closeBtnEl = null;
}
window.removeEventListener('message', this._onMessage);

@@ -841,0 +861,0 @@ }

@@ -21,7 +21,55 @@ import HelloSign from './embedded';

describe('methods', () => {
describe('accessors', () => {
describe('element()', () => {
test('returns the base element', () => {
const client = new HelloSign({ clientId: mockClientId });
client.open(mockSignURL);
expect(client.element).toBeInstanceOf(HTMLElement);
client.close();
});
});
describe('isOpen()', () => {
test('returns the open state', () => {
const client = new HelloSign({ clientId: mockClientId });
expect(client.isOpen).toEqual(false);
client.open(mockSignURL);
expect(client.isOpen).toEqual(true);
client.close();
expect(client.isOpen).toEqual(false);
});
});
});
describe.skip('methods', () => {
describe('open()', () => {
test('emits the "close" event', (done) => {
test('closes the old window if embedded is already open', (done) => {
const client = new HelloSign({
clientId: mockClientId,
});
const fn = jest.fn(() => {
expect(fn).toBeCalledTimes(1);
done();
});
client.once(HelloSign.events.CLOSE, fn);
client.open(mockSignURL);
client.open(mockSignURL);
});
test('emits the "open" event', (done) => {
const client = new HelloSign();

@@ -409,2 +457,4 @@

client.once(HelloSign.events.CLOSE, fn);
client.once(HelloSign.events.OPEN, () => {

@@ -414,4 +464,2 @@ client.close();

client.once(HelloSign.events.CLOSE, fn);
client.open(mockSignURL, {

@@ -421,4 +469,18 @@ clientId: mockClientId,

});
test('does not attempt to close if not open', (done) => {
const client = new HelloSign();
const fn = jest.fn(() => {});
client.once(HelloSign.events.CLOSE, fn);
client.close();
setTimeout(() => {
expect(fn).toBeCalledTimes(0);
done();
}, 1000);
});
});
});
});

@@ -9,7 +9,10 @@ /**

BASE: 'x-hellosign-embedded',
BASE_IN_CONTAINER: 'x-hellosign-embedded--in-container',
BASE_IN_MODAL: 'x-hellosign-embedded--in-modal',
BASE_NO_CANCEL: 'x-hellosign-embedded--no-cancel',
IFRAME: 'x-hellosign-embedded__iframe',
IN_MODAL: 'x-hellosign-embedded--in-modal',
MODAL_CLOSE: 'x-hellosign-embedded__modal-close',
MODAL_CLOSE_BTN: 'x-hellosign-embedded__modal-close-button',
MODAL_CONTENT: 'x-hellosign-embedded__modal-content',
MODAL_SCREEN: 'x-hellosign-embedded__modal-screen',
MODAL_CONTENT: 'x-hellosign-embedded__modal-content',
MODAL_CLOSE_BTN: 'x-hellosign-embedded__modal-close-button',
};

@@ -16,0 +19,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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