Skip to content

Commit

Permalink
Merge branch 'task/450-typeerror-targetownerdocumentcreaterange-is-no…
Browse files Browse the repository at this point in the history
…t-a-function' of https://github.com/capricorn86/happy-dom into task/450-typeerror-targetownerdocumentcreaterange-is-not-a-function
  • Loading branch information
capricorn86 committed Jun 20, 2022
2 parents fa82f07 + a40354f commit acdc0f1
Show file tree
Hide file tree
Showing 44 changed files with 16,753 additions and 328 deletions.
596 changes: 298 additions & 298 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions packages/happy-dom/.eslintrc.js
Expand Up @@ -34,12 +34,12 @@ const COMMON_CONFIG = {
'jsdoc/check-tag-names': WARN,
'jsdoc/check-types': WARN,
'jsdoc/implements-on-classes': WARN,
'jsdoc/match-description': WARN,
'jsdoc/match-description': OFF,
'jsdoc/newline-after-description': WARN,
'jsdoc/no-types': OFF,
'jsdoc/no-undefined-types': OFF,
'jsdoc/require-description': OFF,
'jsdoc/require-description-complete-sentence': WARN,
'jsdoc/require-description-complete-sentence': OFF,
'jsdoc/require-example': OFF,
'jsdoc/require-hyphen-before-param-description': [WARN, 'never'],
'jsdoc/require-param': WARN,
Expand Down
97 changes: 97 additions & 0 deletions packages/happy-dom/src/base64/Base64.ts
@@ -0,0 +1,97 @@
import DOMException from '../exception/DOMException';
import DOMExceptionNameEnum from '../exception/DOMExceptionNameEnum';

const BASE64_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';

/**
* Base64 encoding and decoding.
*/
export default class Base64 {
/**
* Creates a Base64-encoded ASCII string from a binary string (i.e., a string in which each character in the string is treated as a byte of binary data).
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/btoa
* @param data Binay data.
* @returns Base64-encoded string.
*/
public static btoa(data: unknown): string {
const str = (<string>data).toString();
if (/[^\u0000-\u00ff]/.test(str)) {
throw new DOMException(
"Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.",
DOMExceptionNameEnum.invalidCharacterError
);
}

let t = '';
let p = -6;
let a = 0;
let i = 0;
let v = 0;
let c;
while (i < str.length || p > -6) {
if (p < 0) {
if (i < str.length) {
c = str.charCodeAt(i++);
v += 8;
} else {
c = 0;
}
a = ((a & 255) << 8) | (c & 255);
p += 8;
}
t += BASE64_CHARS.charAt(v > 0 ? (a >> p) & 63 : 64);
p -= 6;
v -= 6;
}
return t;
}

/**
* Decodes a string of data which has been encoded using Base64 encoding.
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/atob
* @see https://infra.spec.whatwg.org/#forgiving-base64-encode.
* @see Https://html.spec.whatwg.org/multipage/webappapis.html#btoa.
* @param data Binay string.
* @returns An ASCII string containing decoded data from encodedData.
*/
public static atob(data: unknown): string {
const str = (<string>data).toString();

if (/[^\u0000-\u00ff]/.test(str)) {
throw new DOMException(
"Failed to execute 'atob' on 'Window': The string to be decoded contains characters outside of the Latin1 range.",
DOMExceptionNameEnum.invalidCharacterError
);
}

if (/[^A-Za-z\d+/=]/.test(str) || str.length % 4 == 1) {
throw new DOMException(
"Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.",
DOMExceptionNameEnum.invalidCharacterError
);
}

let t = '';
let p = -8;
let a = 0;
let c;
let d;
for (let i = 0; i < str.length; i++) {
if ((c = BASE64_CHARS.indexOf(str.charAt(i))) < 0) {
continue;
}
a = (a << 6) | (c & 63);
if ((p += 6) >= 0) {
d = (a >> p) & 255;
if (c !== 64) {
t += String.fromCharCode(d);
}
a &= 63;
p -= 8;
}
}
return t;
}
}
9 changes: 6 additions & 3 deletions packages/happy-dom/src/config/ElementTag.ts
Expand Up @@ -13,6 +13,9 @@ import HTMLLabelElement from '../nodes/html-label-element/HTMLLabelElement';
import HTMLSlotElement from '../nodes/html-slot-element/HTMLSlotElement';
import HTMLMetaElement from '../nodes/html-meta-element/HTMLMetaElement';
import HTMLBaseElement from '../nodes/html-base-element/HTMLBaseElement';
import HTMLSelectElement from '../nodes/html-select-element/HTMLSelectElement';
import HTMLOptionElement from '../nodes/html-option-element/HTMLOptionElement';
import HTMLOptGroupElement from '../nodes/html-opt-group-element/HTMLOptGroupElement';

export default {
A: HTMLElement,
Expand Down Expand Up @@ -102,8 +105,8 @@ export default {
NOSCRIPT: HTMLElement,
OBJECT: HTMLElement,
OL: HTMLElement,
OPTGROUP: HTMLElement,
OPTION: HTMLElement,
OPTGROUP: HTMLOptGroupElement,
OPTION: HTMLOptionElement,
OUTPUT: HTMLElement,
P: HTMLElement,
PARAM: HTMLElement,
Expand All @@ -119,7 +122,7 @@ export default {
S: HTMLElement,
SAMP: HTMLElement,
SECTION: HTMLElement,
SELECT: HTMLElement,
SELECT: HTMLSelectElement,
SMALL: HTMLElement,
SOURCE: HTMLElement,
SPAN: HTMLElement,
Expand Down
Expand Up @@ -32,13 +32,10 @@ export default [
'HTMLMediaElement',
'HTMLMeterElement',
'HTMLModElement',
'HTMLOptGroupElement',
'HTMLOptionElement',
'HTMLOutputElement',
'HTMLPictureElement',
'HTMLProgressElement',
'HTMLQuoteElement',
'HTMLSelectElement',
'HTMLSourceElement',
'HTMLSpanElement',
'HTMLTableCaptionElement',
Expand Down
7 changes: 7 additions & 0 deletions packages/happy-dom/src/dom-token-list/DOMTokenList.ts
Expand Up @@ -212,4 +212,11 @@ export default class DOMTokenList implements IDOMTokenList {

(<number>this.length) = list.length;
}

/**
* Returns DOMTokenList value.
*/
public toString(): string {
return this.value || '';
}
}
1 change: 1 addition & 0 deletions packages/happy-dom/src/dom-token-list/IDOMTokenList.ts
Expand Up @@ -16,4 +16,5 @@ export default interface IDOMTokenList {
entries(): IterableIterator<[number, string]>;
forEach(callback: (currentValue, currentIndex, listObj) => void, thisArg?: this): void;
keys(): IterableIterator<number>;
toString(): string;
}
3 changes: 2 additions & 1 deletion packages/happy-dom/src/exception/DOMExceptionNameEnum.ts
Expand Up @@ -5,6 +5,7 @@ enum DOMExceptionNameEnum {
hierarchyRequestError = 'HierarchyRequestError',
notSupportedError = 'NotSupportedError',
wrongDocumentError = 'WrongDocumentError',
invalidNodeTypeError = 'InvalidNodeTypeError'
invalidNodeTypeError = 'InvalidNodeTypeError',
invalidCharacterError = 'InvalidCharacterError'
}
export default DOMExceptionNameEnum;
2 changes: 2 additions & 0 deletions packages/happy-dom/src/index.ts
Expand Up @@ -101,6 +101,7 @@ import XMLParser from './xml-parser/XMLParser';
import XMLSerializer from './xml-serializer/XMLSerializer';
import CSSStyleSheet from './css/CSSStyleSheet';
import Storage from './storage/Storage';
import DOMRect from './nodes/element/DOMRect';
import { URLSearchParams } from 'url';
import Selection from './selection/Selection';

Expand Down Expand Up @@ -208,6 +209,7 @@ export {
XMLSerializer,
CSSStyleSheet,
Storage,
DOMRect,
URLSearchParams,
Selection
};
18 changes: 18 additions & 0 deletions packages/happy-dom/src/nodes/document/Document.ts
Expand Up @@ -39,6 +39,7 @@ import Location from '../../location/Location';
import Selection from '../../selection/Selection';
import IShadowRoot from '../shadow-root/IShadowRoot';
import Range from '../../range/Range';
import IHTMLBaseElement from '../html-base-element/IHTMLBaseElement';

/**
* Document.
Expand Down Expand Up @@ -283,6 +284,20 @@ export default class Document extends Node implements IDocument {
return <IHTMLCollection<IHTMLScriptElement>>this.getElementsByTagName('script');
}

/**
* Returns base URI.
*
* @override
* @returns Base URI.
*/
public get baseURI(): string {
const base = <IHTMLBaseElement>this.querySelector('base');
if (base) {
return base.href;
}
return this.defaultView.location.href;
}

/**
* Inserts a set of Node objects or DOMString objects after the last child of the ParentNode. DOMString objects are inserted as equivalent Text nodes.
*
Expand Down Expand Up @@ -648,6 +663,9 @@ export default class Document extends Node implements IDocument {
element.tagName = tagName;
element.ownerDocument = this;
element.namespaceURI = namespaceURI;
if (element instanceof Element && options && options.is) {
element._isValue = String(options.is);
}

return element;
}
Expand Down
15 changes: 15 additions & 0 deletions packages/happy-dom/src/nodes/element/DOMRect.ts
Expand Up @@ -12,4 +12,19 @@ export default class DOMRect {
public right = 0;
public bottom = 0;
public left = 0;

/**
* Constructor.
*
* @param [x] X position.
* @param [y] Y position.
* @param [width] Width.
* @param [height] Height.
*/
constructor(x?, y?, width?, height?) {
this.x = x || 0;
this.y = y || 0;
this.width = width || 0;
this.height = height || 0;
}
}
1 change: 1 addition & 0 deletions packages/happy-dom/src/nodes/element/Element.ts
Expand Up @@ -48,6 +48,7 @@ export default class Element extends Node implements IElement {
public _attributes: { [k: string]: Attr } = {};

private _classList: DOMTokenList = null;
public _isValue?: string;

/**
* Returns class list.
Expand Down
@@ -1,6 +1,6 @@
import File from '../../file/File';
import HTMLElement from '../html-element/HTMLElement';
import ValidityState from './ValidityState';
import ValidityState from '../validity-state/ValidityState';
import DOMException from '../../exception/DOMException';
import DOMExceptionNameEnum from '../../exception/DOMExceptionNameEnum';
import Event from '../../event/Event';
Expand Down
Expand Up @@ -2,7 +2,7 @@ import File from '../../file/File';
import IHTMLElement from '../html-element/IHTMLElement';
import IHTMLFormElement from '../html-form-element/IHTMLFormElement';
import HTMLInputElementSelectionModeEnum from './HTMLInputElementSelectionModeEnum';
import ValidityState from './ValidityState';
import ValidityState from '../validity-state/ValidityState';

/**
* HTML Input Element.
Expand Down
@@ -0,0 +1,54 @@
import HTMLElement from '../html-element/HTMLElement';
import IHTMLOptGroupElement from './IHTMLOptGroupElement';

/**
* HTML Opt Group Element.
*
* Reference:
* https://developer.mozilla.org/en-US/docs/Web/API/HTMLOptGroupElement.
*/
export default class HTMLOptGroupElement extends HTMLElement implements IHTMLOptGroupElement {
/**
* Returns label.
*
* @returns Label.
*/
public get label(): string {
return this.getAttributeNS(null, 'label') || '';
}

/**
* Sets label.
*
* @param label Label.
*/
public set label(label: string) {
if (!label) {
this.removeAttributeNS(null, 'label');
} else {
this.setAttributeNS(null, 'label', label);
}
}

/**
* Returns disabled.
*
* @returns Disabled.
*/
public get disabled(): boolean {
return this.getAttributeNS(null, 'disabled') !== null;
}

/**
* Sets disabled.
*
* @param disabled Disabled.
*/
public set disabled(disabled: boolean) {
if (!disabled) {
this.removeAttributeNS(null, 'disabled');
} else {
this.setAttributeNS(null, 'disabled', '');
}
}
}
@@ -0,0 +1,12 @@
import IHTMLElement from '../html-element/IHTMLElement';

/**
* HTML Opt Group Element.
*
* Reference:
* https://developer.mozilla.org/en-US/docs/Web/API/HTMLOptGroupElement.
*/
export default interface IHTMLOptGroupElement extends IHTMLElement {
disabled: boolean;
label: string;
}

0 comments on commit acdc0f1

Please sign in to comment.