'use strict';

const response = require('../helpers/context').response;
const request = require('supertest');
const statuses = require('statuses');
const assert = require('assert');
const Koa = require('../..');

describe('res.status=', () => {
  describe('when a status code', () => {
    describe('and valid', () => {
      it('should set the status', () => {
        const res = response();
        res.status = 403;
        res.status.should.equal(403);
      });

      it('should not throw', () => {
        assert.doesNotThrow(() => {
          response().status = 403;
        });
      });
    });

    describe('and invalid', () => {
      it('should throw', () => {
        assert.throws(() => {
          response().status = 999;
        }, 'invalid status code: 999');
      });
    });

    describe('and custom status', () => {
      before(() => statuses['700'] = 'custom status');

      it('should set the status', () => {
        const res = response();
        res.status = 700;
        res.status.should.equal(700);
      });

      it('should not throw', () => {
        assert.doesNotThrow(() => response().status = 700);
      });
    });
  });

  describe('when a status string', () => {
    it('should throw', () => {
      assert.throws(() => response().status = 'forbidden', 'status code must be a number');
    });
  });

  function strip(status){
    it('should strip content related header fields', done => {
      const app = new Koa();

      app.use(ctx => {
        ctx.body = { foo: 'bar' };
        ctx.set('Content-Type', 'application/json; charset=utf-8');
        ctx.set('Content-Length', '15');
        ctx.set('Transfer-Encoding', 'chunked');
        ctx.status = status;
        assert(null == ctx.response.header['content-type']);
        assert(null == ctx.response.header['content-length']);
        assert(null == ctx.response.header['transfer-encoding']);
      });

      request(app.listen())
        .get('/')
        .expect(status)
        .end((err, res) => {
          res.should.not.have.header('content-type');
          res.should.not.have.header('content-length');
          res.should.not.have.header('content-encoding');
          res.text.should.have.length(0);
          done(err);
        });
    });

    it('should strip content releated header fields after status set', done => {
      const app = new Koa();

      app.use(ctx => {
        ctx.status = status;
        ctx.body = { foo: 'bar' };
        ctx.set('Content-Type', 'application/json; charset=utf-8');
        ctx.set('Content-Length', '15');
        ctx.set('Transfer-Encoding', 'chunked');
      });

      request(app.listen())
        .get('/')
        .expect(status)
        .end((err, res) => {
          res.should.not.have.header('content-type');
          res.should.not.have.header('content-length');
          res.should.not.have.header('content-encoding');
          res.text.should.have.length(0);
          done(err);
        });
    });
  }

  describe('when 204', () => strip(204));

  describe('when 205', () => strip(205));

  describe('when 304', () => strip(304));
});


const ctx = this.createContext(req, res);

keep keep keep replace replace keep keep keep keep keep

const onerror = err => ctx.onerror(err);

'use strict';

const request = require('../helpers/context').request;
const assert = require('assert');

describe('req.inspect()', () => {
  describe('with no request.req present', () => {
    it('should return null', () => {
      const req = request();
      req.method = 'GET';
      delete req.req;
      assert(null == req.inspect());
    });
  });

  it('should return a json representation', () => {
    const req = request();
    req.method = 'GET';
    req.url = 'example.com';
    req.header.host = 'example.com';

    req.inspect().should.eql({
      method: 'GET',
      url: 'example.com',
      header: {
        host: 'example.com'
      }
    });
  });
});


keep keep keep keep keep replace keep keep keep

'use strict';

/**
 * Module dependencies.
 */

const isGeneratorFunction = require('is-generator-function');
const debug = require('debug')('koa:application');
const onFinished = require('on-finished');
const response = require('./response');
const compose = require('koa-compose');
const isJSON = require('koa-is-json');
const context = require('./context');
const request = require('./request');
const statuses = require('statuses');
const Cookies = require('cookies');
const accepts = require('accepts');
const Emitter = require('events');
const assert = require('assert');
const Stream = require('stream');
const http = require('http');
const only = require('only');
const convert = require('koa-convert');
const deprecate = require('depd')('koa');

/**
 * Expose `Application` class.
 * Inherits from `Emitter.prototype`.
 */

module.exports = class Application extends Emitter {

  /**
   * Initialize a new `Application`.
   *
   * @api public
   */

  constructor() {
    super();

    this.proxy = false;
    this.middleware = [];
    this.subdomainOffset = 2;
    this.env = process.env.NODE_ENV || 'development';
    this.context = Object.create(context);
    this.request = Object.create(request);
    this.response = Object.create(response);
  }

  /**
   * Shorthand for:
   *
   *    http.createServer(app.callback()).listen(...)
   *
   * @param {Mixed} ...
   * @return {Server}
   * @api public
   */

  listen() {
    debug('listen');
    const server = http.createServer(this.callback());
    return server.listen.apply(server, arguments);
  }

  /**
   * Return JSON representation.
   * We only bother showing settings.
   *
   * @return {Object}
   * @api public
   */

  toJSON() {
    return only(this, [
      'subdomainOffset',
      'proxy',
      'env'
    ]);
  }

  /**
   * Inspect implementation.
   *
   * @return {Object}
   * @api public
   */

  inspect() {
    return this.toJSON();
  }

  /**
   * Use the given middleware `fn`.
   *
   * Old-style middleware will be converted.
   *
   * @param {Function} fn
   * @return {Application} self
   * @api public
   */

  use(fn) {
    if (typeof fn !== 'function') throw new TypeError('middleware must be a function!');
    if (isGeneratorFunction(fn)) {
      deprecate('Support for generators will been removed in v3. ' +
                'See the documentation for examples of how to convert old middleware ' +
                'https://github.com/koajs/koa/tree/v2.x#old-signature-middleware-v1x---deprecated');
      fn = convert(fn);
    }
    debug('use %s', fn._name || fn.name || '-');
    this.middleware.push(fn);
    return this;
  }

  /**
   * Return a request handler callback
   * for node's native http server.
   *
   * @return {Function}
   * @api public
   */

  callback() {
    const fn = compose(this.middleware);

    if (!this.listeners('error').length) this.on('error', this.onerror);

    return (req, res) => {
      res.statusCode = 404;
      const ctx = this.createContext(req, res);
      onFinished(res, ctx.onerror);
      fn(ctx).then(() => respond(ctx)).catch(ctx.onerror);
    };
  }

  /**
   * Initialize a new context.
   *
   * @api private
   */

  createContext(req, res) {
    const context = Object.create(this.context);
    const request = context.request = Object.create(this.request);
    const response = context.response = Object.create(this.response);
    context.app = request.app = response.app = this;
    context.req = request.req = response.req = req;
    context.res = request.res = response.res = res;
    request.ctx = response.ctx = context;
    request.response = response;
    response.request = request;
    context.onerror = context.onerror.bind(context);
    context.originalUrl = request.originalUrl = req.url;
    context.cookies = new Cookies(req, res, {
      keys: this.keys,
      secure: request.secure
    });
    request.ip = request.ips[0] || req.socket.remoteAddress || '';
    context.accept = request.accept = accepts(req);
    context.state = {};
    return context;
  }

  /**
   * Default error handler.
   *
   * @param {Error} err
   * @api private
   */

  onerror(err) {
    assert(err instanceof Error, `non-error thrown: ${err}`);

    if (404 == err.status || err.expose) return;
    if (this.silent) return;

    const msg = err.stack || err.toString();
    console.error();
    console.error(msg.replace(/^/gm, '  '));
    console.error();
  }

};

/**
 * Response helper.
 */

function respond(ctx) {
  // allow bypassing koa
  if (false === ctx.respond) return;

  const res = ctx.res;
  if (!ctx.writable) return;

  let body = ctx.body;
  const code = ctx.status;

  // ignore body
  if (statuses.empty[code]) {
    // strip headers
    ctx.body = null;
    return res.end();
  }

  if ('HEAD' == ctx.method) {
    if (!res.headersSent && isJSON(body)) {
      ctx.length = Buffer.byteLength(JSON.stringify(body));
    }
    return res.end();
  }

  // status body
  if (null == body) {
    body = ctx.message || String(code);
    if (!res.headersSent) {
      ctx.type = 'text';
      ctx.length = Buffer.byteLength(body);
    }
    return res.end(body);
  }

  // responses
  if (Buffer.isBuffer(body)) return res.end(body);
  if ('string' == typeof body) return res.end(body);
  if (body instanceof Stream) return body.pipe(res);

  // body: json
  body = JSON.stringify(body);
  if (!res.headersSent) {
    ctx.length = Buffer.byteLength(body);
  }
  res.end(body);
}


'use strict';

const request = require('supertest');
const assert = require('assert');
const Koa = require('../..');

describe('ctx.state', () => {
  it('should provide a ctx.state namespace', done => {
    const app = new Koa();

    app.use(ctx => {
      assert.deepEqual(ctx.state, {});
    });

    const server = app.listen();

    request(server)
      .get('/')
      .expect(404)
      .end(done);
  });
});


'use strict';

const request = require('../helpers/context').request;
const assert = require('assert');

describe('req.hostname', () => {
  it('should return hostname void of port', () => {
    const req = request();
    req.header.host = 'foo.com:3000';
    req.hostname.should.equal('foo.com');
  });

  describe('with no host present', () => {
    it('should return ""', () => {
      const req = request();
      assert.equal(req.hostname, '');
    });
  });

  describe('when X-Forwarded-Host is present', () => {
    describe('and proxy is not trusted', () => {
      it('should be ignored', () => {
        const req = request();
        req.header['x-forwarded-host'] = 'bar.com';
        req.header.host = 'foo.com';
        req.hostname.should.equal('foo.com');
      });
    });

    describe('and proxy is trusted', () => {
      it('should be used', () => {
        const req = request();
        req.app.proxy = true;
        req.header['x-forwarded-host'] = 'bar.com, baz.com';
        req.header.host = 'foo.com';
        req.hostname.should.equal('bar.com');
      });
    });
  });
});


'use strict';

const response = require('../helpers/context').response;

describe('res.etag=', () => {
  it('should not modify an etag with quotes', () => {
    const res = response();
    res.etag = '"asdf"';
    res.header.etag.should.equal('"asdf"');
  });

  it('should not modify a weak etag', () => {
    const res = response();
    res.etag = 'W/"asdf"';
    res.header.etag.should.equal('W/"asdf"');
  });

  it('should add quotes around an etag if necessary', () => {
    const res = response();
    res.etag = 'asdf';
    res.header.etag.should.equal('"asdf"');
  });
});

describe('res.etag', () => {
  it('should return etag', () => {
    const res = response();
    res.etag = '"asdf"';
    res.etag.should.equal('"asdf"');
  });
});


if (null != original && original != val) this.remove('Content-Length');

keep keep keep keep keep replace keep keep keep keep

ensureErrorHandler(val, err => this.ctx.onerror(err));


node_modules
test.js
coverage
npm-debug.log


'use strict';

const request = require('../helpers/context').request;

describe('req.header', () => {
  it('should return the request header object', () => {
    const req = request();
    req.header.should.equal(req.req.headers);
  });
});


const { render, hydrate, unmountComponentAtNode } = require('preact/compat');

const { render, hydrate } = require('preact/compat');

exports.createRoot = function(container) {
	return {
		render(children) {
			return render(children, container);
		}
	};
};

exports.hydrateRoot = function(container, children) {
	return hydrate(children, container);
};


import 'mocha';
import { expect } from 'chai';
import {
	createElement,
	Component,
	toChildArray,
	FunctionalComponent,
	ComponentConstructor,
	ComponentFactory,
	VNode,
	ComponentChildren,
	cloneElement
} from '../../';

function getDisplayType(vnode: VNode | string | number) {
	if (typeof vnode === 'string' || typeof vnode == 'number') {
		return vnode.toString();
	} else if (typeof vnode.type == 'string') {
		return vnode.type;
	} else {
		return vnode.type.displayName;
	}
}

class SimpleComponent extends Component<{}, {}> {
	render() {
		return
{this.props.children}
;
	}
}

const SimpleFunctionalComponent = () =>
;

const a: ComponentFactory = SimpleComponent;
const b: ComponentFactory = SimpleFunctionalComponent;

describe('VNode TS types', () => {
	it('is returned by h', () => {
		const actual =
;
		expect(actual).to.include.all.keys('type', 'props', 'key');
	});

	it('has a nodeName of string when html element', () => {
		const div =
Hi!
;
		expect(div.type).to.equal('div');
	});

	it('has a nodeName equal to the construction function when SFC', () => {
		const sfc = <SimpleFunctionalComponent />;
		expect(sfc.type).to.be.instanceOf(Function);
		const constructor = sfc.type as FunctionalComponent<any>;
		expect(constructor.name).to.eq('SimpleFunctionalComponent');
	});

	it('has a nodeName equal to the constructor of a component', () => {
		const sfc = <SimpleComponent />;
		expect(sfc.type).to.be.instanceOf(Function);
		const constructor = sfc.type as ComponentConstructor<any>;
		expect(constructor.name).to.eq('SimpleComponent');
	});

	it('has children which is an array of string or other vnodes', () => {
		const comp = (
			<SimpleComponent>
				<SimpleComponent>child1</SimpleComponent>
				child2
			</SimpleComponent>
		);

		expect(comp.props.children).to.be.instanceOf(Array);
		expect(comp.props.children[1]).to.be.a('string');
	});

	it('children type should work with toChildArray', () => {
		const comp: VNode = <SimpleComponent>child1 {1}</SimpleComponent>;

		const children = toChildArray(comp.props.children);
		expect(children).to.have.lengthOf(2);
	});

	it('toChildArray should filter out some types', () => {
		const compChild = <SimpleComponent />;
		const comp: VNode = (
			<SimpleComponent>
				a{null}
				{true}
				{false}
				{2}
				{undefined}
				{['b', 'c']}
				{compChild}
			</SimpleComponent>
		);

		const children = toChildArray(comp.props.children);
		expect(children).to.deep.equal(['a', 2, 'b', 'c', compChild]);
	});

	it('functions like getDisplayType should work', () => {
		function TestComp(props: { children?: ComponentChildren }) {
			return
{props.children}
;
		}
		TestComp.displayName = 'TestComp';

		const compChild = <TestComp />;
		const comp: VNode = (
			<SimpleComponent>
				a{null}
				{true}
				{false}
				{2}
				{undefined}
				{['b', 'c']}
				{compChild}
			</SimpleComponent>
		);

		const types = toChildArray(comp.props.children).map(getDisplayType);
		expect(types).to.deep.equal(['a', '2', 'b', 'c', 'TestComp']);
	});

	it('component should work with cloneElement', () => {
		const comp: VNode = (
			<SimpleComponent>

child 1

			</SimpleComponent>
		);
		const clone: VNode = cloneElement(comp);

		expect(comp.type).to.equal(clone.type);
		expect(comp.props).not.to.equal(clone.props);
		expect(comp.props).to.deep.equal(clone.props);
	});

	it('component should work with cloneElement using generics', () => {
		const comp: VNode<string> = <SimpleComponent></SimpleComponent>;
		const clone: VNode<string> = cloneElement<string>(comp);

		expect(comp.type).to.equal(clone.type);
		expect(comp.props).not.to.equal(clone.props);
		expect(comp.props).to.deep.equal(clone.props);
	});
});

class ComponentWithFunctionChild extends Component<{
	children: (num: number) => string;
}> {
	render() {
		return null;
	}
}

<ComponentWithFunctionChild>
	{num => num.toFixed(2)}
</ComponentWithFunctionChild>;

class ComponentWithStringChild extends Component<{ children: string }> {
	render() {
		return null;
	}
}

<ComponentWithStringChild>child</ComponentWithStringChild>;

class ComponentWithNumberChild extends Component<{ children: number }> {
	render() {
		return null;
	}
}

<ComponentWithNumberChild>{1}</ComponentWithNumberChild>;

class ComponentWithBooleanChild extends Component<{ children: boolean }> {
	render() {
		return null;
	}
}

<ComponentWithBooleanChild>{false}</ComponentWithBooleanChild>;

class ComponentWithNullChild extends Component<{ children: null }> {
	render() {
		return null;
	}
}

<ComponentWithNullChild>{null}</ComponentWithNullChild>;

class ComponentWithNumberChildren extends Component<{ children: number[] }> {
	render() {
		return null;
	}
}

<ComponentWithNumberChildren>
	{1}
	{2}
</ComponentWithNumberChildren>;


export as namespace preact;

import { JSXInternal } from './jsx';

export import JSX = JSXInternal;

//
// Preact Virtual DOM
// -----------------------------------

export interface VNode
 {
	type: ComponentType
 | string;
	props: P & { children: ComponentChildren };
	key: Key;
	/**
	 * ref is not guaranteed by React.ReactElement, for compatibility reasons
	 * with popular react libs we define it as optional too
	 */
	ref?: Ref<any> | null;
	/**
	 * The time this `vnode` started rendering. Will only be set when
	 * the devtools are attached.
	 * Default value: `0`
	 */
	startTime?: number;
	/**
	 * The time that the rendering of this `vnode` was completed. Will only be
	 * set when the devtools are attached.
	 * Default value: `-1`
	 */
	endTime?: number;
}

//
// Preact Component interface
// -----------------------------------

export type Key = string | number | any;

export type RefObject<T> = { current: T | null };
export type RefCallback<T> = (instance: T | null) => void;
export type Ref<T> = RefObject<T> | RefCallback<T>;

export type ComponentChild =
	| VNode<any>
	| object
	| string
	| number
	| bigint
	| boolean
	| null
	| undefined;
export type ComponentChildren = ComponentChild[] | ComponentChild;

export interface Attributes {
	key?: Key;
	jsx?: boolean;
}

export interface ClassAttributes<T> extends Attributes {
	ref?: Ref<T>;
}

export interface PreactDOMAttributes {
	children?: ComponentChildren;
	dangerouslySetInnerHTML?: {
		__html: string;
	};
}

export interface ErrorInfo {
	componentStack?: string;
}

export type RenderableProps
 = P &
	Readonly<Attributes & { children?: ComponentChildren; ref?: Ref<RefType> }>;

export type ComponentType
 = ComponentClass
 | FunctionComponent
;
export type ComponentFactory
 = ComponentType
;

export type ComponentProps<
	C extends ComponentType<any> | keyof JSXInternal.IntrinsicElements
> = C extends ComponentType<infer P>
	? P
	: C extends keyof JSXInternal.IntrinsicElements
	? JSXInternal.IntrinsicElements[C]
	: never;

export interface FunctionComponent
 {
	(props: RenderableProps
, context?: any): VNode<any> | null;
	displayName?: string;
	defaultProps?: Partial
;
}
export interface FunctionalComponent
 extends FunctionComponent
 {}

export interface ComponentClass
 {
	new (props: P, context?: any): Component
;
	displayName?: string;
	defaultProps?: Partial
;
	contextType?: Context<any>;
	getDerivedStateFromProps?(
		props: Readonly
,
		state: Readonly<S>
	): Partial<S> | null;
	getDerivedStateFromError?(error: any): Partial<S> | null;
}
export interface ComponentConstructor

	extends ComponentClass
 {}

// Type alias for a component instance considered generally, whether stateless or stateful.
export type AnyComponent
 =
	| FunctionComponent

	| Component
;

export interface Component
 {
	componentWillMount?(): void;
	componentDidMount?(): void;
	componentWillUnmount?(): void;
	getChildContext?(): object;
	componentWillReceiveProps?(nextProps: Readonly
, nextContext: any): void;
	shouldComponentUpdate?(
		nextProps: Readonly
,
		nextState: Readonly<S>,
		nextContext: any
	): boolean;
	componentWillUpdate?(
		nextProps: Readonly
,
		nextState: Readonly<S>,
		nextContext: any
	): void;
	getSnapshotBeforeUpdate?(oldProps: Readonly
, oldState: Readonly<S>): any;
	componentDidUpdate?(
		previousProps: Readonly
,
		previousState: Readonly<S>,
		snapshot: any
	): void;
	componentDidCatch?(error: any, errorInfo: ErrorInfo): void;
}

export abstract class Component
 {
	constructor(props?: P, context?: any);

	static displayName?: string;
	static defaultProps?: any;
	static contextType?: Context<any>;

	// Static members cannot reference class type parameters. This is not
	// supported in TypeScript. Reusing the same type arguments from `Component`
	// will lead to an impossible state where one cannot satisfy the type
	// constraint under no circumstances, see #1356.In general type arguments
	// seem to be a bit buggy and not supported well at the time of this
	// writing with TS 3.3.3333.
	static getDerivedStateFromProps?(
		props: Readonly<object>,
		state: Readonly<object>
	): object | null;
	static getDerivedStateFromError?(error: any): object | null;

	state: Readonly<S>;
	props: RenderableProps
;
	context: any;
	base?: Element | Text;

	// From https://github.com/DefinitelyTyped/DefinitelyTyped/blob/e836acc75a78cf0655b5dfdbe81d69fdd4d8a252/types/react/index.d.ts#L402
	// // We MUST keep setState() as a unified signature because it allows proper checking of the method return type.
	// // See: https://github.com/DefinitelyTyped/DefinitelyTyped/issues/18365#issuecomment-351013257
	setState<K extends keyof S>(
		state:
			| ((
					prevState: Readonly<S>,
					props: Readonly

			  ) => Pick<S, K> | Partial<S> | null)
			| (Pick<S, K> | Partial<S> | null),
		callback?: () => void
	): void;

	forceUpdate(callback?: () => void): void;

	abstract render(
		props?: RenderableProps
,
		state?: Readonly<S>,
		context?: any
	): ComponentChild;
}

//
// Preact createElement
// -----------------------------------

export function createElement(
	type: string,
	props:
		| (JSXInternal.HTMLAttributes &
				JSXInternal.SVGAttributes &
				Record<string, any>)
		| null,
	...children: ComponentChildren[]
): VNode<any>;
export function createElement
(
	type: ComponentType
,
	props: (Attributes & P) | null,
	...children: ComponentChildren[]
): VNode<any>;
export namespace createElement {
	export import JSX = JSXInternal;
}

export function h(
	type: string,
	props:
		| (JSXInternal.HTMLAttributes &
				JSXInternal.SVGAttributes &
				Record<string, any>)
		| null,
	...children: ComponentChildren[]
): VNode<any>;
export function h
(
	type: ComponentType
,
	props: (Attributes & P) | null,
	...children: ComponentChildren[]
): VNode<any>;
export namespace h {
	export import JSX = JSXInternal;
}

//
// Preact render
// -----------------------------------

export function render(
	vnode: ComponentChild,
	parent: Element | Document | ShadowRoot | DocumentFragment,
	replaceNode?: Element | Text
): void;
export function hydrate(
	vnode: ComponentChild,
	parent: Element | Document | ShadowRoot | DocumentFragment
): void;
export function cloneElement(
	vnode: VNode<any>,
	props?: any,
	...children: ComponentChildren[]
): VNode<any>;
export function cloneElement
(
	vnode: VNode
,
	props?: any,
	...children: ComponentChildren[]
): VNode
;

//
// Preact Built-in Components
// -----------------------------------

// TODO: Revisit what the public type of this is...
export const Fragment: FunctionComponent<{}>;

//
// Preact options
// -----------------------------------

/**
 * Global options for preact
 */
export interface Options {
	/** Attach a hook that is invoked whenever a VNode is created. */
	vnode?(vnode: VNode): void;
	/** Attach a hook that is invoked immediately before a vnode is unmounted. */
	unmount?(vnode: VNode): void;
	/** Attach a hook that is invoked after a vnode has rendered. */
	diffed?(vnode: VNode): void;
	event?(e: Event): any;
	requestAnimationFrame?(callback: () => void): void;
	debounceRendering?(cb: () => void): void;
	useDebugValue?(value: string | number): void;
	_addHookName?(name: string | number): void;
	__suspenseDidResolve?(vnode: VNode, cb: () => void): void;
	// __canSuspenseResolve?(vnode: VNode, cb: () => void): void;
}

export const options: Options;

//
// Preact helpers
// -----------------------------------
export function createRef<T = any>(): RefObject<T>;
export function toChildArray(
	children: ComponentChildren
): Array<VNode | string | number>;
export function isValidElement(vnode: any): vnode is VNode;

//
// Context
// -----------------------------------
export interface Consumer<T>
	extends FunctionComponent<{
		children: (value: T) => ComponentChildren;
	}> {}
export interface PreactConsumer<T> extends Consumer<T> {}

export interface Provider<T>
	extends FunctionComponent<{
		value: T;
		children: ComponentChildren;
	}> {}
export interface PreactProvider<T> extends Provider<T> {}
export type ContextType<C extends Context<any>> = C extends Context<infer T>
	? T
	: never;

export interface Context<T> {
	Consumer: Consumer<T>;
	Provider: Provider<T>;
	displayName?: string;
}
export interface PreactContext<T> extends Context<T> {}

export function createContext<T>(defaultValue: T): Context<T>;


<!DOCTYPE html>

		<meta charset="UTF-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
		<title>Text Updates</title>


exports.createRoot = function(container) {

import { render, hydrate } from 'preact/compat'

export function createRoot(container) {
	return {
		render(children) {
			return render(children, container)
		}
	}
}

export function hydrateRoot(container, children) {
	return hydrate(children, container);
}


import React, {
	createElement,
	render,
	createPortal,
	useState,
	Component,
	useEffect
} from 'preact/compat';
import { setupScratch, teardown } from '../../../test/_util/helpers';
import { setupRerender, act } from 'preact/test-utils';

/* eslint-disable react/jsx-boolean-value, react/display-name, prefer-arrow-callback */

describe('Portal', () => {
	/** @type {HTMLDivElement} */
	let scratch;
	/** @type {HTMLDivElement} */
	let scratch2;

	let rerender;

	beforeEach(() => {
		scratch = setupScratch();
		scratch2 = setupScratch('scratch-2');
		rerender = setupRerender();
	});

	afterEach(() => {
		teardown(scratch);
		teardown(scratch2);
	});

	it('should render into a different root node', () => {
		let root = document.createElement('div');
		document.body.appendChild(root);

		function Foo(props) {
			return
{createPortal(props.children, root)}
;
		}
		render(<Foo>foobar</Foo>, scratch);

		expect(root.innerHTML).to.equal('foobar');

		root.parentNode.removeChild(root);
	});

	it('should insert the portal', () => {
		let setFalse;
		function Foo(props) {
			const [mounted, setMounted] = useState(true);
			setFalse = () => setMounted(() => false);
			return (

Hello

					{mounted && createPortal(props.children, scratch)}

			);
		}
		render(<Foo>foobar</Foo>, scratch);
		expect(scratch.innerHTML).to.equal('foobar

Hello

');

		setFalse();
		rerender();
		expect(scratch.innerHTML).to.equal('

Hello

');
	});

	it('should toggle the portal', () => {
		let toggle;

		function Foo(props) {
			const [mounted, setMounted] = useState(true);
			toggle = () => setMounted(s => !s);
			return (

Hello

					{mounted && createPortal(props.children, scratch)}

			);
		}

		render(
			<Foo>

foobar

			</Foo>,
			scratch
		);
		expect(scratch.innerHTML).to.equal(
			'
foobar

Hello

'
		);

		toggle();
		rerender();
		expect(scratch.innerHTML).to.equal('

Hello

');

		toggle();
		rerender();
		expect(scratch.innerHTML).to.equal(
			'

Hello

foobar
'
		);
	});

	it('should notice prop changes on the portal', () => {
		let set;

		function Foo(props) {
			const [additionalProps, setProps] = useState({
				style: { backgroundColor: 'red' }
			});
			set = c => setProps(c);
			return (

Hello

					{createPortal(
Foo
, scratch)}

			);
		}

		render(<Foo />, scratch);
		expect(scratch.firstChild.style.backgroundColor).to.equal('red');

		set({});
		rerender();
		expect(scratch.firstChild.style.backgroundColor).to.equal('');
	});

	it('should not unmount the portal component', () => {
		let spy = sinon.spy();
		let set;
		class Child extends Component {
			componentWillUnmount() {
				spy();
			}

			render(props) {
				return props.children;
			}
		}

		function Foo(props) {
			const [additionalProps, setProps] = useState({
				style: { background: 'red' }
			});
			set = c => setProps(c);
			return (

Hello

					{createPortal(<Child {...additionalProps}>Foo</Child>, scratch)}

			);
		}

		render(<Foo />, scratch);
		expect(spy).not.to.be.called;

		set({});
		rerender();
		expect(spy).not.to.be.called;
	});

	it('should not render <undefined> for Portal nodes', () => {
		let root = document.createElement('div');
		let dialog = document.createElement('div');
		dialog.id = 'container';

		scratch.appendChild(root);
		scratch.appendChild(dialog);

		function Dialog() {
			return
Dialog content
;
		}

		function App() {
			return
{createPortal(<Dialog />, dialog)}
;
		}

		render(<App />, root);
		expect(scratch.firstChild.firstChild.childNodes.length).to.equal(0);
	});

	it('should unmount Portal', () => {
		let root = document.createElement('div');
		let dialog = document.createElement('div');
		dialog.id = 'container';

		scratch.appendChild(root);
		scratch.appendChild(dialog);

		function Dialog() {
			return
Dialog content
;
		}

		function App() {
			return
{createPortal(<Dialog />, dialog)}
;
		}

		render(<App />, root);
		expect(dialog.childNodes.length).to.equal(1);
		render(null, root);
		expect(dialog.childNodes.length).to.equal(0);
	});

	it('should leave a working root after the portal', () => {
		let toggle, toggle2;

		function Foo(props) {
			const [mounted, setMounted] = useState(false);
			const [mounted2, setMounted2] = useState(true);
			toggle = () => setMounted(s => !s);
			toggle2 = () => setMounted2(s => !s);
			return (

					{mounted && createPortal(props.children, scratch)}
					{mounted2 &&
Hello
}

			);
		}

		render(
			<Foo>

foobar

			</Foo>,
			scratch
		);
		expect(scratch.innerHTML).to.equal('

Hello

');

		toggle();
		rerender();
		expect(scratch.innerHTML).to.equal(
			'

Hello

foobar
'
		);

		toggle2();
		rerender();
		expect(scratch.innerHTML).to.equal('

foobar
');

		toggle2();
		rerender();
		expect(scratch.innerHTML).to.equal(
			'

Hello

foobar
'
		);

		toggle();
		rerender();
		expect(scratch.innerHTML).to.equal('

Hello

');

		toggle2();
		rerender();
		expect(scratch.innerHTML).to.equal('

');
	});

	it('should work with stacking portals', () => {
		let toggle, toggle2;

		function Foo(props) {
			const [mounted, setMounted] = useState(false);
			const [mounted2, setMounted2] = useState(false);
			toggle = () => setMounted(s => !s);
			toggle2 = () => setMounted2(s => !s);
			return (

Hello

					{mounted && createPortal(props.children, scratch)}
					{mounted2 && createPortal(props.children2, scratch)}

			);
		}

		render(
			<Foo children2={
foobar2
}>

foobar

			</Foo>,
			scratch
		);
		expect(scratch.innerHTML).to.equal('

Hello

');

		toggle();
		rerender();
		expect(scratch.innerHTML).to.equal(
			'

Hello

foobar
'
		);

		toggle2();
		rerender();
		expect(scratch.innerHTML).to.equal(
			'

Hello

foobar

foobar2
'
		);

		toggle2();
		rerender();
		expect(scratch.innerHTML).to.equal(
			'

Hello

foobar
'
		);

		toggle();
		rerender();
		expect(scratch.innerHTML).to.equal('

Hello

');
	});

	it('should work with changing the container', () => {
		let set, ref;

		function Foo(props) {
			const [container, setContainer] = useState(scratch);
			set = setContainer;

			return (

 {
						ref = r;
					}}
				>

Hello

					{createPortal(props.children, container)}

			);
		}

		render(
			<Foo>

foobar

			</Foo>,
			scratch
		);
		expect(scratch.innerHTML).to.equal(
			'
foobar

Hello

'
		);

		set(() => ref);
		rerender();
		expect(scratch.innerHTML).to.equal(
			'

Hello

foobar

'
		);
	});

	it('should work with replacing placeholder portals', () => {
		let toggle, toggle2;

		function Foo(props) {
			const [mounted, setMounted] = useState(false);
			const [mounted2, setMounted2] = useState(false);
			toggle = () => setMounted(s => !s);
			toggle2 = () => setMounted2(s => !s);
			return (

Hello

					{createPortal(mounted && props.children, scratch)}
					{createPortal(mounted2 && props.children, scratch)}

			);
		}

		render(
			<Foo>

foobar

			</Foo>,
			scratch
		);
		expect(scratch.innerHTML).to.equal('

Hello

');

		toggle();
		rerender();
		expect(scratch.innerHTML).to.equal(
			'

Hello

foobar
'
		);

		toggle();
		rerender();
		expect(scratch.innerHTML).to.equal('

Hello

');

		toggle2();
		rerender();
		expect(scratch.innerHTML).to.equal(
			'

Hello

foobar
'
		);

		toggle2();
		rerender();
		expect(scratch.innerHTML).to.equal('

Hello

');
	});

	it('should work with removing an element from stacked container to new one', () => {
		let toggle, root2;

		function Foo(props) {
			const [root, setRoot] = useState(scratch);
			toggle = () => setRoot(() => root2);
			return (

 {
						root2 = r;
					}}
				>

Hello

					{createPortal(props.children, scratch)}
					{createPortal(props.children, root)}

			);
		}

		render(
			<Foo>

foobar

			</Foo>,
			scratch
		);
		expect(scratch.innerHTML).to.equal(
			'
foobar

foobar

Hello

'
		);

		toggle();
		rerender();
		expect(scratch.innerHTML).to.equal(
			'
foobar

Hello

foobar

'
		);
	});

	it('should support nested portals', () => {
		let toggle, toggle2, inner;

		function Bar() {
			const [mounted, setMounted] = useState(false);
			toggle2 = () => setMounted(s => !s);
			return (

 {
						inner = r;
					}}
				>

Inner

					{mounted && createPortal(
hiFromBar
, scratch)}
					{mounted && createPortal(
innerPortal
, inner)}

			);
		}

		function Foo(props) {
			const [mounted, setMounted] = useState(false);
			toggle = () => setMounted(s => !s);
			return (

Hello

					{mounted && createPortal(<Bar />, scratch)}

			);
		}

		render(<Foo />, scratch);
		expect(scratch.innerHTML).to.equal('

Hello

');

		toggle();
		rerender();
		expect(scratch.innerHTML).to.equal(
			'

Hello

Inner

'
		);

		toggle2();
		rerender();
		expect(scratch.innerHTML).to.equal(
			'

Hello

Inner

innerPortal

hiFromBar
'
		);

		toggle();
		rerender();
		expect(scratch.innerHTML).to.equal('

Hello

');
	});

	it('should support nested portals remounting #2669', () => {
		let setVisible;
		let i = 0;

		function PortalComponent(props) {
			const innerVnode =
{i}
;
			innerVnode.___id = 'inner_' + i++;
			const outerVnode = (

					{i}
					{props.show && createPortal(innerVnode, scratch)}

			);
			outerVnode.___id = 'outer_' + i++;
			return createPortal(outerVnode, scratch);
		}

		function App() {
			const [visible, _setVisible] = useState(true);
			setVisible = _setVisible;

			return (

					test
					<PortalComponent show={visible} />

			);
		}

		render(<App />, scratch);
		expect(scratch.innerHTML).to.equal(
			'
0

1

test
'
		);

		act(() => {
			setVisible(false);
		});
		rerender();
		expect(scratch.innerHTML).to.equal(
			'
3

test
'
		);

		act(() => {
			setVisible(true);
		});
		rerender();
		expect(scratch.innerHTML).to.equal(
			'
5

test

4
'
		);

		act(() => {
			setVisible(false);
		});
		rerender();
		expect(scratch.innerHTML).to.equal(
			'
7

test
'
		);
	});

	it('should not unmount when parent renders', () => {
		let root = document.createElement('div');
		let dialog = document.createElement('div');
		dialog.id = 'container';

		scratch.appendChild(root);
		scratch.appendChild(dialog);

		let spy = sinon.spy();
		class Child extends Component {
			componentDidMount() {
				spy();
			}

			render() {
				return
child
;
			}
		}

		let spyParent = sinon.spy();
		class App extends Component {
			componentDidMount() {
				spyParent();
			}
			render() {
				return
{createPortal(<Child />, dialog)}
;
			}
		}

		render(<App />, root);
		let dom = document.getElementById('child');
		expect(spyParent).to.be.calledOnce;
		expect(spy).to.be.calledOnce;

		// Render twice to trigger update scenario
		render(<App />, root);
		render(<App />, root);

		let domNew = document.getElementById('child');
		expect(dom).to.equal(domNew);
		expect(spyParent).to.be.calledOnce;
		expect(spy).to.be.calledOnce;
	});

	it('should switch between non portal and portal node (Modal as lastChild)', () => {
		let toggle;
		const Modal = ({ children, open }) =>
			open ? createPortal(
{children}
, scratch) :
Closed
;

		const App = () => {
			const [open, setOpen] = useState(false);
			toggle = setOpen.bind(this, x => !x);
			return (

					<button onClick={() => setOpen(!open)}>Show</button>
					{open ? 'Open' : 'Closed'}
					<Modal open={open}>Hello</Modal>

			);
		};

		render(<App />, scratch);
		expect(scratch.innerHTML).to.equal(
			'
<button>Show</button>Closed
Closed

'
		);

		toggle();
		rerender();
		expect(scratch.innerHTML).to.equal(
			'
<button>Show</button>Open

Hello
'
		);
	});

	it('should switch between non portal and portal node (Modal as firstChild)', () => {
		let toggle;
		const Modal = ({ children, open }) =>
			open ? createPortal(
{children}
, scratch) :
Closed
;

		const App = () => {
			const [open, setOpen] = useState(false);
			toggle = setOpen.bind(this, x => !x);
			return (

					<Modal open={open}>Hello</Modal>
					<button onClick={() => setOpen(!open)}>Show</button>
					{open ? 'Open' : 'Closed'}

			);
		};

		render(<App />, scratch);
		expect(scratch.innerHTML).to.equal(
			'

Closed
<button>Show</button>Closed
'
		);

		toggle();
		rerender();
		expect(scratch.innerHTML).to.equal(
			'
<button>Show</button>Open

Hello
'
		);

		toggle();
		rerender();
		expect(scratch.innerHTML).to.equal(
			'

Closed
<button>Show</button>Closed
'
		);
	});

	it('should order effects well', () => {
		const calls = [];
		const Modal = ({ children }) => {
			useEffect(() => {
				calls.push('Modal');
			}, []);
			return createPortal(
{children}
, scratch);
		};

		const ModalButton = ({ i }) => {
			useEffect(() => {
				calls.push(`Button ${i}`);
			}, []);

			return <button>Action</button>;
		};

		const App = () => {
			useEffect(() => {
				calls.push('App');
			}, []);

			return (
				<Modal>
					<ModalButton i="1" />
					<ModalButton i="2" />
				</Modal>
			);
		};

		act(() => {
			render(<App />, scratch);
		});

		expect(calls).to.deep.equal(['Button 1', 'Button 2', 'Modal', 'App']);
	});

	it('should include containerInfo', () => {
		let root = document.createElement('div');
		document.body.appendChild(root);

		const A = () => A;

		let portal;
		function Foo(props) {
			portal = createPortal(props.children, root);
			return
{portal}
;
		}
		render(
			<Foo>

			</Foo>,
			scratch
		);

		expect(portal.containerInfo).to.equal(root);

		root.parentNode.removeChild(root);
	});

	it('should order complex effects well', () => {
		const calls = [];
		const Parent = ({ children, isPortal }) => {
			useEffect(() => {
				calls.push(`${isPortal ? 'Portal ' : ''}Parent`);
			}, [isPortal]);

			return
{children}
;
		};

		const Child = ({ index, isPortal }) => {
			useEffect(() => {
				calls.push(`${isPortal ? 'Portal ' : ''}Child ${index}`);
			}, [index, isPortal]);

			return
{index}
;
		};

		const Portal = () => {
			const content = [1, 2, 3].map(index => (
				<Child key={index} index={index} isPortal />
			));

			useEffect(() => {
				calls.push('Portal');
			}, []);

			return createPortal(<Parent isPortal>{content}</Parent>, scratch2);
		};

		const App = () => {
			const content = [1, 2, 3].map(index => (
				<Child key={index} index={index} />
			));

			return (
				<React.Fragment>
					<Parent>{content}</Parent>
					<Portal />
				</React.Fragment>
			);
		};

		act(() => {
			render(<App />, scratch);
		});

		expect(calls).to.deep.equal([
			'Child 1',
			'Child 2',
			'Child 3',
			'Parent',
			'Portal Child 1',
			'Portal Child 2',
			'Portal Child 3',
			'Portal Parent',
			'Portal'
		]);
	});
});


.DS_Store
node_modules
npm-debug.log
dist
*/package-lock.json
yarn.lock
.vscode
.idea
test/ts/**/*.js
coverage
*.sw[op]
*.log
package/
preact-*.tgz
preact.tgz


import { expect } from 'chai';
import {
	createElement,
	ComponentFactory,
	ComponentConstructor,
	Component
} from '../../';
import { SimpleComponent, SimpleComponentProps } from './Component-test';

export interface highlightedProps {
	isHighlighted: boolean;
}

export function highlighted<T>(
	Wrappable: ComponentFactory<T>
): ComponentConstructor<T & highlightedProps> {
	return class extends Component<T & highlightedProps> {
		constructor(props: T & highlightedProps) {
			super(props);
		}

		render() {
			let className = this.props.isHighlighted ? 'highlighted' : '';
			return (
				<div className={className}>
					<Wrappable {...this.props} />
				</div>
			);
		}

		toString() {
			return `Highlighted ${Wrappable.name}`;
		}
	};
}

const HighlightedSimpleComponent = highlighted<SimpleComponentProps>(
	SimpleComponent
);

describe('hoc', () => {
	it('wraps the given component', () => {
		const highlight = new HighlightedSimpleComponent({
			initialName: 'initial name',
			isHighlighted: true
		});

		expect(highlight.toString()).to.eq('Highlighted SimpleComponent');
	});
});


return {
render(children) {
return render(children, container);
}
};

render(children, container);
},
unmount() {
unmountComponentAtNode(container);


name: Compressed Size

on:
  pull_request:
    branches:
      - '**'
    paths:
      - '**/src/**.js'

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: preactjs/compressed-size-action@v1
        with:
          repo-token: '${{ secrets.GITHUB_TOKEN }}'


import { Component, ComponentChild, ComponentChildren } from '../../src';

//
// SuspenseList
// -----------------------------------

export interface SuspenseListProps {
	children?: ComponentChildren;
	revealOrder?: 'forwards' | 'backwards' | 'together';
}

export class SuspenseList extends Component<SuspenseListProps> {
	render(): ComponentChild;
}


import React, { createElement, unmountComponentAtNode } from 'preact/compat';
import { setupScratch, teardown } from '../../../test/_util/helpers';

describe('unmountComponentAtNode', () => {
	/** @type {HTMLDivElement} */
	let scratch;

	beforeEach(() => {
		scratch = setupScratch();
	});

	afterEach(() => {
		teardown(scratch);
	});

	it('should unmount a root node', () => {
		const App = () =>
foo
;
		React.render(<App />, scratch);

		expect(unmountComponentAtNode(scratch)).to.equal(true);
		expect(scratch.innerHTML).to.equal('');
	});

	it('should do nothing if root is not mounted', () => {
		expect(unmountComponentAtNode(scratch)).to.equal(false);
		expect(scratch.innerHTML).to.equal('');
	});
});


exports.hydrateRoot = function(container, children) {


import React, { createElement } from 'preact/compat';
import { setupRerender } from 'preact/test-utils';
import { setupScratch, teardown } from '../../../test/_util/helpers';

describe('PureComponent', () => {
	/** @type {HTMLDivElement} */
	let scratch;

	/** @type {() => void} */
	let rerender;

	beforeEach(() => {
		scratch = setupScratch();
		rerender = setupRerender();
	});

	afterEach(() => {
		teardown(scratch);
	});

	it('should be a class', () => {
		expect(React)
			.to.have.property('PureComponent')
			.that.is.a('function');
	});

	it('should pass props in constructor', () => {
		let spy = sinon.spy();
		class Foo extends React.PureComponent {
			constructor(props) {
				super(props);
				spy(this.props, props);
			}
		}

		React.render(<Foo foo="bar" />, scratch);

		let expected = { foo: 'bar' };
		expect(spy).to.be.calledWithMatch(expected, expected);
	});

	it('should ignore the __source variable', () => {
		const pureSpy = sinon.spy();
		const appSpy = sinon.spy();
		let set;
		class Pure extends React.PureComponent {
			render() {
				pureSpy();
				return
Static
;
			}
		}

		const App = () => {
			const [, setState] = React.useState(0);
			appSpy();
			set = setState;
			return <Pure __source={{}} />;
		};

		React.render(<App />, scratch);
		expect(appSpy).to.be.calledOnce;
		expect(pureSpy).to.be.calledOnce;

		set(1);
		rerender();
		expect(appSpy).to.be.calledTwice;
		expect(pureSpy).to.be.calledOnce;
	});

	it('should only re-render when props or state change', () => {
		class C extends React.PureComponent {
			render() {
				return
;
			}
		}
		let spy = sinon.spy(C.prototype, 'render');

		let inst = React.render(<C />, scratch);
		expect(spy).to.have.been.calledOnce;
		spy.resetHistory();

		inst = React.render(<C />, scratch);
		expect(spy).not.to.have.been.called;

		let b = { foo: 'bar' };
		inst = React.render(<C a="a" b={b} />, scratch);
		expect(spy).to.have.been.calledOnce;
		spy.resetHistory();

		inst = React.render(<C a="a" b={b} />, scratch);
		expect(spy).not.to.have.been.called;

		inst.setState({});
		rerender();
		expect(spy).not.to.have.been.called;

		inst.setState({ a: 'a', b });
		rerender();
		expect(spy).to.have.been.calledOnce;
		spy.resetHistory();

		inst.setState({ a: 'a', b });
		rerender();
		expect(spy).not.to.have.been.called;
	});

	it('should update when props are removed', () => {
		let spy = sinon.spy();
		class App extends React.PureComponent {
			render() {
				spy();
				return
foo
;
			}
		}

		React.render(<App a="foo" />, scratch);
		React.render(<App />, scratch);
		expect(spy).to.be.calledTwice;
	});

	it('should have "isPureReactComponent" property', () => {
		let Pure = new React.PureComponent();
		expect(Pure.isReactComponent).to.deep.equal({});
	});
});


root = true

[*]
indent_style = tab
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[{*.json,.*rc,*.yml}]
indent_style = space
indent_size = 2
insert_final_newline = false

[*.md]
trim_trailing_whitespace = false


# Contributor Covenant Code of Conduct

## Our Pledge

In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.

## Our Standards

Examples of behavior that contributes to creating a positive environment include:

* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members

Examples of unacceptable behavior by participants include:

* The use of sexualized language or imagery and unwelcome sexual attention or advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a professional setting

## Our Responsibilities

Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.

Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.

## Scope

This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at hello@preactjs.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.

Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]

[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/


hydrate(children, container);
return createRoot(container);


import React, { createElement, findDOMNode } from 'preact/compat';
import { setupScratch, teardown } from '../../../test/_util/helpers';

describe('findDOMNode()', () => {
	/** @type {HTMLDivElement} */
	let scratch;

	class Helper extends React.Component {
		render({ something }) {
			if (something == null) return null;
			if (something === false) return null;
			return <div />;
		}
	}

	beforeEach(() => {
		scratch = setupScratch();
	});

	afterEach(() => {
		teardown(scratch);
	});

	it.skip('should return DOM Node if render is not false nor null', () => {
		const helper = React.render(<Helper />, scratch);
		expect(findDOMNode(helper)).to.be.instanceof(Node);
	});

	it('should return null if given null', () => {
		expect(findDOMNode(null)).to.be.null;
	});

	it('should return a regular DOM Element if given a regular DOM Element', () => {
		let scratch = document.createElement('div');
		expect(findDOMNode(scratch)).to.equalNode(scratch);
	});

	// NOTE: React.render() returning false or null has the component pointing
	// 			to no DOM Node, in contrast, Preact always render an empty Text DOM Node.
	it('should return null if render returns false', () => {
		const helper = React.render(<Helper something={false} />, scratch);
		expect(findDOMNode(helper)).to.be.null;
	});

	// NOTE: React.render() returning false or null has the component pointing
	// 			to no DOM Node, in contrast, Preact always render an empty Text DOM Node.
	it('should return null if render returns null', () => {
		const helper = React.render(<Helper something={null} />, scratch);
		expect(findDOMNode(helper)).to.be.null;
	});
});


<!DOCTYPE html>

		<meta charset="UTF-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
		<title>Patching HTML</title>


import { setupScratch, teardown } from '../../../test/_util/helpers';
import React, { createElement, render } from 'preact/compat';

describe('Select', () => {
	let scratch;

	beforeEach(() => {
		scratch = setupScratch();
	});

	afterEach(() => {
		teardown(scratch);
	});

	it('should work with multiple selected (array of values)', () => {
		function App() {
			return (
				<select multiple value={['B', 'C']}>
					<option value="A">A</option>
					<option value="B">B</option>
					<option value="C">C</option>
				</select>
			);
		}

		render(<App />, scratch);
		const options = scratch.firstChild.children;
		expect(options[0]).to.have.property('selected', false);
		expect(options[1]).to.have.property('selected', true);
		expect(options[2]).to.have.property('selected', true);
		expect(scratch.firstChild.value).to.equal('B');
	});
});


import { render, hydrate } from 'preact/compat'

import { render, hydrate, unmountComponentAtNode } from 'preact/compat'


import { Component } from 'preact';
import { shallowDiffers } from './util';

/**
 * Component class with a predefined `shouldComponentUpdate` implementation
 */
export function PureComponent(p) {
	this.props = p;
}
PureComponent.prototype = new Component();
// Some third-party libraries check if this property is present
PureComponent.prototype.isPureReactComponent = true;
PureComponent.prototype.shouldComponentUpdate = function(props, state) {
	return shallowDiffers(this.props, props) || shallowDiffers(this.state, state);
};


import React, { Component, lazy } from 'preact/compat';

const h = React.createElement;

/**
 * Create a Lazy component whose promise is controlled by by the test. This
 * function returns 3 values: The Lazy component to render, a `resolve`
 * function, and a `reject` function. Call `resolve` with the component the Lazy
 * component should resolve with. Call `reject` with the error the Lazy
 * component should reject with
 *
 * @example
 * // 1. Create and render the Lazy component
 * const [Lazy, resolve] = createLazy();
 * render(
 * 	<Suspense fallback={
Suspended...
}>
 * 		<Lazy />
 * 	</Suspense>,
 * 	scratch
 * );
 * rerender(); // Rerender is required so the fallback is displayed
 * expect(scratch.innerHTML).to.eql(`<div>Suspended...</div>`);
 *
 * // 2. Resolve the Lazy with a new component to render
 * return resolve(() =>
Hello
).then(() => {
 * 	rerender();
 * 	expect(scratch.innerHTML).to.equal(`<div>Hello</div>`);
 * });
 *
 * @typedef {import('../../../src').ComponentType<any>} ComponentType
 * @returns {[typeof Component, (c: ComponentType) => Promise<void>, (e: Error) => Promise<void>]}
 */
export function createLazy() {
	/** @type {(c: ComponentType) => Promise<void>} */
	let resolver, rejecter;
	const Lazy = lazy(() => {
		let promise = new Promise((resolve, reject) => {
			resolver = c => {
				resolve({ default: c });
				return promise;
			};

			rejecter = e => {
				reject(e);
				return promise;
			};
		});

		return promise;
	});

	return [Lazy, c => resolver(c), e => rejecter(e)];
}

/**
 * Returns a Component and a function (named `suspend`) that will suspend the component when called.
 * `suspend` will return two functions, `resolve` and `reject`. Call `resolve` with a Component the
 * suspended component should resume with or reject with the Error the suspended component should
 * reject with
 *
 * @example
 * // 1. Create a suspender with initial children (argument to createSuspender) and render it
 * const [Suspender, suspend] = createSuspender(() =>
Hello
);
 * render(
 * 	<Suspense fallback={
Suspended...
}>
 * 		<Suspender />
 * 	</Suspense>,
 * 	scratch
 * );
 * expect(scratch.innerHTML).to.eql(`div>Hello</div>`);
 *
 * // 2. Cause the component to suspend and rerender the update (i.e. the fallback)
 * const [resolve] = suspend();
 * rerender();
 * expect(scratch.innerHTML).to.eql(`div>Suspended...</div>`);
 *
 * // 3. Resolve the suspended component with a new component and rerender
 * return resolve(() =>
Hello2
).then(() => {
 * 	rerender();
 * 	expect(scratch.innerHTML).to.eql(`div>Hello2</div>`);
 * });
 *
 * @typedef {Component<{}, any>} Suspender
 * @typedef {[(c: ComponentType) => Promise<void>, (error: Error) => Promise<void>]} Resolvers
 * @param {ComponentType} DefaultComponent
 * @returns {[typeof Suspender, () => Resolvers]}
 */
export function createSuspender(DefaultComponent) {
	/** @type {(lazy: typeof Component) => void} */
	let renderLazy;
	class Suspender extends Component {
		constructor(props, context) {
			super(props, context);
			this.state = { Lazy: null };

			renderLazy = Lazy => this.setState({ Lazy });
		}

		render(props, state) {
			return state.Lazy ? h(state.Lazy, props) : h(DefaultComponent, props);
		}
	}

	sinon.spy(Suspender.prototype, 'render');

	/**
	 * @returns {Resolvers}
	 */
	function suspend() {
		const [Lazy, resolve, reject] = createLazy();
		renderLazy(Lazy);
		return [resolve, reject];
	}

	return [Suspender, suspend];
}


keep keep keep keep replace keep keep keep keep

render(children, container)
},
unmount() {
unmountComponentAtNode(container)

const { render, hydrate } = require('preact/compat');

exports.createRoot = function(container) {
	return {
		render(children) {
			return render(children, container);
		}
	};
};

exports.hydrateRoot = function(container, children) {
	return hydrate(children, container);
};


import { createElement, render, Component } from 'preact';
import { setupScratch, teardown } from '../_util/helpers';

/** @jsx createElement */

const runSuite = typeof customElements == 'undefined' ? xdescribe : describe;

runSuite('customised built-in elements', () => {
	let scratch;

	beforeEach(() => {
		scratch = setupScratch();
	});

	afterEach(() => {
		teardown(scratch);
	});

	it('should create built in elements correctly', () => {
		class Foo extends Component {
			render() {
				return <div is="built-in" />;
			}
		}

		const spy = sinon.spy();

		class BuiltIn extends HTMLDivElement {
			connectedCallback() {
				spy();
			}
		}

		customElements.define('built-in', BuiltIn, { extends: 'div' });

		render(<Foo />, scratch);

		expect(spy).to.have.been.calledOnce;
	});
});


import htm from 'htm';
import { h } from 'preact';
import { useState, useCallback } from 'preact/hooks';

const html = htm.bind(h);

// configuration used to show behavior vs. workaround
let childFirst = true;
const Config = () => html`

		<input
			type="checkbox"
			checked=${childFirst}
			onchange=${evt => {
				childFirst = evt.target.checked;
			}}
		/>
		Set child state before parent state.

`;

const Child = ({ items, setItems }) => {
	let [pendingId, setPendingId] = useState(null);
	if (!pendingId) {
		setPendingId(
			(pendingId = Math.random()
				.toFixed(20)
				.slice(2))
		);
	}

	const onInput = useCallback(
		evt => {
			let val = evt.target.value,
				_items = [...items, { _id: pendingId, val }];
			if (childFirst) {
				setPendingId(null);
				setItems(_items);
			} else {
				setItems(_items);
				setPendingId(null);
			}
		},
		[childFirst, setPendingId, setItems, items, pendingId]
	);

	return html`

			${items.map(
				(item, idx) => html`
					<input
						key=${item._id}
						value=${item.val}
						oninput=${evt => {
							let val = evt.target.value,
								_items = [...items];
							_items.splice(idx, 1, { ...item, val });
							setItems(_items);
						}}
					/>
				`
			)}

			<input
				key=${pendingId}
				placeholder="type to add an item"
				oninput=${onInput}
			/>

	`;
};

const Parent = () => {
	let [items, setItems] = useState([]);
	return html`

<${Config} /><${Child} items=${items} setItems=${setItems} />

	`;
};

export default Parent;


The MIT License (MIT)

Copyright (c) 2015-present Jason Miller

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

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.


export function hydrateRoot(container, children) {

hydrate(children, container)
return createRoot(container)


import { createElement, Suspense, lazy } from 'react';

import { Router, Route, Switch } from './simple-router';

/** @jsx createElement */

let Hello = lazy(() => import('./hello.js'));
let Bye = lazy(() => import('./bye.js'));

function Loading() {
	return
Hey! This is a fallback because we're loading things! :D
;
}

export default function SuspenseRouterBug() {
	return (
		<Router>

Suspense Router bug

			<Suspense fallback={<Loading />}>
				<Switch>
					<Route path="/" exact>
						<Hello />
					</Route>
					<Route path="/bye">
						<Bye />
					</Route>
				</Switch>
			</Suspense>
		</Router>
	);
}


<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
		<title>hydrate 1k table rows</title>
		<meta name="description" content="hydrating 1,000 rows" />
		<style>
			.preloadicon {
				display: none;
			}
			.glyphicon-remove:before {
				content: '⨯';
			}
		</style>
	</head>
	<body>
		<template id="template"></template>
		<script type="module">
			import {
				measureName,
				measureMemory,
				testElementText,
				afterFrame,
				afterFrameAsync
			} from './util.js';
			import * as framework from 'framework';
			import { getComponents } from '../src/keyed-children/components.js';
			import { Store } from '../src/keyed-children/store.js';

			/** @type {HTMLTemplateElement} */
			const template = document.getElementById('template');
			const { Main } = getComponents(framework);
			const { createRoot, createElement } = framework;

			const firstRowSel = 'tr:first-child > td:first-child';
			const lastRowSel = 'tr:last-child > td:first-child';

			const baseStore = new Store();
			baseStore.run();

			/**
			 * Delete the old hydrate root and create a new one with a clone of the
			 * template's content
			 */
			function setupHydrateRoot() {
				const hydrateRootId = 'hydrate-root';
				let hydrateRoot = document.getElementById(hydrateRootId);
				if (hydrateRoot) {
					hydrateRoot.remove();
				}

				hydrateRoot = document.createElement('div');
				hydrateRoot.id = hydrateRootId;
				hydrateRoot.appendChild(template.content.cloneNode(true));
				document.body.appendChild(hydrateRoot);
				return hydrateRoot;
			}

			/** Render the app inside the template tag */
			async function initializeTemplate() {
				// Initialize template
				createRoot(template.content).render(
					createElement(Main, { store: baseStore })
				);
				await afterFrameAsync();
			}

			/**
			 * Click the second row's remove link and ensure the number of rows before
			 * and after the click are as expected
			 */
			async function clickRemove(root, label, expectedBefore, expectedAfter) {
				let rowCount = root.querySelectorAll('tr').length;
				if (rowCount !== expectedBefore) {
					throw new Error(
						`${label}: Incorrect number of rows before remove click. Expected ${expectedBefore} but got ${rowCount}`
					);
				}

				const removeLink = root.querySelector(
					'tr:nth-child(2) td:nth-child(3) a'
				);
				removeLink.click();
				await afterFrameAsync();

				rowCount = root.querySelectorAll('tr').length;
				if (rowCount !== expectedAfter) {
					throw new Error(
						`${label}: Incorrect number of rows after after remove click. Expected ${expectedAfter} but got ${rowCount}`
					);
				}
			}

			async function warmupRun(i) {
				// Test out hydrate and ensure it works
				const hydrateRoot = setupHydrateRoot();

				// Verify initial hydrate root isn't already hydrated and is static
				testElementText(firstRowSel, '1');
				testElementText(lastRowSel, '1000');
				await clickRemove(hydrateRoot, `WARMUP ${i} - prehydrate`, 1000, 1000);

				const store = new Store();
				store.data = baseStore.data.slice();
				createRoot(hydrateRoot).hydrate(createElement(Main, { store }));

				// Verify hydrate has correct markup and is properly hydrated
				testElementText(firstRowSel, '1');
				testElementText(lastRowSel, '1000');
				await clickRemove(hydrateRoot, `WARMUP ${i} - posthydrate`, 1000, 999);
			}

			function timedRun() {
				afterFrame(function () {
					performance.mark('stop');
					performance.measure(measureName, 'start', 'stop');

					measureMemory();
				});

				const hydrateRoot = setupHydrateRoot();
				const store = new Store();
				store.data = baseStore.data.slice();

				performance.mark('start');
				createRoot(hydrateRoot).hydrate(createElement(Main, { store }));
			}

			async function main() {
				// const WARMUP_COUNT = 5;
				const WARMUP_COUNT = 5;
				for (let i = 0; i < WARMUP_COUNT; i++) {
					await warmupRun(i);
				}

				await afterFrameAsync();

				timedRun();
			}

			initializeTemplate().then(main);
		</script>
	</body>
</html>


import { createElement, render } from 'preact';
import { setupScratch, teardown } from '../../../test/_util/helpers';
import { useCallback } from 'preact/hooks';

/** @jsx createElement */

describe('useCallback', () => {
	/** @type {HTMLDivElement} */
	let scratch;

	beforeEach(() => {
		scratch = setupScratch();
	});

	afterEach(() => {
		teardown(scratch);
	});

	it('only recomputes the callback when inputs change', () => {
		const callbacks = [];

		function Comp({ a, b }) {
			const cb = useCallback(() => a + b, [a, b]);
			callbacks.push(cb);
			return null;
		}

		render(<Comp a={1} b={1} />, scratch);
		render(<Comp a={1} b={1} />, scratch);

		expect(callbacks[0]).to.equal(callbacks[1]);
		expect(callbacks[0]()).to.equal(2);

		render(<Comp a={1} b={2} />, scratch);
		render(<Comp a={1} b={2} />, scratch);

		expect(callbacks[1]).to.not.equal(callbacks[2]);
		expect(callbacks[2]).to.equal(callbacks[3]);
		expect(callbacks[2]()).to.equal(3);
	});
});


/*
 * Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * 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.
 *
 */
/*global module, require*/
module.exports = function (grunt) {
    'use strict';

    var common = require("./tasks/lib/common")(grunt);

    // Project configuration.
    grunt.initConfig({
        pkg  : grunt.file.readJSON("package.json"),
        meta : {
            src   : [
                'src/**/*.js',
                '!src/thirdparty/**',
                '!src/widgets/bootstrap-*.js',
                '!src/extensions/**/unittest-files/**/*.js',
                '!src/extensions/**/thirdparty/**/*.js',
                '!src/extensions/dev/**',
                '!src/extensions/disabled/**',
                '!**/node_modules/**/*.js',
                '!src/**/*-min.js',
                '!src/**/*.min.js'
            ],
            test : [
                'test/**/*.js',
                '!test/perf/*-files/**/*.js',
                '!test/spec/*-files/**/*.js',
                '!test/smokes/**',
                '!test/temp/**',
                '!test/thirdparty/**',
                '!test/**/node_modules/**/*.js'
            ],
            grunt: [
                'Gruntfile.js',
                'tasks/**/*.js'
            ],
            /* specs that can run in phantom.js */
            specs : [
                'test/spec/CommandManager-test.js',
                //'test/spec/LanguageManager-test.js',
                //'test/spec/PreferencesManager-test.js',
                'test/spec/ViewUtils-test.js'
            ]
        },
        watch: {
            all : {
                files: ['**/*', '!**/node_modules/**'],
                tasks: ['jshint']
            },
            grunt : {
                files: ['<%= meta.grunt %>', 'tasks/**/*'],
                tasks: ['jshint:grunt']
            },
            src : {
                files: ['<%= meta.src %>', 'src/**/*'],
                tasks: ['jshint:src']
            },
            test : {
                files: ['<%= meta.test %>', 'test/**/*'],
                tasks: ['jshint:test']
            }
        },
        /* FIXME (jasonsanjose): how to handle extension tests */
        jasmine : {
            src : 'undefined.js', /* trick the default runner to run without importing src files */
            options : {
                junit : {
                    path: 'test/results',
                    consolidate: true
                },
                specs : '<%= meta.specs %>',
                /* Keep in sync with test/SpecRunner.html dependencies */
                vendor : [
                    'src/thirdparty/jquery-1.7.js',
                    'src/thirdparty/CodeMirror2/lib/codemirror.js',
                    'src/thirdparty/CodeMirror2/lib/util/dialog.js',
                    'src/thirdparty/CodeMirror2/lib/util/searchcursor.js',
                    'src/thirdparty/CodeMirror2/addon/edit/closetag.js',
                    'src/thirdparty/CodeMirror2/addon/selection/active-line.js',
                    'src/thirdparty/mustache/mustache.js',
                    'src/thirdparty/path-utils/path-utils.min',
                    'src/thirdparty/less-1.3.0.min.js'
                ],
                helpers : [
                    'test/spec/PhantomHelper.js'
                ],
                template : require('grunt-template-jasmine-requirejs'),
                templateOptions: {
                    requireConfig : {
                        baseUrl: 'src',
                        paths: {
                            'test' : '../test',
                            'perf' : '../test/perf',
                            'spec' : '../test/spec',
                            'text' : 'thirdparty/text/text',
                            'i18n' : 'thirdparty/i18n/i18n'
                        }
                    }
                }
            }
        },
        jshint: {
            all: [
                '<%= meta.grunt %>',
                '<%= meta.src %>',
                '<%= meta.test %>'
            ],
            grunt:  '<%= meta.grunt %>',
            src:    '<%= meta.src %>',
            test:   '<%= meta.test %>',
            /* use strict options to mimic JSLINT until we migrate to JSHINT in Brackets */
            options: {
                jshintrc: '.jshintrc'
            }
        },
        shell: {
            repo: grunt.option("shell-repo") || "../brackets-shell",
            mac: "<%= shell.repo %>/installer/mac/staging/<%= pkg.name %>.app",
            win: "<%= shell.repo %>/installer/win/staging/<%= pkg.name %>.exe"
        }
    });

    // load dependencies
    grunt.loadTasks('tasks');
    grunt.loadNpmTasks('grunt-contrib-jasmine');
    grunt.loadNpmTasks('grunt-contrib-jshint');
    grunt.loadNpmTasks('grunt-contrib-watch');

    // task: install
    grunt.registerTask('install', ['write-config']);

    // task: test
    //grunt.registerTask('test', ['jshint', 'jasmine']);
    grunt.registerTask('test', ['jshint']);

    // task: set-sprint
    // Update sprint number in package.json and rewrite src/config.json
    grunt.registerTask('set-sprint', ['update-sprint-number', 'write-config']);

    // Default task.
    grunt.registerTask('default', ['test']);
};


/*!
 * Connect - favicon
 * Copyright(c) 2010 Sencha Inc.
 * Copyright(c) 2011 TJ Holowaychuk
 * MIT Licensed
 */

/**
 * Module dependencies.
 */

var fs = require('fs')
  , utils = require('../utils');

/**
 * Favicon:
 *
 * By default serves the connect favicon, or the favicon
 * located by the given `path`.
 *
 * Options:
 *
 *   - `maxAge`  cache-control max-age directive, defaulting to 1 day
 *
 * Examples:
 *
 *   Serve default favicon:
 *
 *     connect()
 *       .use(connect.favicon())
 *
 *   Serve favicon before logging for brevity:
 *
 *     connect()
 *       .use(connect.favicon())
 *       .use(connect.logger('dev'))
 *
 *   Serve custom favicon:
 *
 *     connect()
 *       .use(connect.favicon('public/favicon.ico))
 *
 * @param {String} path
 * @param {Object} options
 * @return {Function}
 * @api public
 */

module.exports = function favicon(path, options){
  var options = options || {}
    , path = path || __dirname + '/../public/favicon.ico'
    , maxAge = options.maxAge || 86400000
    , icon; // favicon cache

  return function favicon(req, res, next){
    if ('/favicon.ico' == req.url) {
      if (icon) {
        res.writeHead(200, icon.headers);
        res.end(icon.body);
      } else {
        fs.readFile(path, function(err, buf){
          if (err) return next(err);
          icon = {
            headers: {
                'Content-Type': 'image/x-icon'
              , 'Content-Length': buf.length
              , 'ETag': '"' + utils.md5(buf) + '"'
              , 'Cache-Control': 'public, max-age=' + (maxAge / 1000)
            },
            body: buf
          };
          res.writeHead(200, icon.headers);
          res.end(icon.body);
        });
      }
    } else {
      next();
    }
  };
};


#quick-view-container {
    display: none;

    background: #e0e1e3;
    position: absolute;
    z-index: 5000;
    left: 200px;
    top: 40px;
    pointer-events: none;

    padding: 15px;
    text-align: center;

    border-radius: 5px;
    box-shadow: 0 4px 15px rgba(0,0,0,0.25), inset 0 0 0 1px #a6a6a6, inset 0 0 0 2px #ebedec;
}

#quick-view-container .preview-content {
    background-image: url(preview_bg.png);
    border-radius: 2px;
    border: 1px solid #a6a8a8;
}

#quick-view-container .color-swatch {
    width: 100px;
    height: 100px;
    background-size: 100%;
}

#quick-view-container .image-preview {
    line-height: 0;
}

#quick-view-container .image-preview img {
    min-width: 100px;
    max-width: 200px;
    max-height: 200px;
}

#quick-view-container .img-size {
    background-color: #c8cac9;
    border-top: 1px solid #a6a8a8;
    font-size: 0.9em;
    color: #565656;
    padding-left: 3px;
    margin-top: 0;
    text-align: left;
    text-shadow: 0 1px 0px #e8e8e8;
}

#quick-view-container.preview-bubble-above:before {
    display: none;
}

#quick-view-container.preview-bubble-above:after {
    width: 24px;
    height: 14px;
    bottom: -12px;
    content: '';
    position: absolute;
    left: 50%;
    margin-left: -12px;
    background: url(point.svg) no-repeat center;
    z-index: 100;
    display: block;
}

#quick-view-container.preview-bubble-below:before {
    width: 24px;
    height: 14px;
    top: -12px;
    content: '';
    position: absolute;
    left: 50%;
    margin-left: -12px;
    background: url(point.svg) no-repeat center;
    z-index: 100;
    display: block;
    -webkit-transform: rotate(180deg);
}

#quick-view-container.preview-bubble-below:after {
    display: none;
}

.quick-view-highlight {
    background-color: rgba(200, 200, 150, 0.4);
}


<!DOCTYPE html>

	<meta charset="utf-8">
	<title>jQuery UI Accordion - Customize icons</title>
	<link rel="stylesheet" href="../../themes/base/jquery.ui.all.css">

	<link rel="stylesheet" href="../demos.css">

Section 1

Mauris mauris ante, blandit et, ultrices a, suscipit eget, quam. Integer ut neque. Vivamus nisi metus, molestie vel, gravida in, condimentum sit amet, nunc. Nam a nibh. Donec suscipit eros. Nam mi. Proin viverra leo ut odio. Curabitur malesuada. Vestibulum a velit eu ante scelerisque vulputate.

Section 2

Sed non urna. Donec et ante. Phasellus eu ligula. Vestibulum sit amet purus. Vivamus hendrerit, dolor at aliquet laoreet, mauris turpis porttitor velit, faucibus interdum tellus libero ac justo. Vivamus non quam. In suscipit faucibus urna.

Section 3

Nam enim risus, molestie et, porta ac, aliquam ac, risus. Quisque lobortis. Phasellus pellentesque purus in massa. Aenean in pede. Phasellus ac libero ac tellus pellentesque semper. Sed ac felis. Sed commodo, magna quis lacinia ornare, quam ante aliquam nisi, eu iaculis leo purus venenatis dui.

List item one

List item two

List item three

Section 4

Cras dictum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aenean lacinia mauris vel est.

Suspendisse eu nisl. Nullam ut libero. Integer dignissim consequat lectus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.

<button id="toggle">Toggle icons</button>

Customize the header icons with the icons option, which accepts classes for the header's default and active (open) state.  Use any class from the UI CSS framework, or create custom classes with background images.


(function() {

var parts = document.location.search.slice( 1 ).split( "&" ),
	length = parts.length,
	i = 0,
	current,
	version,
	url;

for ( ; i < length; i++ ) {
	current = parts[ i ].split( "=" );
	if ( current[ 0 ] === "jquery" ) {
		version = current[ 1 ];
		break;
	}
}

if ( version === "git" ) {
	url = "http://code.jquery.com/jquery-git.js";
} else {
	url = "../../jquery-" + ( version || "1.7.2" ) + ".js";
}

document.write( "<script src='" + url + "'></script>" );

}() );


var fstream = require("../fstream.js")
var path = require("path")

var r = fstream.Reader({ path: path.dirname(__dirname)
                       , filter: function () {
                           return !this.basename.match(/^\./) &&
                                  !this.basename.match(/^node_modules$/)
                                  !this.basename.match(/^deep-copy$/)
                                  !this.basename.match(/^filter-copy$/)
                         }
                       })

// this writer will only write directories
var w = fstream.Writer({ path: path.resolve(__dirname, "filter-copy")
                       , type: "Directory"
                       , filter: function () {
                           return this.type === "Directory"
                         }
                       })

var indent = ""
var escape = {}

r.on("entry", appears)
r.on("ready", function () {
  console.error("ready to begin!", r.path)
})

function appears (entry) {
  console.error(indent + "a %s appears!", entry.type, entry.basename, typeof entry.basename)
  if (foggy) {
    console.error("FOGGY!")
    var p = entry
    do {
      console.error(p.depth, p.path, p._paused)
    } while (p = p.parent)

    throw new Error("\033[mshould not have entries while foggy")
  }
  indent += "\t"
  entry.on("data", missile(entry))
  entry.on("end", runaway(entry))
  entry.on("entry", appears)
}

var foggy
function missile (entry) {
  if (entry.type === "Directory") {
    var ended = false
    entry.once("end", function () { ended = true })
    return function (c) {
      // throw in some pathological pause()/resume() behavior
      // just for extra fun.
      process.nextTick(function () {
        if (!foggy && !ended) { // && Math.random() < 0.3) {
          console.error(indent +"%s casts a spell", entry.basename)
          console.error("\na slowing fog comes over the battlefield...\n\033[32m")
          entry.pause()
          entry.once("resume", liftFog)
          foggy = setTimeout(liftFog, 1000)

          function liftFog (who) {
            if (!foggy) return
            if (who) {
              console.error("%s breaks the spell!", who && who.path)
            } else {
              console.error("the spell expires!")
            }
            console.error("\033[mthe fog lifts!\n")
            clearTimeout(foggy)
            foggy = null
            if (entry._paused) entry.resume()
          }

        }
      })
    }
  }

  return function (c) {
    var e = Math.random() < 0.5
    console.error(indent + "%s %s for %d damage!",
                entry.basename,
                e ? "is struck" : "fires a chunk",
                c.length)
  }
}

function runaway (entry) { return function () {
  var e = Math.random() < 0.5
  console.error(indent + "%s %s",
                entry.basename,
                e ? "turns to flee" : "is vanquished!")
  indent = indent.slice(0, -1)
}}

w.on("entry", attacks)
//w.on("ready", function () { attacks(w) })
function attacks (entry) {
  console.error(indent + "%s %s!", entry.basename,
              entry.type === "Directory" ? "calls for backup" : "attacks")
  entry.on("entry", attacks)
}

ended = false
var i = 1
r.on("end", function () {
  if (foggy) clearTimeout(foggy)
  console.error("\033[mIT'S OVER!!")
  console.error("A WINNAR IS YOU!")

  console.log("ok " + (i ++) + " A WINNAR IS YOU")
  ended = true
  // now go through and verify that everything in there is a dir.
  var p = path.resolve(__dirname, "filter-copy")
  var checker = fstream.Reader({ path: p })
  checker.checker = true
  checker.on("child", function (e) {
    var ok = e.type === "Directory"
    console.log((ok ? "" : "not ") + "ok " + (i ++) +
                " should be a dir: " +
                e.path.substr(checker.path.length + 1))
  })
})

process.on("exit", function () {
  console.log((ended ? "" : "not ") + "ok " + (i ++) + " ended")
})

r.pipe(w)


delayed-stream

# delayed-stream

Buffers events from a stream until you are ready to handle them.

## Installation

``` bash
npm install delayed-stream
```

## Usage

The following example shows how to write a http echo server that delays its
response by 1000 ms.

``` javascript
var DelayedStream = require('delayed-stream');
var http = require('http');

http.createServer(function(req, res) {
  var delayed = DelayedStream.create(req);

  setTimeout(function() {
    res.writeHead(200);
    delayed.pipe(res);
  }, 1000);
});
```

If you are not using `Stream#pipe`, you can also manually release the buffered
events by calling `delayedStream.resume()`:

``` javascript
var delayed = DelayedStream.create(req);

setTimeout(function() {
  // Emit all buffered events and resume underlaying source
  delayed.resume();
}, 1000);
```

## Implementation

In order to use this meta stream properly, here are a few things you should
know about the implementation.

### Event Buffering / Proxying

All events of the `source` stream are hijacked by overwriting the `source.emit`
method. Until node implements a catch-all event listener, this is the only way.

However, delayed-stream still continues to emit all events it captures on the
`source`, regardless of whether you have released the delayed stream yet or
not.

Upon creation, delayed-stream captures all `source` events and stores them in
an internal event buffer. Once `delayedStream.release()` is called, all
buffered events are emitted on the `delayedStream`, and the event buffer is
cleared. After that, delayed-stream merely acts as a proxy for the underlaying
source.

### Error handling

Error events on `source` are buffered / proxied just like any other events.
However, `delayedStream.create` attaches a no-op `'error'` listener to the
`source`. This way you only have to handle errors on the `delayedStream`
object, rather than in two places.

### Buffer limits

delayed-stream provides a `maxDataSize` property that can be used to limit
the amount of data being buffered. In order to protect you from bad `source`
streams that don't react to `source.pause()`, this feature is enabled by
default.

## API

### DelayedStream.create(source, [options])

Returns a new `delayedStream`. Available options are:

* `pauseStream`
* `maxDataSize`

The description for those properties can be found below.

### delayedStream.source

The `source` stream managed by this object. This is useful if you are
passing your `delayedStream` around, and you still want to access properties
on the `source` object.

### delayedStream.pauseStream = true

Whether to pause the underlaying `source` when calling
`DelayedStream.create()`. Modifying this property afterwards has no effect.

### delayedStream.maxDataSize = 1024 * 1024

The amount of data to buffer before emitting an `error`.

If the underlaying source is emitting `Buffer` objects, the `maxDataSize`
refers to bytes.

If the underlaying source is emitting JavaScript strings, the size refers to
characters.

If you know what you are doing, you can set this property to `Infinity` to
disable this feature. You can also modify this property during runtime.

### delayedStream.maxDataSize = 1024 * 1024

The amount of data to buffer before emitting an `error`.

If the underlaying source is emitting `Buffer` objects, the `maxDataSize`
refers to bytes.

If the underlaying source is emitting JavaScript strings, the size refers to
characters.

If you know what you are doing, you can set this property to `Infinity` to
disable this feature.

### delayedStream.dataSize = 0

The amount of data buffered so far.

### delayedStream.readable

An ECMA5 getter that returns the value of `source.readable`.

### delayedStream.resume()

If the `delayedStream` has not been released so far, `delayedStream.release()`
is called.

In either case, `source.resume()` is called.

### delayedStream.pause()

Calls `source.pause()`.

### delayedStream.pipe(dest)

Calls `delayedStream.resume()` and then proxies the arguments to `source.pipe`.

### delayedStream.release()

Emits and clears all events that have been buffered up so far. This does not
resume the underlaying source, use `delayedStream.resume()` instead.

## License

delayed-stream is licensed under the MIT license.


"use strict"; // run code in ES5 strict mode

/**
 * Configures webpack so it can be used with rewire. Make sure that the options aren't modified
 * after calling this function. It's important that the rewire()-postLoader is the last loader called on a module.
 *
 * @see https://github.com/webpack/webpack
 *
 * @param {Object} options a webpack option object
 */
function configureWebpack(options) {
    console.log("(DEPRECATED) rewire itself doesn't support webpack anymore. Please use rewire-webpack (https://github.com/jhnns/rewire-webpack)");

    options.resolve = options.resolve || {};
    options.postLoaders = options.postLoaders || [];
    options.resolve.postprocess = options.resolve.postprocess || {};
    options.resolve.postprocess.normal = options.resolve.postprocess.normal || [];

    // Registering the postLoader for injecting the special rewire code
    options.postLoaders.push(require("./webpackPostLoader.js"));

    // Registering the postProcessor for resolving paths
    options.resolve.postprocess.normal.push(require("./webpackPostProcessor.js"));
}

module.exports = configureWebpack;


/*
 * Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * 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.
 *
 */

/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50, node: true */
/*global */

(function () {
    "use strict";

    /**
     * @private
     * @type {DomainManager}
     * The DomainManager passed in at init.
     */
    var _domainManager = null;

    /**
     * @private
     * Handler for test.reverseAsync command. Reverses the specified string
     * and then returns the result asynconously.
     * @param {string} s String to reverse.
     * @param {Function} cb Callback function of the form cb(err, response)
     */
    function cmdTestReverseAsync(s, cb) {
        var result = s.split("").reverse().join("");
        process.nextTick(function () {
            cb(null, result);
        });
    }

    /**
     * Initializes the test domain with an additional test command.
     * @param {DomainManager} DomainManager The DomainManager for the server
     */
    function init(DomainManager) {
        _domainManager = DomainManager;
        if (!_domainManager.hasDomain("test")) {
            _domainManager.registerDomain("test", {major: 0, minor: 1});
        }
        _domainManager.registerCommand(
            "test",
            "reverseAsync",
            cmdTestReverseAsync,
            true,
            "reverses the specified string using an async call on the server",
            [{name: "s", type: "string"}],
            [{name: "reversedString", type: "string"}]
        );
    }

    exports.init = init;

}());


// Update sprint number in package.json and rewrite src/config.json


module.exports = rimraf
rimraf.sync = rimrafSync

var path = require("path")
  , fs

try {
  // optional dependency
  fs = require("graceful-fs")
} catch (er) {
  fs = require("fs")
}

// for EMFILE handling
var timeout = 0
exports.EMFILE_MAX = 1000
exports.BUSYTRIES_MAX = 3

function rimraf (p, cb) {
  if (!cb) throw new Error("No callback passed to rimraf()")

  var busyTries = 0
  rimraf_(p, function CB (er) {
    if (er) {
      if (er.code === "EBUSY" && busyTries < exports.BUSYTRIES_MAX) {
        busyTries ++
        var time = busyTries * 100
        // try again, with the same exact callback as this one.
        return setTimeout(function () {
          rimraf_(p, CB)
        }, time)
      }

      // this one won't happen if graceful-fs is used.
      if (er.code === "EMFILE" && timeout < exports.EMFILE_MAX) {
        return setTimeout(function () {
          rimraf_(p, CB)
        }, timeout ++)
      }

      // already gone
      if (er.code === "ENOENT") er = null
    }

    timeout = 0
    cb(er)
  })
}

// Two possible strategies.
// 1. Assume it's a file.  unlink it, then do the dir stuff on EPERM or EISDIR
// 2. Assume it's a directory.  readdir, then do the file stuff on ENOTDIR
//
// Both result in an extra syscall when you guess wrong.  However, there
// are likely far more normal files in the world than directories.  This
// is based on the assumption that a the average number of files per
// directory is >= 1.
//
// If anyone ever complains about this, then I guess the strategy could
// be made configurable somehow.  But until then, YAGNI.
function rimraf_ (p, cb) {
  fs.unlink(p, function (er) {
    if (er && er.code === "ENOENT")
      return cb()
    if (er && (er.code === "EPERM" || er.code === "EISDIR"))
      return rmdir(p, er, cb)
    return cb(er)
  })
}

function rmdir (p, originalEr, cb) {
  // try to rmdir first, and only readdir on ENOTEMPTY or EEXIST (SunOS)
  // if we guessed wrong, and it's not a directory, then
  // raise the original error.
  fs.rmdir(p, function (er) {
    if (er && (er.code === "ENOTEMPTY" || er.code === "EEXIST"))
      rmkids(p, cb)
    else if (er && er.code === "ENOTDIR")
      cb(originalEr)
    else
      cb(er)
  })
}

function rmkids(p, cb) {
  fs.readdir(p, function (er, files) {
    if (er)
      return cb(er)
    var n = files.length
    if (n === 0)
      return fs.rmdir(p, cb)
    var errState
    files.forEach(function (f) {
      rimraf(path.join(p, f), function (er) {
        if (errState)
          return
        if (er)
          return cb(errState = er)
        if (--n === 0)
          fs.rmdir(p, cb)
      })
    })
  })
}

// this looks simpler, and is strictly *faster*, but will
// tie up the JavaScript thread and fail on excessively
// deep directory trees.
function rimrafSync (p) {
  try {
    fs.unlinkSync(p)
  } catch (er) {
    if (er.code === "ENOENT")
      return
    if (er.code !== "EPERM" && er.code !== "EISDIR")
      throw er
    try {
      fs.rmdirSync(p)
    } catch (er2) {
      if (er2.code === "ENOENT")
        return
      if (er2.code === "ENOTDIR")
        throw er
      if (er2.code === "ENOTEMPTY") {
        fs.readdirSync(p).forEach(function (f) {
          rimrafSync(path.join(p, f))
        })
        fs.rmdirSync(p)
      }
    }
  }
}