<commit_before>import React from 'react';
import {
  Collapse,
  Navbar,
  NavbarToggler,
  NavbarBrand,
  Nav,
  NavItem,
  NavLink,
  UncontrolledDropdown,
  DropdownToggle,
  DropdownMenu,
  DropdownItem } from 'reactstrap';

export default class Example extends React.Component {
  constructor(props) {
    super(props);

    this.toggle = this.toggle.bind(this);
    this.state = {
      isOpen: false
    };
  }
  toggle() {
    this.setState({
      isOpen: !this.state.isOpen
    });
  }
  render() {
    return (

        <Navbar color="faded" light expand="md">
          <NavbarBrand href="/">reactstrap</NavbarBrand>
          <NavbarToggler onClick={this.toggle} />
          <Collapse isOpen={this.state.isOpen} navbar>

              <NavItem>
                <NavLink href="/components/">Components</NavLink>
              </NavItem>
              <NavItem>
                <NavLink href="https://github.com/reactstrap/reactstrap">GitHub</NavLink>
              </NavItem>
              <UncontrolledDropdown nav inNavbar>
                <DropdownToggle nav caret>
                  Options
                </DropdownToggle>
                <DropdownMenu right>
                  <DropdownItem>
                    Option 1
                  </DropdownItem>
                  <DropdownItem>
                    Option 2
                  </DropdownItem>
                  <DropdownItem divider />
                  <DropdownItem>
                    Reset
                  </DropdownItem>
                </DropdownMenu>
              </UncontrolledDropdown>

          </Collapse>
        </Navbar>

    );
  }
}
<commit_msg>chore(docs): Update Navbar example background color (#939)<commit_after>import React from 'react';
import {
  Collapse,
  Navbar,
  NavbarToggler,
  NavbarBrand,
  Nav,
  NavItem,
  NavLink,
  UncontrolledDropdown,
  DropdownToggle,
  DropdownMenu,
  DropdownItem } from 'reactstrap';

export default class Example extends React.Component {
  constructor(props) {
    super(props);

    this.toggle = this.toggle.bind(this);
    this.state = {
      isOpen: false
    };
  }
  toggle() {
    this.setState({
      isOpen: !this.state.isOpen
    });
  }
  render() {
    return (

        <Navbar color="light" light expand="md">
          <NavbarBrand href="/">reactstrap</NavbarBrand>
          <NavbarToggler onClick={this.toggle} />
          <Collapse isOpen={this.state.isOpen} navbar>

              <NavItem>
                <NavLink href="/components/">Components</NavLink>
              </NavItem>
              <NavItem>
                <NavLink href="https://github.com/reactstrap/reactstrap">GitHub</NavLink>
              </NavItem>
              <UncontrolledDropdown nav inNavbar>
                <DropdownToggle nav caret>
                  Options
                </DropdownToggle>
                <DropdownMenu right>
                  <DropdownItem>
                    Option 1
                  </DropdownItem>
                  <DropdownItem>
                    Option 2
                  </DropdownItem>
                  <DropdownItem divider />
                  <DropdownItem>
                    Reset
                  </DropdownItem>
                </DropdownMenu>
              </UncontrolledDropdown>

          </Collapse>
        </Navbar>

    );
  }
}
<|endoftext|>


<commit_before>'use strict';

const { readFileSync, existsSync } = require('fs');
const path = require('path');
const Rollup = require('broccoli-rollup');
const Funnel = require('broccoli-funnel');
const MergeTrees = require('broccoli-merge-trees');
const typescript = require('broccoli-typescript-compiler').typescript;
const BroccoliDebug = require('broccoli-debug');
const findLib = require('./find-lib');
const findPackage = require('./find-package');
const funnelLib = require('./funnel-lib');
const { VERSION } = require('./version');
const WriteFile = require('broccoli-file-creator');
const StringReplace = require('broccoli-string-replace');
const { RELEASE, DEBUG, toConst } = require('./features');
const GlimmerTemplatePrecompiler = require('./glimmer-template-compiler');
const VERSION_PLACEHOLDER = /VERSION_STRING_PLACEHOLDER/g;
const { stripIndent } = require('common-tags');
const toES5 = require('./to-es5');

const debugTree = BroccoliDebug.buildDebugCallback('ember-source');

module.exports.routerES = function _routerES() {
  return new Rollup(findLib('router_js'), {
    rollup: {
      external: ['route-recognizer', 'rsvp'],
      input: 'index.js',
      output: {
        file: 'router.js',
        format: 'es',
      },
    },
    annotation: 'router.js',
  });
};

module.exports.jquery = function _jquery() {
  return new Funnel(findLib('jquery'), {
    files: ['jquery.js'],
    destDir: 'jquery',
    annotation: 'jquery',
  });
};

module.exports.internalLoader = function _internalLoader() {
  return new Funnel('packages/loader/lib', {
    files: ['index.js'],
    getDestinationPath() {
      return 'loader.js';
    },
    annotation: 'internal loader',
  });
};

module.exports.qunit = function _qunit() {
  return new Funnel(findLib('qunit'), {
    files: ['qunit.js', 'qunit.css'],
    destDir: 'qunit',
    annotation: 'qunit',
  });
};

module.exports.getPackagesES = function getPackagesES() {
  let input = new Funnel(`packages`, {
    exclude: ['node-module/**', 'loader/**', 'external-helpers/**'],
    destDir: `packages`,
  });

  let debuggedInput = debugTree(input, `get-packages-es:input`);

  let compiledTemplatesAndTypescript = new GlimmerTemplatePrecompiler(debuggedInput, {
    persist: true,
    glimmer: require('@glimmer/compiler'),
    annotation: `get-packages-es templates -> es`,
  });

  let debuggedCompiledTemplatesAndTypeScript = debugTree(
    compiledTemplatesAndTypescript,
    `get-packages-es:templates-output`
  );

  let nonTypeScriptContents = new Funnel(debuggedCompiledTemplatesAndTypeScript, {
    srcDir: 'packages',
    exclude: ['**/*.ts'],
  });

  let typescriptContents = new Funnel(debuggedCompiledTemplatesAndTypeScript, {
    include: ['**/*.ts'],
  });

  let typescriptCompiled = typescript(debugTree(typescriptContents, `get-packages-es:ts:input`));

  let debuggedCompiledTypescript = debugTree(typescriptCompiled, `get-packages-es:ts:output`);

  let mergedFinalOutput = new MergeTrees([nonTypeScriptContents, debuggedCompiledTypescript], {
    overwrite: true,
  });

  return debugTree(mergedFinalOutput, `get-packages-es:output`);
};

module.exports.emberTypescriptPkgES = function emberTypescriptPkg(name) {
  let input = new Funnel(`packages/${name}`, {
    destDir: `packages/${name}`,
  });

  let debuggedInput = debugTree(input, `${name}:input`);

  let compiledTemplatesAndTypescript = new GlimmerTemplatePrecompiler(debuggedInput, {
    persist: true,
    glimmer: require('@glimmer/compiler'),
    annotation: `${name} templates -> es`,
  });

  let debuggedCompiledTemplatesAndTypeScript = debugTree(
    compiledTemplatesAndTypescript,
    `${name}:templates-output`
  );

  let nonTypeScriptContents = new Funnel(debuggedCompiledTemplatesAndTypeScript, {
    srcDir: 'packages',
    exclude: ['**/*.ts'],
  });

  let typescriptContents = new Funnel(debuggedCompiledTemplatesAndTypeScript, {
    include: ['**/*.ts'],
  });

  let typescriptCompiled = typescript(debugTree(typescriptContents, `${name}:ts:input`));

  let debuggedCompiledTypescript = debugTree(typescriptCompiled, `${name}:ts:output`);

  let mergedFinalOutput = new MergeTrees([nonTypeScriptContents, debuggedCompiledTypescript], {
    overwrite: true,
  });

  return debugTree(mergedFinalOutput, `${name}:output`);
};

module.exports.rollupEmberGlimmerES = function(emberGlimmerES) {
  return new Rollup(emberGlimmerES, {
    annotation: 'ember-glimmer',
    rollup: {
      external: [
        '@glimmer/reference',
        '@glimmer/runtime',
        '@glimmer/node',
        '@glimmer/opcode-compiler',
        '@glimmer/program',
        '@glimmer/wire-format',
        '@glimmer/util',
        'ember-console',
        'ember-debug',
        'ember-env-flags',
        'ember/features',
        'ember-environment',
        'ember-utils',
        'ember-metal',
        'ember-runtime',
        'ember-views',
        'ember-routing',
        'node-module',
        'rsvp',
        'container',
      ],
      input: 'ember-glimmer/index.js',
      output: {
        file: 'ember-glimmer.js',
        format: 'es',
        exports: 'named',
      },
    },
  });
};

module.exports.handlebarsES = function _handlebars() {
  return new Rollup(findLib('handlebars', 'lib'), {
    annotation: 'handlebars',
    rollup: {
      input: 'handlebars/compiler/base.js',
      output: {
        file: 'handlebars.js',
        format: 'es',
        exports: 'named',
      },
      plugins: [handlebarsFix()],
    },
  });
};

function handlebarsFix() {
  var HANDLEBARS_PARSER = /[\/\\]parser.js$/;
  return {
    load: function(id) {
      if (HANDLEBARS_PARSER.test(id)) {
        var code = readFileSync(id, 'utf8');
        return {
          code: code
            .replace('exports.__esModule = true;', '')
            .replace("exports['default'] = handlebars;", 'export default handlebars;'),

          map: { mappings: null },
        };
      }
    },
  };
}

module.exports.rsvpES = function _rsvpES() {
  let lib = path.resolve(path.dirname(require.resolve('rsvp')), '../lib');
  return new Rollup(lib, {
    annotation: 'rsvp.js',
    rollup: {
      input: 'rsvp.js',
      output: {
        file: 'rsvp.js',
        format: 'es',
        exports: 'named',
      },
    },
  });
};

module.exports.backburnerES = function _backburnerES() {
  return funnelLib('backburner.js', 'dist/es6', {
    files: ['backburner.js'],
    annotation: 'backburner es',
  });
};

module.exports.dagES = function _dagES() {
  let lib = funnelLib('dag-map', {
    files: ['dag-map.js'],
    annotation: 'dag-map es',
  });

  return new StringReplace(lib, {
    files: ['dag-map.js'],
    patterns: [
      {
        match: /\/\/# sourceMappingURL=dag-map.js.map/g,
        replacement: '',
      },
    ],
    annotation: 'remove sourcemap annotation (dag-map)',
  });
};

module.exports.routeRecognizerES = function _routeRecognizerES() {
  return funnelLib('route-recognizer', {
    files: ['route-recognizer.es.js'],
    getDestinationPath() {
      return 'route-recognizer.js';
    },
    annotation: 'route-recognizer es',
  });
};

module.exports.simpleHTMLTokenizerES = function _simpleHTMLTokenizerES() {
  let packageInfo = findPackage('simple-html-tokenizer', '@glimmer/syntax');
  let moduleInfo = packageInfo.module;
  return new Rollup(moduleInfo.dir, {
    annotation: 'simple-html-tokenizer es',
    rollup: {
      input: moduleInfo.base,
      output: {
        file: 'simple-html-tokenizer.js',
        format: 'es',
        exports: 'named',
      },
    },
  });
};

module.exports.emberPkgES = function _emberPkgES(name, rollup, externs) {
  if (rollup) {
    return new Rollup(`packages/${name}`, {
      annotation: `rollup ${name}`,
      rollup: {
        input: 'index.js',
        external: externs,
        output: {
          file: `${name}.js`,
          format: 'es',
          exports: 'named',
        },
      },
    });
  }

  return new Funnel(`packages/${name}`, {
    exclude: ['.gitkeep', '**/*.d.ts', 'tests'],
    destDir: name,
    annotation: `${name} es`,
  });
};

const glimmerTrees = new Map();

function rollupGlimmerPackage(pkg) {
  let name = pkg.name;
  let tree = glimmerTrees.get(name);
  if (tree === undefined) {
    tree = new Rollup(pkg.module.dir, {
      rollup: {
        input: pkg.module.base,
        external: pkg.dependencies,
        output: {
          file: name + '.js',
          format: 'es',
        },
      },
      annotation: name,
    });
    glimmerTrees.set(name, tree);
  }
  return tree;
}

module.exports.glimmerPkgES = function glimmerPkgES(name) {
  return rollupGlimmerPackage(findPackage(name));
};

module.exports.glimmerTrees = function glimmerTrees(entries) {
  let seen = new Set();

  // glimmer runtime has dependency on this even though it is only in tests
  seen.add('@glimmer/object');
  seen.add('@glimmer/object-reference');

  let trees = [];
  let queue = Array.isArray(entries) ? entries.slice() : [entries];
  let name;
  while ((name = queue.pop()) !== undefined) {
    if (seen.has(name)) {
      continue;
    }
    seen.add(name);

    if (!name.startsWith('@glimmer/')) {
      continue;
    }

    let pkg = findPackage(name);

    if (pkg.module && existsSync(pkg.module.path)) {
      trees.push(rollupGlimmerPackage(pkg));
    }

    let dependencies = pkg.dependencies;
    if (dependencies) {
      queue.push(...dependencies);
    }
  }
  return trees;
};

module.exports.emberTestsES = function _emberTestES(name) {
  return new Funnel(`packages/${name}/tests`, {
    exclude: ['.gitkeep'],
    destDir: `${name}/tests`,
    annotation: `${name} tests es`,
  });
};

module.exports.nodeModuleUtils = function _nodeModuleUtils() {
  return new Funnel('packages/node-module/lib', {
    files: ['node-module.js'],
  });
};

module.exports.emberVersionES = function _emberVersionES() {
  let content = 'export default ' + JSON.stringify(VERSION) + ';\n';
  return new WriteFile('ember/version.js', content, {
    annotation: 'ember/version',
  });
};

module.exports.buildEmberEnvFlagsES = function(flags) {
  let content = '';
  for (let key in flags) {
    content += `\nexport const ${key} = ${flags[key]};`;
  }

  return new WriteFile('ember-env-flags.js', content, {
    annotation: 'ember-env-flags',
  });
};

module.exports.emberLicense = function _emberLicense() {
  let license = new Funnel('generators', {
    files: ['license.js'],
    annotation: 'license',
  });

  return new StringReplace(license, {
    files: ['license.js'],
    patterns: [
      {
        match: VERSION_PLACEHOLDER,
        replacement: VERSION,
      },
    ],
    annotation: 'license',
  });
};

module.exports.emberFeaturesES = function _emberFeaturesES(production = false) {
  let FEATURES = production ? RELEASE : DEBUG;
  let content = stripIndent`
    import { ENV } from 'ember-environment';
    import { assign } from 'ember-utils';
    export const DEFAULT_FEATURES = ${JSON.stringify(FEATURES)};
    export const FEATURES = assign(DEFAULT_FEATURES, ENV.FEATURES);

    ${Object.keys(toConst(FEATURES))
      .map(FEATURE => {
        return `export const ${FEATURE} = FEATURES["${FEATURE.replace(/_/g, '-').toLowerCase()}"];`;
      })
      .join('\n')}
  `;

  return new WriteFile('ember/features.js', content, {
    annotation: `ember/features ${production ? 'production' : 'debug'}`,
  });
};

module.exports.nodeTests = function _nodeTests() {
  return new Funnel('tests', {
    include: ['**/*/*.js'],
  });
};

module.exports.rollupEmberMetal = function _rollupEmberMetal(tree, options) {
  options = Object.assign({ transformModules: false, annotation: 'ember metal' }, options);
  let emberMetalES5 = toES5(tree, options);
  return toES5(
    new Rollup(emberMetalES5, {
      annotation: `rollup ember-metal`,
      rollup: {
        input: `index.js`,
        output: {
          amd: { id: 'ember-metal' },
          file: 'ember-metal.js',
          format: 'amd',
          exports: 'named',
        },
        external: [
          'node-module',
          'ember-babel',
          'ember-debug',
          'ember-environment',
          'ember-utils',
          '@glimmer/reference',
          'require',
          'backburner',
          'ember-console',
          'ember-env-flags',
          'ember/features',
        ],
      },
    }),
    { transformDefine: true }
  );
};
<commit_msg>Remove unused build support code.<commit_after>'use strict';

const { readFileSync, existsSync } = require('fs');
const path = require('path');
const Rollup = require('broccoli-rollup');
const Funnel = require('broccoli-funnel');
const MergeTrees = require('broccoli-merge-trees');
const typescript = require('broccoli-typescript-compiler').typescript;
const BroccoliDebug = require('broccoli-debug');
const findLib = require('./find-lib');
const findPackage = require('./find-package');
const funnelLib = require('./funnel-lib');
const { VERSION } = require('./version');
const WriteFile = require('broccoli-file-creator');
const StringReplace = require('broccoli-string-replace');
const { RELEASE, DEBUG, toConst } = require('./features');
const GlimmerTemplatePrecompiler = require('./glimmer-template-compiler');
const VERSION_PLACEHOLDER = /VERSION_STRING_PLACEHOLDER/g;
const { stripIndent } = require('common-tags');
const toES5 = require('./to-es5');

const debugTree = BroccoliDebug.buildDebugCallback('ember-source');

module.exports.routerES = function _routerES() {
  return new Rollup(findLib('router_js'), {
    rollup: {
      external: ['route-recognizer', 'rsvp'],
      input: 'index.js',
      output: {
        file: 'router.js',
        format: 'es',
      },
    },
    annotation: 'router.js',
  });
};

module.exports.jquery = function _jquery() {
  return new Funnel(findLib('jquery'), {
    files: ['jquery.js'],
    destDir: 'jquery',
    annotation: 'jquery',
  });
};

module.exports.internalLoader = function _internalLoader() {
  return new Funnel('packages/loader/lib', {
    files: ['index.js'],
    getDestinationPath() {
      return 'loader.js';
    },
    annotation: 'internal loader',
  });
};

module.exports.qunit = function _qunit() {
  return new Funnel(findLib('qunit'), {
    files: ['qunit.js', 'qunit.css'],
    destDir: 'qunit',
    annotation: 'qunit',
  });
};

module.exports.getPackagesES = function getPackagesES() {
  let input = new Funnel(`packages`, {
    exclude: ['node-module/**', 'loader/**', 'external-helpers/**'],
    destDir: `packages`,
  });

  let debuggedInput = debugTree(input, `get-packages-es:input`);

  let compiledTemplatesAndTypescript = new GlimmerTemplatePrecompiler(debuggedInput, {
    persist: true,
    glimmer: require('@glimmer/compiler'),
    annotation: `get-packages-es templates -> es`,
  });

  let debuggedCompiledTemplatesAndTypeScript = debugTree(
    compiledTemplatesAndTypescript,
    `get-packages-es:templates-output`
  );

  let nonTypeScriptContents = new Funnel(debuggedCompiledTemplatesAndTypeScript, {
    srcDir: 'packages',
    exclude: ['**/*.ts'],
  });

  let typescriptContents = new Funnel(debuggedCompiledTemplatesAndTypeScript, {
    include: ['**/*.ts'],
  });

  let typescriptCompiled = typescript(debugTree(typescriptContents, `get-packages-es:ts:input`));

  let debuggedCompiledTypescript = debugTree(typescriptCompiled, `get-packages-es:ts:output`);

  let mergedFinalOutput = new MergeTrees([nonTypeScriptContents, debuggedCompiledTypescript], {
    overwrite: true,
  });

  return debugTree(mergedFinalOutput, `get-packages-es:output`);
};

module.exports.handlebarsES = function _handlebars() {
  return new Rollup(findLib('handlebars', 'lib'), {
    annotation: 'handlebars',
    rollup: {
      input: 'handlebars/compiler/base.js',
      output: {
        file: 'handlebars.js',
        format: 'es',
        exports: 'named',
      },
      plugins: [handlebarsFix()],
    },
  });
};

function handlebarsFix() {
  var HANDLEBARS_PARSER = /[\/\\]parser.js$/;
  return {
    load: function(id) {
      if (HANDLEBARS_PARSER.test(id)) {
        var code = readFileSync(id, 'utf8');
        return {
          code: code
            .replace('exports.__esModule = true;', '')
            .replace("exports['default'] = handlebars;", 'export default handlebars;'),

          map: { mappings: null },
        };
      }
    },
  };
}

module.exports.rsvpES = function _rsvpES() {
  let lib = path.resolve(path.dirname(require.resolve('rsvp')), '../lib');
  return new Rollup(lib, {
    annotation: 'rsvp.js',
    rollup: {
      input: 'rsvp.js',
      output: {
        file: 'rsvp.js',
        format: 'es',
        exports: 'named',
      },
    },
  });
};

module.exports.backburnerES = function _backburnerES() {
  return funnelLib('backburner.js', 'dist/es6', {
    files: ['backburner.js'],
    annotation: 'backburner es',
  });
};

module.exports.dagES = function _dagES() {
  let lib = funnelLib('dag-map', {
    files: ['dag-map.js'],
    annotation: 'dag-map es',
  });

  return new StringReplace(lib, {
    files: ['dag-map.js'],
    patterns: [
      {
        match: /\/\/# sourceMappingURL=dag-map.js.map/g,
        replacement: '',
      },
    ],
    annotation: 'remove sourcemap annotation (dag-map)',
  });
};

module.exports.routeRecognizerES = function _routeRecognizerES() {
  return funnelLib('route-recognizer', {
    files: ['route-recognizer.es.js'],
    getDestinationPath() {
      return 'route-recognizer.js';
    },
    annotation: 'route-recognizer es',
  });
};

module.exports.simpleHTMLTokenizerES = function _simpleHTMLTokenizerES() {
  let packageInfo = findPackage('simple-html-tokenizer', '@glimmer/syntax');
  let moduleInfo = packageInfo.module;
  return new Rollup(moduleInfo.dir, {
    annotation: 'simple-html-tokenizer es',
    rollup: {
      input: moduleInfo.base,
      output: {
        file: 'simple-html-tokenizer.js',
        format: 'es',
        exports: 'named',
      },
    },
  });
};

const glimmerTrees = new Map();

function rollupGlimmerPackage(pkg) {
  let name = pkg.name;
  let tree = glimmerTrees.get(name);
  if (tree === undefined) {
    tree = new Rollup(pkg.module.dir, {
      rollup: {
        input: pkg.module.base,
        external: pkg.dependencies,
        output: {
          file: name + '.js',
          format: 'es',
        },
      },
      annotation: name,
    });
    glimmerTrees.set(name, tree);
  }
  return tree;
}

module.exports.glimmerTrees = function glimmerTrees(entries) {
  let seen = new Set();

  // glimmer runtime has dependency on this even though it is only in tests
  seen.add('@glimmer/object');
  seen.add('@glimmer/object-reference');

  let trees = [];
  let queue = Array.isArray(entries) ? entries.slice() : [entries];
  let name;
  while ((name = queue.pop()) !== undefined) {
    if (seen.has(name)) {
      continue;
    }
    seen.add(name);

    if (!name.startsWith('@glimmer/')) {
      continue;
    }

    let pkg = findPackage(name);

    if (pkg.module && existsSync(pkg.module.path)) {
      trees.push(rollupGlimmerPackage(pkg));
    }

    let dependencies = pkg.dependencies;
    if (dependencies) {
      queue.push(...dependencies);
    }
  }
  return trees;
};

module.exports.nodeModuleUtils = function _nodeModuleUtils() {
  return new Funnel('packages/node-module/lib', {
    files: ['node-module.js'],
  });
};

module.exports.emberVersionES = function _emberVersionES() {
  let content = 'export default ' + JSON.stringify(VERSION) + ';\n';
  return new WriteFile('ember/version.js', content, {
    annotation: 'ember/version',
  });
};

module.exports.buildEmberEnvFlagsES = function(flags) {
  let content = '';
  for (let key in flags) {
    content += `\nexport const ${key} = ${flags[key]};`;
  }

  return new WriteFile('ember-env-flags.js', content, {
    annotation: 'ember-env-flags',
  });
};

module.exports.emberLicense = function _emberLicense() {
  let license = new Funnel('generators', {
    files: ['license.js'],
    annotation: 'license',
  });

  return new StringReplace(license, {
    files: ['license.js'],
    patterns: [
      {
        match: VERSION_PLACEHOLDER,
        replacement: VERSION,
      },
    ],
    annotation: 'license',
  });
};

module.exports.emberFeaturesES = function _emberFeaturesES(production = false) {
  let FEATURES = production ? RELEASE : DEBUG;
  let content = stripIndent`
    import { ENV } from 'ember-environment';
    import { assign } from 'ember-utils';
    export const DEFAULT_FEATURES = ${JSON.stringify(FEATURES)};
    export const FEATURES = assign(DEFAULT_FEATURES, ENV.FEATURES);

    ${Object.keys(toConst(FEATURES))
      .map(FEATURE => {
        return `export const ${FEATURE} = FEATURES["${FEATURE.replace(/_/g, '-').toLowerCase()}"];`;
      })
      .join('\n')}
  `;

  return new WriteFile('ember/features.js', content, {
    annotation: `ember/features ${production ? 'production' : 'debug'}`,
  });
};

module.exports.nodeTests = function _nodeTests() {
  return new Funnel('tests', {
    include: ['**/*/*.js'],
  });
};
<|endoftext|>


<commit_before>if (!cbus.hasOwnProperty("server")) { cbus.server = {} }

(function() {
  cbus.server.generateOPML = function(feeds, callback) {
    /* create the document */

    let doc = document.implementation.createDocument(null, "opml");
    let root = doc.children[0];

    let head = document.createElement("head");
    let title = document.createElement("title");
    title.textContent = "CPod feeds";
    head.appendChild(title);
    root.appendChild(head);

    let body = document.createElement("body");
    let outlineParent = document.createElement("outline");
    outlineParent.setAttribute("text", "feeds");
    for (let i = 0, l = feeds.length; i < l; i++) {
      let outlineChild = document.createElement("outline");
      outlineChild.setAttribute("type", "rss");
      outlineChild.setAttribute("text", feeds[i].title);
      outlineChild.setAttribute("xmlUrl", feeds[i].url);
      outlineParent.appendChild(outlineChild);
    }
    body.appendChild(outlineParent);
    root.appendChild(body);

    let serialized = new XMLSerializer().serializeToString(doc);

    /* save the document */

    function savedCallback(err) {
      if (err) {
        remote.dialog.showErrorBox(i18n.__("dialog_opml-save-error_title"), i18n.__("dialog_opml-save-error_body"));
      }
    }

    remote.dialog.showSaveDialog(cbus.ui.browserWindow, {
      defaultPath: `${APP_NAME.toLowerCase()}_opml_export.opml`
    }, function(filename) {
      fs.writeFile(filename, serialized, savedCallback);
    });
  };
}())
<commit_msg>Fix OPML generation<commit_after>if (!cbus.hasOwnProperty("server")) { cbus.server = {} }

(function() {
  cbus.server.generateOPML = function(feeds, callback) {
    /* create the document */

    let doc = document.implementation.createDocument("http://www.w3.org/1999/xhtml", "opml");
    let root = doc.children[0];

    let head = doc.createElement("head");
    let title = doc.createElement("title");
    title.textContent = "CPod feeds";
    head.appendChild(title);
    root.appendChild(head);

    let body = doc.createElement("body");
    let outlineParent = doc.createElement("outline");
    outlineParent.setAttribute("text", "feeds");
    for (let i = 0, l = feeds.length; i < l; i++) {
      let outlineChild = doc.createElement("outline");
      outlineChild.setAttribute("type", "rss");
      outlineChild.setAttribute("text", feeds[i].title);
      outlineChild.setAttribute("xmlUrl", feeds[i].url);
      outlineParent.appendChild(outlineChild);
    }
    body.appendChild(outlineParent);
    root.appendChild(body);

    let serialized = new XMLSerializer().serializeToString(doc);

    /* save the document */

    function savedCallback(err) {
      if (err) {
        remote.dialog.showErrorBox(i18n.__("dialog_opml-save-error_title"), i18n.__("dialog_opml-save-error_body"));
      }
    }

    remote.dialog.showSaveDialog(cbus.ui.browserWindow, {
      defaultPath: `${APP_NAME.toLowerCase()}_opml_export.opml`
    }, function(filename) {
      fs.writeFile(filename, serialized, savedCallback);
    });
  };
}())
<|endoftext|>


<commit_before>if typeof process isnt 'undefined' and process.execPath and process.execPath.match /node|iojs/
  chai = require 'chai' unless chai
  noflo = require '../src/lib/NoFlo'
  path = require('path')
  browser = false
else
  noflo = require 'noflo'
  browser = true

describe 'NoFlo interface', ->
  it 'should be able to tell whether it is running on browser', ->
    chai.expect(noflo.isBrowser()).to.equal browser
    return
  describe 'working with graph files', ->
    targetPath = null
    before ->
      # These features only work on Node.js
      if noflo.isBrowser()
        @skip()
        return
      targetPath = path.resolve __dirname, 'tmp.json'
      return
    after (done) ->
      if noflo.isBrowser()
        done()
        return
      fs = require 'fs'
      fs.unlink targetPath, done
      return
    it 'should be able to save a graph file', (done) ->
      graph = new noflo.Graph
      graph.addNode 'G', 'Graph'
      noflo.saveFile graph, targetPath, done
      return
    it 'should be able to load a graph file', (done) ->
      noflo.loadFile targetPath,
        baseDir: process.cwd()
        delay: true
      , (err, network) ->
        if err
          done err
          return
        chai.expect(network.isRunning()).to.equal false
        done()
        return
      return
    return
  return
<commit_msg>decaffeinate: Convert NoFlo.coffee to JS<commit_after>let browser, chai, noflo, path;
if ((typeof process !== 'undefined') && process.execPath && process.execPath.match(/node|iojs/)) {
  if (!chai) { chai = require('chai'); }
  noflo = require('../src/lib/NoFlo');
  path = require('path');
  browser = false;
} else {
  noflo = require('noflo');
  browser = true;
}

describe('NoFlo interface', function() {
  it('should be able to tell whether it is running on browser', function() {
    chai.expect(noflo.isBrowser()).to.equal(browser);
  });
  describe('working with graph files', function() {
    let targetPath = null;
    before(function() {
      // These features only work on Node.js
      if (noflo.isBrowser()) {
        this.skip();
        return;
      }
      targetPath = path.resolve(__dirname, 'tmp.json');
    });
    after(function(done) {
      if (noflo.isBrowser()) {
        done();
        return;
      }
      const fs = require('fs');
      fs.unlink(targetPath, done);
    });
    it('should be able to save a graph file', function(done) {
      const graph = new noflo.Graph;
      graph.addNode('G', 'Graph');
      noflo.saveFile(graph, targetPath, done);
    });
    it('should be able to load a graph file', function(done) {
      noflo.loadFile(targetPath, {
        baseDir: process.cwd(),
        delay: true
      }
      , function(err, network) {
        if (err) {
          done(err);
          return;
        }
        chai.expect(network.isRunning()).to.equal(false);
        done();
      });
    });
  });
});
<|endoftext|>


<commit_before>//Single Car Controller
angular.module('myApp').controller('singleCarCtrl', function ($scope, $http, $routeParams, $location, porsche) {
   //grab data
    var url_ID = $routeParams.id;
    porsche.single(url_ID).success(function (data) {
        $scope.car = data.stock;
    })
    //code required for angular toggle of hidden content to slide down
    $scope.hiddenDiv = false;
    $scope.showDiv = function () {
        $scope.hiddenDiv = !$scope.hiddenDiv;
    };
    // On click of 'place bet' button, run the following function to post and save bet
    $scope.update = function () {
        var id = JSON.stringify($scope.car._id),
            model = JSON.stringify($scope.car.model),
            mileage = $scope.car.mileage,
            owners = $scope.car.owners,
            year = $scope.car.year,
            transmission = JSON.stringify($scope.car.transmission),
            engine = $scope.car.engine,
            image = JSON.stringify($scope.car.image),
            price = $scope.car.price,
            sold = $scope.car.sold,
            fuel = JSON.stringify($scope.car.fuel),
            colour = JSON.stringify($scope.car.colour),
            location = JSON.stringify($scope.car.location),
            interior = JSON.stringify($scope.car.interior),

            carInfo = '{"_id":' + id + ', "model":' + model + ', "mileage":' + mileage + ', "owners":' + owners + ', "year":' + year + ', "transmission":' + transmission + ', "engine":' + engine + ', "image":' + image + ', "price":' + price + ', "sold":' + sold + ', "fuel":' + fuel + ', "colour":' + colour + ', "location":' + location + ', "interior":' + interior + '}',
            jsonObj = JSON.parse(carInfo);
        porsche.edit(url_ID, jsonObj).success(function (data, status) {
            $scope.ServerResponse = data;
            $scope.updated = true;
            $location.url('/admin/updated');
        }).error(function (data, status) {
            $scope.ServerResponse = data;
            $scope.updated = false;
        });
    };
});<commit_msg>Update singleCarCtrl.js<commit_after>//Single Car Controller
angular.module('myApp').controller('singleCarCtrl', function ($scope, $http, $routeParams, $location, porsche) {
   //grab data
    var url_ID = $routeParams.id;
    porsche.single(url_ID).success(function (data) {
        $scope.car = data.stock;
    })
    //code required for angular toggle of hidden content to slide down
    $scope.hiddenDiv = false;
    $scope.showDiv = function () {
        $scope.hiddenDiv = !$scope.hiddenDiv;
    };
    // On click of update button, run the following function to PUT and update record
    $scope.update = function () {
       /* Retrieve existing stored data from car object as data is bring updated not added */
        var id = JSON.stringify($scope.car._id),
            model = JSON.stringify($scope.car.model),
            mileage = $scope.car.mileage,
            owners = $scope.car.owners,
            year = $scope.car.year,
            transmission = JSON.stringify($scope.car.transmission),
            engine = $scope.car.engine,
            image = JSON.stringify($scope.car.image),
            price = $scope.car.price,
            sold = $scope.car.sold,
            fuel = JSON.stringify($scope.car.fuel),
            colour = JSON.stringify($scope.car.colour),
            location = JSON.stringify($scope.car.location),
            interior = JSON.stringify($scope.car.interior),

            carInfo = '{"_id":' + id + ', "model":' + model + ', "mileage":' + mileage + ', "owners":' + owners + ', "year":' + year + ', "transmission":' + transmission + ', "engine":' + engine + ', "image":' + image + ', "price":' + price + ', "sold":' + sold + ', "fuel":' + fuel + ', "colour":' + colour + ', "location":' + location + ', "interior":' + interior + '}',
            jsonObj = JSON.parse(carInfo);
       // PUT service
        porsche.edit(url_ID, jsonObj).success(function (data, status) {
           // Save response and save a variable for success
            $scope.ServerResponse = data;
            $scope.updated = true;
            // redirect on success
            $location.url('/admin/updated');
        }).error(function (data, status) {
           // Save response and variable for unsuccessful update
            $scope.ServerResponse = data;
            $scope.updated = false;
        });
    };
});
<|endoftext|>


<commit_before>// CalendarDateSelect - a small prototype based date picker
// Version 1.0
// Questions, comments, bugs? - email the Author - Tim Harper <"timseeharper@gmail.seeom".gsub("see", "c")>
Element.addMethods({
  purgeChildren: function(element) {
    $A(element.childNodes).each(function(e){$(e).remove();});
  },
  build: function(element, type, options, style) {
    newElement = Element.build(type, options, style);
    element.appendChild(newElement);
    return newElement;
  }
});

Element.build = function(type, options, style)
{
  e = $(document.createElement(type));

  $H(options).each(function(pair) {
    eval("e." + pair.key + " = pair.value" );
  });

  if (style) $H(style).each(function(pair) {
    eval("e.style." + pair.key + " = pair.value" );
  });

  return e;
};
nil=null;

CalendarDateSelect = Class.create();
CalendarDateSelect.weekdays = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'];
CalendarDateSelect.months = $w("January February March April May June July August September October November December" );
CalendarDateSelect.same_month = function(a,b) { return ( (a.getMonth()==b.getMonth()) && (a.getFullYear()==b.getFullYear()) ) }
CalendarDateSelect.same_day = function(a,b) { return ( (a.getDate()==b.getDate()) && (a.getMonth()==b.getMonth()) && (a.getFullYear()==b.getFullYear()) ) }
CalendarDateSelect.padded2 = function(hour) { padded2 = hour.toString(); if (parseInt(hour) < 10) padded2="0" + padded2; return padded2; }
CalendarDateSelect.ampm = function(hour) { return (hour < 12) ? "AM" : "PM"; }
CalendarDateSelect.ampm_hour = function(hour) { return (hour == 0) ? 12 : (hour > 12 ? hour - 12 : hour ) }
CalendarDateSelect.date_string = function(date, time){
  if (! date) return "";
  str = "";
  str += CalendarDateSelect.months[date.getMonth()] + " ";
  str += date.getDate().toString() + ", ";
  str += date.getFullYear().toString();

  if (time)
  {
    str += " ";
    hour = date.getHours();

    str += CalendarDateSelect.ampm_hour(hour).toString() +
           ":" + CalendarDateSelect.padded2( date.getMinutes() ) +
           " " + CalendarDateSelect.ampm(hour)
  }
  return str;
}

CalendarDateSelect.prototype = {
  initialize: function(target_element, options) {
    // initialize the date control
    this.options = $H({
      embedded: false,
      time: false,
      year_range: 10,
      calendar_div: nil,
      close_on_click: nil,
      minute_interval: 5
    }).merge(options || {});

    this.target_element = $(target_element); // make sure it's an element, not a string
    this.selection_made = $F(this.target_element)!="";

    if (this.target_element.calendar_date_select)
    {
      this.target_element.calendar_date_select.close();
      return false;
    }
    this.target_element.calendar_date_select = this;

    this.calendar_div = $(this.options['calendar_div']);
    if (!this.target_element) { alert("Target element " + target_element + " not found!"); return false;}

    this.parse_date();

    // by default, stick it by the target element (if embedded, that's where we'll want it to show up)
    if (this.calendar_div == nil) { this.calendar_div = $( this.options.embedded ? this.target_element.parentNode : document.body ).build('div'); }
    if (!this.options.embedded) {
      this.calendar_div.style.position = "absolute";
      pos = Position.cumulativeOffset(this.target_element);

      this.calendar_div.style.left = pos[0].toString() + "px";
      this.calendar_div.style.top = (pos[1] + this.target_element.getDimensions().height ).toString() + "px";
    }

    this.calendar_div.addClassName("calendar_date_select");

    if (this.options["embedded"]) this.options["close_on_click"]=false;
    // logic for close on click
    if (this.options['close_on_click']===nil )
    {
      if (this.options['time'])
        this.options["close_on_click"] = false;
      else
        this.options['close_on_click'] = true;
    }

    this.init_frame();
  },
  init_frame: function() {
    that=this;
    // create the divs
    $w("header body time buttons footer").each(function(name) {
      eval(name + "_div = that." + name + "_div = that.calendar_div.build('div', { className: '"+name+"' }, { clear: 'left'} ); ");
    });

    this.init_time_div();
    this.init_buttons_div();
    this.footer_div.update(" ");
    // make the header buttons
    this.prev_month_button = header_div.build("button", { innerHTML : "<", type: "button"});
    this.month_select = header_div.build("select");
    this.year_select = header_div.build("select");
    this.next_month_button = header_div.build("button", { innerHTML : ">", type: "button"});

    // make the month selector
    for(x=0; x<12; x++)
      this.month_select.options[x]=new Option(CalendarDateSelect.months[x],x);

    Event.observe(this.prev_month_button, 'click', (function () { this.nav_month(-1) }).bindAsEventListener(this));
    Event.observe(this.next_month_button, 'click', (function () { this.nav_month(1) }).bindAsEventListener(this));
    Event.observe(this.month_select, 'change', (function () { this.set_month($F(this.month_select)) }).bindAsEventListener(this));
    Event.observe(this.year_select, 'change', (function () { this.set_year($F(this.year_select)) }).bindAsEventListener(this));

    this.refresh();
  },
  init_buttons_div: function()
  {
    buttons_div = this.buttons_div;

    buttons_div.build("button", {
      innerHTML: (this.options["time"] ? "Now" : "Today" ),
      onclick: this.today.bindAsEventListener(this),
      type: "button"
    });
    if (this.allow_close_buttons())
    {
      buttons_div.build("button", {
        innerHTML: "Ok",
        onclick: this.ok.bindAsEventListener(this),
        type: "button"
      });
      buttons_div.build("button", {
        innerHTML: "Cancel",
        onclick: this.close.bindAsEventListener(this),
        type: "button"
      });
    }
  },
  init_time_div: function()
  {
    time_div = this.time_div;
    // make the time div
    if (this.options["time"])
    {
      time_div.build("span", {innerHTML:" @ "})
      this.hour_select = time_div.build("select", {
        calendar_date_select: this,
        onchange: function() { this.calendar_date_select.select_day( { hour: this.value });}
      });
      time_div.build("span", {innerHTML:"  : "});
      this.minute_select = time_div.build("select", {
        calendar_date_select: this,
        onchange: function() { this.calendar_date_select.select_day( {minute: this.value }) }
      });

      // populate hours
      for(x=0;x<=23;x++) { this.hour_select.options[x] = new Option( CalendarDateSelect.ampm_hour(x).toString() + " " + CalendarDateSelect.ampm(x), x ) }
      // populate minutes
      x=0; for(m=0;m<=60;m+=this.options["minute_interval"]) { this.minute_select.options[x++] = new Option( CalendarDateSelect.padded2(m), m ) }
    } else (time_div.remove());
  },
  allow_close_buttons: function() { return ( !this.options["embedded"]); },
  nav_month: function(dir) {
    this.set_month(this.date.getMonth() + dir )
  },
  date_string: function() {
    return (this.selection_made) ? CalendarDateSelect.date_string(this.selectedDate, this.options['time']) : " ";
  },
  set_month: function(month) {
    prev_day = this.date.getDate();
    // do it twice to force the month if the date is out of range
    this.date.setMonth(month);
    this.date.setMonth(month);

    if (this.date.getDate()!=prev_day ) this.date.setDate(28);

    this.refresh();
  },
  set_year: function(year) {
    this.date.setYear(year);
    this.refresh();
  },
  refresh: function ()
  {
    // set the month
    this.month_select.selectedIndex = this.date.getMonth();

    // set the year,
    range=this.options["year_range"];
    this.year_select.purgeChildren();
    for( x=0; x<=range*2; x++)
    {
      year = x+(this.date.getFullYear() - range);
      this.year_select.options[x]=new Option(year,year);
    }
    this.year_select.selectedIndex=range;

    // make the calendar!!
    (body_div=this.body_div).purgeChildren();
    days_table = body_div.build("table", { cellPadding: "0px", cellSpacing: "0px", width: "100%" }).build("tbody");

    // make the weekdays!
    weekdays_row = days_table.build("tr", {className: "weekdays"});

    CalendarDateSelect.weekdays.each( function(weekday) {
      weekdays_row.build("td", {innerHTML: weekday});
    });

    // Make the days!
    days_row = days_table.build("tr", {className: "days"});
    iterator = new Date(this.date);

    pre_days = iterator.getDay() // draw some days before the fact
    if (pre_days < 3) pre_days+=7;
    iterator.setDate(1 - pre_days);
    cells_to_render = 42;
    cell_index = 0;
    today = new Date();

    do {
      day = iterator.getDate();
      day_td = days_row.build("td", {
          innerHTML: day,
          day: day,
          month: iterator.getMonth(),
          year: iterator.getFullYear(),
          calendar_date_select: this,
          className: (CalendarDateSelect.same_day(iterator, today) ? "today " : "") + (iterator.getMonth() == this.date.getMonth() ? "" : "other") ,
          onmouseover: function () { this.calendar_date_select.day_hover(this); },
          onmouseout: function () { this.calendar_date_select.day_hover_out(this) },
          onclick: function() { this.calendar_date_select.select_day(this); }
        },
        { cursor: "pointer" }
      );
      iterator.setDate( day + 1);
      cell_index++;
      if ( cell_index %7==0 ) days_row = days_table.build("tr", {className: "days"});
    } while ( cells_to_render > cell_index );

    // set the time
    if (this.options["time"]) {
      this.hour_select.selectedIndex = this.selectedDate.getHours();
      this.minute_select.selectedIndex = this.selectedDate.getMinutes() / this.options["minute_interval"];

      this.hour_select.onchange();
      this.minute_select.onchange();

    }

    this.set_selected_class();
    this.update_footer();
  },
  day_hover: function(element) {
    element.addClassName("hover");
    hover_date = new Date(this.selectedDate);
    hover_date.setYear(element.year); hover_date.setMonth(element.month); hover_date.setDate(element.day);
    this.footer_div.update(CalendarDateSelect.date_string(hover_date, this.options['time']));
  },
  day_hover_out: function(element) { element.removeClassName("hover"); this.update_footer();},
  update_footer: function() { this.footer_div.update(this.date_string()); },
  set_selected_class: function() {
    // clear selection
    this.body_div.getElementsBySelector(".selected").each(function(e) { e.removeClassName("selected")});

    if (!this.selection_made) return;

    day = this.selectedDate.getDate(); month = this.selectedDate.getMonth();
    this.body_div.getElementsBySelector("td").each(function(e) { if ((e.day == day) && (e.month == month)) {e.addClassName("selected")} } );
  },
  reparse: function() { this.parse_date(); this.refresh(); },
  parse_date: function()
  {
    // try a few things to get a valid date
    this.date = new Date(this.options['date'] || $F(this.target_element));
    if (isNaN(this.date.getDate())) this.date = new Date();
    this.selectedDate = new Date(this.date);
  },
  select_day:function(parts) {
    if (parts.day) {
      this.selectedDate.setDate(parts.day);
      this.selectedDate.setMonth(parts.month);
      this.selectedDate.setYear(parts.year); //this.date.getFullYear());
      this.selection_made = true;
    }

    if (parts.hour) this.selectedDate.setHours(parts.hour);
    if (parts.minute) this.selectedDate.setMinutes(parts.minute);

    if (this.options.embedded) { this.target_element.value = this.date_string(); }
    if (this.options.close_on_click) { this.ok(); }

    this.set_selected_class();
  },
  ok: function() {
    this.target_element.value = this.date_string();
    if (this.options.onok) this.options.onok(this);
    this.close();
  },
  today: function() {
    this.selection_made=true;
    this.selectedDate = new Date();
    this.date = new Date();
    this.refresh();
  },
  close: function() {
    this.target_element.calendar_date_select = nil;
    this.calendar_div.remove();
  }
}<commit_msg>changing hour updates footer<commit_after>// CalendarDateSelect - a small prototype based date picker
// Version 1.0
// Questions, comments, bugs? - email the Author - Tim Harper <"timseeharper@gmail.seeom".gsub("see", "c")>
Element.addMethods({
  purgeChildren: function(element) {
    $A(element.childNodes).each(function(e){$(e).remove();});
  },
  build: function(element, type, options, style) {
    newElement = Element.build(type, options, style);
    element.appendChild(newElement);
    return newElement;
  }
});

Element.build = function(type, options, style)
{
  e = $(document.createElement(type));

  $H(options).each(function(pair) {
    eval("e." + pair.key + " = pair.value" );
  });

  if (style) $H(style).each(function(pair) {
    eval("e.style." + pair.key + " = pair.value" );
  });

  return e;
};
nil=null;

CalendarDateSelect = Class.create();
CalendarDateSelect.weekdays = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'];
CalendarDateSelect.months = $w("January February March April May June July August September October November December" );
CalendarDateSelect.same_month = function(a,b) { return ( (a.getMonth()==b.getMonth()) && (a.getFullYear()==b.getFullYear()) ) }
CalendarDateSelect.same_day = function(a,b) { return ( (a.getDate()==b.getDate()) && (a.getMonth()==b.getMonth()) && (a.getFullYear()==b.getFullYear()) ) }
CalendarDateSelect.padded2 = function(hour) { padded2 = hour.toString(); if (parseInt(hour) < 10) padded2="0" + padded2; return padded2; }
CalendarDateSelect.ampm = function(hour) { return (hour < 12) ? "AM" : "PM"; }
CalendarDateSelect.ampm_hour = function(hour) { return (hour == 0) ? 12 : (hour > 12 ? hour - 12 : hour ) }
CalendarDateSelect.date_string = function(date, time){
  if (! date) return "";
  str = "";
  str += CalendarDateSelect.months[date.getMonth()] + " ";
  str += date.getDate().toString() + ", ";
  str += date.getFullYear().toString();

  if (time)
  {
    str += " ";
    hour = date.getHours();

    str += CalendarDateSelect.ampm_hour(hour).toString() +
           ":" + CalendarDateSelect.padded2( date.getMinutes() ) +
           " " + CalendarDateSelect.ampm(hour)
  }
  return str;
}

CalendarDateSelect.prototype = {
  initialize: function(target_element, options) {
    // initialize the date control
    this.options = $H({
      embedded: false,
      time: false,
      year_range: 10,
      calendar_div: nil,
      close_on_click: nil,
      minute_interval: 5
    }).merge(options || {});

    this.target_element = $(target_element); // make sure it's an element, not a string
    this.selection_made = $F(this.target_element)!="";

    if (this.target_element.calendar_date_select)
    {
      this.target_element.calendar_date_select.close();
      return false;
    }
    this.target_element.calendar_date_select = this;

    this.calendar_div = $(this.options['calendar_div']);
    if (!this.target_element) { alert("Target element " + target_element + " not found!"); return false;}

    this.parse_date();

    // by default, stick it by the target element (if embedded, that's where we'll want it to show up)
    if (this.calendar_div == nil) { this.calendar_div = $( this.options.embedded ? this.target_element.parentNode : document.body ).build('div'); }
    if (!this.options.embedded) {
      this.calendar_div.style.position = "absolute";
      pos = Position.cumulativeOffset(this.target_element);

      this.calendar_div.style.left = pos[0].toString() + "px";
      this.calendar_div.style.top = (pos[1] + this.target_element.getDimensions().height ).toString() + "px";
    }

    this.calendar_div.addClassName("calendar_date_select");

    if (this.options["embedded"]) this.options["close_on_click"]=false;
    // logic for close on click
    if (this.options['close_on_click']===nil )
    {
      if (this.options['time'])
        this.options["close_on_click"] = false;
      else
        this.options['close_on_click'] = true;
    }

    this.init_frame();
  },
  init_frame: function() {
    that=this;
    // create the divs
    $w("header body time buttons footer").each(function(name) {
      eval(name + "_div = that." + name + "_div = that.calendar_div.build('div', { className: '"+name+"' }, { clear: 'left'} ); ");
    });

    this.init_time_div();
    this.init_buttons_div();
    this.footer_div.update(" ");
    // make the header buttons
    this.prev_month_button = header_div.build("button", { innerHTML : "<", type: "button"});
    this.month_select = header_div.build("select");
    this.year_select = header_div.build("select");
    this.next_month_button = header_div.build("button", { innerHTML : ">", type: "button"});

    // make the month selector
    for(x=0; x<12; x++)
      this.month_select.options[x]=new Option(CalendarDateSelect.months[x],x);

    Event.observe(this.prev_month_button, 'click', (function () { this.nav_month(-1) }).bindAsEventListener(this));
    Event.observe(this.next_month_button, 'click', (function () { this.nav_month(1) }).bindAsEventListener(this));
    Event.observe(this.month_select, 'change', (function () { this.set_month($F(this.month_select)) }).bindAsEventListener(this));
    Event.observe(this.year_select, 'change', (function () { this.set_year($F(this.year_select)) }).bindAsEventListener(this));

    this.refresh();
  },
  init_buttons_div: function()
  {
    buttons_div = this.buttons_div;

    buttons_div.build("button", {
      innerHTML: (this.options["time"] ? "Now" : "Today" ),
      onclick: this.today.bindAsEventListener(this),
      type: "button"
    });
    if (this.allow_close_buttons())
    {
      buttons_div.build("button", {
        innerHTML: "Ok",
        onclick: this.ok.bindAsEventListener(this),
        type: "button"
      });
      buttons_div.build("button", {
        innerHTML: "Cancel",
        onclick: this.close.bindAsEventListener(this),
        type: "button"
      });
    }
  },
  init_time_div: function()
  {
    time_div = this.time_div;
    // make the time div
    if (this.options["time"])
    {
      time_div.build("span", {innerHTML:" @ "})
      this.hour_select = time_div.build("select", {
        calendar_date_select: this,
        onchange: function() { this.calendar_date_select.update_selected_date( { hour: this.value });}
      });
      time_div.build("span", {innerHTML:"  : "});
      this.minute_select = time_div.build("select", {
        calendar_date_select: this,
        onchange: function() { this.calendar_date_select.update_selected_date( {minute: this.value }) }
      });

      // populate hours
      for(x=0;x<=23;x++) { this.hour_select.options[x] = new Option( CalendarDateSelect.ampm_hour(x).toString() + " " + CalendarDateSelect.ampm(x), x ) }
      // populate minutes
      x=0; for(m=0;m<=60;m+=this.options["minute_interval"]) { this.minute_select.options[x++] = new Option( CalendarDateSelect.padded2(m), m ) }
    } else (time_div.remove());
  },
  allow_close_buttons: function() { return ( !this.options["embedded"]); },
  nav_month: function(dir) {
    this.set_month(this.date.getMonth() + dir )
  },
  date_string: function() {
    return (this.selection_made) ? CalendarDateSelect.date_string(this.selectedDate, this.options['time']) : " ";
  },
  set_month: function(month) {
    prev_day = this.date.getDate();
    // do it twice to force the month if the date is out of range
    this.date.setMonth(month);
    this.date.setMonth(month);

    if (this.date.getDate()!=prev_day ) this.date.setDate(28);

    this.refresh();
  },
  set_year: function(year) {
    this.date.setYear(year);
    this.refresh();
  },
  refresh: function ()
  {
    // set the month
    this.month_select.selectedIndex = this.date.getMonth();

    // set the year,
    range=this.options["year_range"];
    this.year_select.purgeChildren();
    for( x=0; x<=range*2; x++)
    {
      year = x+(this.date.getFullYear() - range);
      this.year_select.options[x]=new Option(year,year);
    }
    this.year_select.selectedIndex=range;

    // make the calendar!!
    (body_div=this.body_div).purgeChildren();
    days_table = body_div.build("table", { cellPadding: "0px", cellSpacing: "0px", width: "100%" }).build("tbody");

    // make the weekdays!
    weekdays_row = days_table.build("tr", {className: "weekdays"});

    CalendarDateSelect.weekdays.each( function(weekday) {
      weekdays_row.build("td", {innerHTML: weekday});
    });

    // Make the days!
    days_row = days_table.build("tr", {className: "days"});
    iterator = new Date(this.date);

    pre_days = iterator.getDay() // draw some days before the fact
    if (pre_days < 3) pre_days+=7;
    iterator.setDate(1 - pre_days);
    cells_to_render = 42;
    cell_index = 0;
    today = new Date();

    do {
      day = iterator.getDate();
      day_td = days_row.build("td", {
          innerHTML: day,
          day: day,
          month: iterator.getMonth(),
          year: iterator.getFullYear(),
          calendar_date_select: this,
          className: (CalendarDateSelect.same_day(iterator, today) ? "today " : "") + (iterator.getMonth() == this.date.getMonth() ? "" : "other") ,
          onmouseover: function () { this.calendar_date_select.day_hover(this); },
          onmouseout: function () { this.calendar_date_select.day_hover_out(this) },
          onclick: function() { this.calendar_date_select.update_selected_date(this); }
        },
        { cursor: "pointer" }
      );
      iterator.setDate( day + 1);
      cell_index++;
      if ( cell_index %7==0 ) days_row = days_table.build("tr", {className: "days"});
    } while ( cells_to_render > cell_index );

    // set the time
    if (this.options["time"]) {
      this.hour_select.selectedIndex = this.selectedDate.getHours();
      this.minute_select.selectedIndex = this.selectedDate.getMinutes() / this.options["minute_interval"];

      this.hour_select.onchange();
      this.minute_select.onchange();

    }

    this.set_selected_class();
    this.update_footer();
  },
  day_hover: function(element) {
    element.addClassName("hover");
    hover_date = new Date(this.selectedDate);
    hover_date.setYear(element.year); hover_date.setMonth(element.month); hover_date.setDate(element.day);
    this.footer_div.update(CalendarDateSelect.date_string(hover_date, this.options['time']));
  },
  day_hover_out: function(element) { element.removeClassName("hover"); this.update_footer();},
  update_footer: function() { this.footer_div.update(this.date_string()); },
  set_selected_class: function() {
    // clear selection
    this.body_div.getElementsBySelector(".selected").each(function(e) { e.removeClassName("selected")});

    if (!this.selection_made) return;

    day = this.selectedDate.getDate(); month = this.selectedDate.getMonth();
    this.body_div.getElementsBySelector("td").each(function(e) { if ((e.day == day) && (e.month == month)) {e.addClassName("selected")} } );
  },
  reparse: function() { this.parse_date(); this.refresh(); },
  parse_date: function()
  {
    // try a few things to get a valid date
    this.date = new Date(this.options['date'] || $F(this.target_element));
    if (isNaN(this.date.getDate())) this.date = new Date();
    this.selectedDate = new Date(this.date);
  },
  update_selected_date:function(parts) {
    if (parts.day) {
      this.selectedDate.setDate(parts.day);
      this.selectedDate.setMonth(parts.month);
      this.selectedDate.setYear(parts.year); //this.date.getFullYear());
      this.selection_made = true;
    }

    if (parts.hour) this.selectedDate.setHours(parts.hour);
    if (parts.minute) this.selectedDate.setMinutes(parts.minute);

    if (this.options.embedded) { this.target_element.value = this.date_string(); }
    if (this.options.close_on_click) { this.ok(); }
    this.update_footer();
    this.set_selected_class();
  },
  ok: function() {
    this.target_element.value = this.date_string();
    if (this.options.onok) this.options.onok(this);
    this.close();
  },
  today: function() {
    this.selection_made=true;
    this.selectedDate = new Date();
    this.date = new Date();
    this.refresh();
  },
  close: function() {
    this.target_element.calendar_date_select = nil;
    this.calendar_div.remove();
  }
}<|endoftext|>


<commit_before>// CalendarDateSelect version 1.5.1 - a small prototype based date picker
// Questions, comments, bugs? - email the Author - Tim Harper <"timseeharper@gmail.seeom".gsub("see", "c")>
Element.addMethods({
  purgeChildren: function(element) { $A(element.childNodes).each(function(e){$(e).remove();}); },
  build: function(element, type, options, style) {
    newElement = Element.build(type, options, style);
    element.appendChild(newElement);
    return newElement;
  }
});

Element.build = function(type, options, style)
{
  e = $(document.createElement(type));
  $H(options).each(function(pair) { eval("e." + pair.key + " = pair.value" ); });
  if (style)
    $H(style).each(function(pair) { eval("e.style." + pair.key + " = pair.value" ); });
  return e;
};
nil=null;

Date.one_day = 24*60*60*1000;
Date.weekdays = $w("S M T W T F S");
Date.months = $w("January February March April May June July August September October November December" );
Date.padded2 = function(hour) { padded2 = hour.toString(); if (parseInt(hour) < 10) padded2="0" + padded2; return padded2; }
Date.prototype.getPaddedMinutes = function() { return Date.padded2(this.getMinutes()); }
Date.prototype.getAMPMHour = function() { hour=this.getHours(); return (hour == 0) ? 12 : (hour > 12 ? hour - 12 : hour ) }
Date.prototype.getAMPM = function() { return (this.getHours() < 12) ? "AM" : "PM"; }
Date.prototype.stripTime = function() { return new Date(this.getFullYear(), this.getMonth(), this.getDate());};
Date.prototype.daysDistance = function(compare_date) { return Math.round((compare_date - this) / Date.one_day); };
Date.prototype.toFormattedString = function(include_time){
  str = Date.months[this.getMonth()] + " " + this.getDate() + ", " + this.getFullYear();

  if (include_time) { hour=this.getHours(); str += " " + this.getAMPMHour() + ":" + this.getPaddedMinutes() + " " + this.getAMPM() }
  return str;
}
window.f_height = function() { return([window.innerHeight ? window.innerHeight : null, document.documentElement ? document.documentElement.clientHeight : null, document.body ? document.body.clientHeight : null].compact().first()); }
window.f_scrollTop = function() { return ([window.pageYOffset ? window.pageYOffset : null, document.documentElement ? document.documentElement.scrollTop : null, document.body ? document.body.scrollTop : null].compact().first() ); }

CalendarDateSelect = Class.create();
CalendarDateSelect.prototype = {
  initialize: function(target_element, options) {
    // initialize the date control
    this.options = $H({
      embedded: false,
      time: false,
      year_range: 10,
      calendar_div: nil,
      close_on_click: nil,
      minute_interval: 5
    }).merge(options || {});

    this.target_element = $(target_element); // make sure it's an element, not a string
    this.selection_made = $F(this.target_element)!="";

    if (this.target_element.calendar_date_select)
    {
      this.target_element.calendar_date_select.close();
      return false;
    }
    this.target_element.calendar_date_select = this;

    this.calendar_div = $(this.options['calendar_div']);
    if (!this.target_element) { alert("Target element " + target_element + " not found!"); return false;}

    this.parseDate();

    // by default, stick it by the target element (if embedded, that's where we'll want it to show up)
    if (this.calendar_div == nil) { this.calendar_div = $( this.options.embedded ? this.target_element.parentNode : document.body ).build('div'); }
    if (!this.options.embedded) {
      this.calendar_div.style.position = "absolute";
      this.positionCalendarDiv();
    }

    this.calendar_div.addClassName("calendar_date_select");

    if (this.options["embedded"]) this.options["close_on_click"]=false;
    // logic for close on click
    if (this.options['close_on_click']===nil )
    {
      if (this.options['time'])
        this.options["close_on_click"] = false;
      else
        this.options['close_on_click'] = true;
    }

    // set the click handler to check if a user has clicked away from the document
    if(!this.options["embedded"]) Event.observe(document.body, "mousedown", this.bodyClick_handler=this.bodyClick.bindAsEventListener(this));

    this.initFrame();
    if(!this.options["embedded"]) setTimeout(function(){
      if (( parseInt(this.calendar_div.style.top) + this.calendar_div.getDimensions().height ) > (window.f_scrollTop() + window.f_height()))
        this.positionCalendarDiv(true);
      }.bindAsEventListener(this), 1);
  },
  positionCalendarDiv: function(above) {
    pos = Position.cumulativeOffset(this.target_element);

    this.calendar_div.style.left = pos[0].toString() + "px";
    if (above)
      this.calendar_div.style.top = (pos[1] - this.calendar_div.getDimensions().height ).toString() + "px";
    else
      this.calendar_div.style.top = (pos[1] + this.target_element.getDimensions().height ).toString() + "px";
  },
  initFrame: function() {
    that=this;
    // create the divs
    $w("header body time footer buttons").each(function(name) {
      eval(name + "_div = that." + name + "_div = that.calendar_div.build('div', { className: 'cds_"+name+"' }, { clear: 'left'} ); ");
    });

    this.initTimeDiv();
    this.initButtonsDiv();

    this.updateFooter(" ");
    // make the header buttons
    this.next_month_button = header_div.build("input", { type: "button", value : ">", className: "next" });
    this.prev_month_button = header_div.build("input", { type: "button", value : "<", className: "prev" });
    this.month_select = header_div.build("select", { className: "month"});
    this.year_select = header_div.build("select", { className: "year"});

    // make the month selector
    for(x=0; x<12; x++)
      this.month_select.options[x]=new Option(Date.months[x],x);
    Event.observe(this.prev_month_button, 'mousedown', function () { this.navMonth(this.date.getMonth() - 1 ) }.bindAsEventListener(this));
    Event.observe(this.next_month_button, 'mousedown', function () { this.navMonth(this.date.getMonth() + 1 ) }.bindAsEventListener(this));
    Event.observe(this.month_select, 'change', (function () { this.navMonth($F(this.month_select)) }).bindAsEventListener(this));
    Event.observe(this.year_select, 'change', (function () { this.navYear($F(this.year_select)) }).bindAsEventListener(this));

    // build the calendar day grid
    this.calendar_day_grid = [];
    days_table = body_div.build("table", { cellPadding: "0px", cellSpacing: "0px", width: "100%" }).build("tbody");

    // make the weekdays!
    weekdays_row = days_table.build("tr", {className: "weekdays"});
    Date.weekdays.each( function(weekday) {
      weekdays_row.build("td", {innerHTML: weekday});
    });

    // Make the days!
    for(cell_index=0; cell_index<42; cell_index++)
    {
      weekday=cell_index%7;
      if ( cell_index %7==0 ) days_row = days_table.build("tr", {className: "days"});
      (this.calendar_day_grid[cell_index] = days_row.build("td", {
          calendar_date_select: this,
          onmouseover: function () { this.calendar_date_select.dayHover(this); },
          onmouseout: function () { this.calendar_date_select.dayHoverOut(this) },
          onclick: function() { this.calendar_date_select.updateSelectedDate(this); },
          className: (weekday==0) || (weekday==6) ? " weekend" : "" //clear the class
        },
        { cursor: "pointer" }
      )).build("div");
      this.calendar_day_grid[cell_index];
    }
    this.refresh();
  },
  initButtonsDiv: function()
  {
    buttons_div = this.buttons_div;

    buttons_div.build("input", {
      value: (this.options["time"] ? "Now" : "Today" ),
      onclick: this.today.bindAsEventListener(this),
      type: "button"
    });

    if (this.allowCloseButtons())
    {
      buttons_div.build("input", {
        value: "OK",
        onclick: this.close.bindAsEventListener(this),
        type: "button"
      });
    }
  },
  initTimeDiv: function()
  {
    time_div = this.time_div;
    // make the time div
    if (this.options["time"])
    {
      time_div.build("span", {innerHTML:" @ "})
      this.hour_select = time_div.build("select", {
        calendar_date_select: this,
        onchange: function() { this.calendar_date_select.updateSelectedDate( { hour: this.value });}
      });
      time_div.build("span", {innerHTML:"  : "});
      this.minute_select = time_div.build("select", {
        calendar_date_select: this,
        onchange: function() { this.calendar_date_select.updateSelectedDate( {minute: this.value }) }
      });
      t=new Date();
      // populate hours
      for(x=0;x<=23;x++) { t.setHours(x); this.hour_select.options[x] = new Option( "" + t.getAMPMHour() + " " + t.getAMPM(), x ) }
      // populate minutes
      x=0; for(m=0;m<=60;m+=this.options["minute_interval"]) { this.minute_select.options[x++] = new Option( Date.padded2(m), m ) }
    } else (time_div.remove());
  },
  allowCloseButtons: function() { return ( !this.options["embedded"] && this.options["time"]); },
  dateString: function() {
    return (this.selection_made) ? this.selected_date.toFormattedString(this.options['time']) : " ";
  },
  navMonth: function(month) {
    prev_day = this.date.getDate();
    this.date.setMonth(month);

    this.refresh();
  },
  navYear: function(year) {
    this.date.setYear(year);
    this.refresh();
  },
  refresh: function ()
  {
    // set the month
    this.month_select.selectedIndex = this.date.getMonth();

    // set the year,
    range=this.options["year_range"];
    this.year_select.purgeChildren();
    for( x=0; x<=range*2; x++)
    {
      year = x+(this.date.getFullYear() - range);
      this.year_select.options[x]=new Option(year,year);
    }

    this.year_select.selectedIndex = range;

    // populate the calendar_day_grid
    this.beginning_date = new Date(this.date).stripTime();
    this.beginning_date.setDate(1);
    pre_days = this.beginning_date.getDay() // draw some days before the fact
    if (pre_days < 3) pre_days+=7;
    this.beginning_date.setDate(1 - pre_days);

    iterator = new Date(this.beginning_date);

    today = new Date().stripTime();
    this_month = this.date.getMonth();
    for (cell_index=0;cell_index<42; cell_index++)
    {

      day = iterator.getDate(); month = iterator.getMonth();
      cell = this.calendar_day_grid[cell_index];
      Element.remove(cell.childNodes[0]); div = cell.build("div", {innerHTML:day});
      if (month!=this_month) div.className = "other";
      cell.day=day; cell.month = month; cell.year = iterator.getFullYear();
      iterator.setDate( day + 1);
    }

    if (this.today_cell) this.today_cell.removeClassName("today");

    if ( $R(0,42).include(days_until = this.beginning_date.daysDistance(today)) ) {
      this.today_cell = this.calendar_day_grid[days_until];
      this.today_cell.addClassName("today");
    }

    // set the time
    if (this.options["time"]) {
      this.hour_select.selectedIndex = this.selected_date.getHours();
      this.minute_select.selectedIndex = this.selected_date.getMinutes() / this.options["minute_interval"];

      this.hour_select.onchange();
      this.minute_select.onchange();
    }

    this.setSelectedClass();
    this.updateFooter();
  },
  dayHover: function(element) {
    element.addClassName("hover");
    hover_date = new Date(this.selected_date);
    hover_date.setYear(element.year); hover_date.setMonth(element.month); hover_date.setDate(element.day);
    this.updateFooter(hover_date.toFormattedString(this.options['time']));
  },
  dayHoverOut: function(element) { element.removeClassName("hover"); this.updateFooter(); },
  setSelectedClass: function() {
    if (!this.selection_made) return;

    // clear selection
    if (this.selected_cell) this.selected_cell.removeClassName("selected");

    if ($R(0,42).include( days_until = this.beginning_date.daysDistance(this.selected_date.stripTime()) )) {
      this.selected_cell = this.calendar_day_grid[days_until];
      this.selected_cell.addClassName("selected");
    }
  },
  reparse: function() { this.parseDate(); this.refresh(); },
  parseDate: function()
  {
    this.date = new Date(this.options['date'] || $F(this.target_element));
    if (isNaN(this.date.getDate())) this.date = new Date();
    this.selected_date = new Date(this.date);
    this.date.setDate(1);
  },
  updateFooter:function(text) { if (!text) text=this.dateString(); this.footer_div.purgeChildren(); this.footer_div.build("text", {innerHTML: text }); },
  updateSelectedDate:function(parts) {
    if (parts.day) {
      this.selection_made = true;
      for (x=0; x<=1; x++) {
      this.selected_date.setDate(parts.day);
      this.selected_date.setMonth(parts.month);
      this.selected_date.setYear(parts.year);}
    }

    if (parts.hour) this.selected_date.setHours(parts.hour);
    if (parts.minute) this.selected_date.setMinutes(parts.minute);

    if (this.selection_made) this.target_element.value = this.dateString();
    if (this.options.close_on_click) { this.close(); }

    this.updateFooter();
    this.setSelectedClass();
  },
  today: function() {
    this.date = new Date();
    d=new Date(); this.updateSelectedDate( { day: d.getDate(), month: d.getMonth(), year: d.getFullYear(), hour: d.getHours(), minute: d.getMinutes() } );
    this.refresh();
  },
  close: function() {
    this.target_element.calendar_date_select = nil;
    Event.stopObserving(document.body, "mousedown", this.bodyClick_handler);
    this.calendar_div.remove();
    this.target_element.focus();
  },
  bodyClick: function(e) { // checks to see if somewhere other than calendar date select grid was clicked.  in which case, close
    if (! $(Event.element(e)).descendantOf(this.calendar_div) ) this.close();
  }
}<commit_msg>date parseing broken out to static function Date.parseFormattedString() for anyone who wants date's to parse a different way from javascript<commit_after>// CalendarDateSelect version 1.5.1 - a small prototype based date picker
// Questions, comments, bugs? - email the Author - Tim Harper <"timseeharper@gmail.seeom".gsub("see", "c")>
Element.addMethods({
  purgeChildren: function(element) { $A(element.childNodes).each(function(e){$(e).remove();}); },
  build: function(element, type, options, style) {
    newElement = Element.build(type, options, style);
    element.appendChild(newElement);
    return newElement;
  }
});

Element.build = function(type, options, style)
{
  e = $(document.createElement(type));
  $H(options).each(function(pair) { eval("e." + pair.key + " = pair.value" ); });
  if (style)
    $H(style).each(function(pair) { eval("e.style." + pair.key + " = pair.value" ); });
  return e;
};
nil=null;

Date.one_day = 24*60*60*1000;
Date.weekdays = $w("S M T W T F S");
Date.months = $w("January February March April May June July August September October November December" );
Date.padded2 = function(hour) { padded2 = hour.toString(); if (parseInt(hour) < 10) padded2="0" + padded2; return padded2; }
Date.prototype.getPaddedMinutes = function() { return Date.padded2(this.getMinutes()); }
Date.prototype.getAMPMHour = function() { hour=this.getHours(); return (hour == 0) ? 12 : (hour > 12 ? hour - 12 : hour ) }
Date.prototype.getAMPM = function() { return (this.getHours() < 12) ? "AM" : "PM"; }
Date.prototype.stripTime = function() { return new Date(this.getFullYear(), this.getMonth(), this.getDate());};
Date.prototype.daysDistance = function(compare_date) { return Math.round((compare_date - this) / Date.one_day); };
Date.prototype.toFormattedString = function(include_time){
  str = Date.months[this.getMonth()] + " " + this.getDate() + ", " + this.getFullYear();

  if (include_time) { hour=this.getHours(); str += " " + this.getAMPMHour() + ":" + this.getPaddedMinutes() + " " + this.getAMPM() }
  return str;
}
Date.parseFormattedString = function(string) { return new Date(string);}
window.f_height = function() { return([window.innerHeight ? window.innerHeight : null, document.documentElement ? document.documentElement.clientHeight : null, document.body ? document.body.clientHeight : null].compact().first()); }
window.f_scrollTop = function() { return ([window.pageYOffset ? window.pageYOffset : null, document.documentElement ? document.documentElement.scrollTop : null, document.body ? document.body.scrollTop : null].compact().first() ); }

CalendarDateSelect = Class.create();
CalendarDateSelect.prototype = {
  initialize: function(target_element, options) {
    // initialize the date control
    this.options = $H({
      embedded: false,
      time: false,
      year_range: 10,
      calendar_div: nil,
      close_on_click: nil,
      minute_interval: 5
    }).merge(options || {});

    this.target_element = $(target_element); // make sure it's an element, not a string
    this.selection_made = $F(this.target_element)!="";

    if (this.target_element.calendar_date_select)
    {
      this.target_element.calendar_date_select.close();
      return false;
    }
    this.target_element.calendar_date_select = this;

    this.calendar_div = $(this.options['calendar_div']);
    if (!this.target_element) { alert("Target element " + target_element + " not found!"); return false;}

    this.parseDate();

    // by default, stick it by the target element (if embedded, that's where we'll want it to show up)
    if (this.calendar_div == nil) { this.calendar_div = $( this.options.embedded ? this.target_element.parentNode : document.body ).build('div'); }
    if (!this.options.embedded) {
      this.calendar_div.style.position = "absolute";
      this.positionCalendarDiv();
    }

    this.calendar_div.addClassName("calendar_date_select");

    if (this.options["embedded"]) this.options["close_on_click"]=false;
    // logic for close on click
    if (this.options['close_on_click']===nil )
    {
      if (this.options['time'])
        this.options["close_on_click"] = false;
      else
        this.options['close_on_click'] = true;
    }

    // set the click handler to check if a user has clicked away from the document
    if(!this.options["embedded"]) Event.observe(document.body, "mousedown", this.bodyClick_handler=this.bodyClick.bindAsEventListener(this));

    this.initFrame();
    if(!this.options["embedded"]) setTimeout(function(){
      if (( parseInt(this.calendar_div.style.top) + this.calendar_div.getDimensions().height ) > (window.f_scrollTop() + window.f_height()))
        this.positionCalendarDiv(true);
      }.bindAsEventListener(this), 1);
  },
  positionCalendarDiv: function(above) {
    pos = Position.cumulativeOffset(this.target_element);

    this.calendar_div.style.left = pos[0].toString() + "px";
    if (above)
      this.calendar_div.style.top = (pos[1] - this.calendar_div.getDimensions().height ).toString() + "px";
    else
      this.calendar_div.style.top = (pos[1] + this.target_element.getDimensions().height ).toString() + "px";
  },
  initFrame: function() {
    that=this;
    // create the divs
    $w("header body time footer buttons").each(function(name) {
      eval(name + "_div = that." + name + "_div = that.calendar_div.build('div', { className: 'cds_"+name+"' }, { clear: 'left'} ); ");
    });

    this.initTimeDiv();
    this.initButtonsDiv();

    this.updateFooter(" ");
    // make the header buttons
    this.next_month_button = header_div.build("input", { type: "button", value : ">", className: "next" });
    this.prev_month_button = header_div.build("input", { type: "button", value : "<", className: "prev" });
    this.month_select = header_div.build("select", { className: "month"});
    this.year_select = header_div.build("select", { className: "year"});

    // make the month selector
    for(x=0; x<12; x++)
      this.month_select.options[x]=new Option(Date.months[x],x);
    Event.observe(this.prev_month_button, 'mousedown', function () { this.navMonth(this.date.getMonth() - 1 ) }.bindAsEventListener(this));
    Event.observe(this.next_month_button, 'mousedown', function () { this.navMonth(this.date.getMonth() + 1 ) }.bindAsEventListener(this));
    Event.observe(this.month_select, 'change', (function () { this.navMonth($F(this.month_select)) }).bindAsEventListener(this));
    Event.observe(this.year_select, 'change', (function () { this.navYear($F(this.year_select)) }).bindAsEventListener(this));

    // build the calendar day grid
    this.calendar_day_grid = [];
    days_table = body_div.build("table", { cellPadding: "0px", cellSpacing: "0px", width: "100%" }).build("tbody");

    // make the weekdays!
    weekdays_row = days_table.build("tr", {className: "weekdays"});
    Date.weekdays.each( function(weekday) {
      weekdays_row.build("td", {innerHTML: weekday});
    });

    // Make the days!
    for(cell_index=0; cell_index<42; cell_index++)
    {
      weekday=cell_index%7;
      if ( cell_index %7==0 ) days_row = days_table.build("tr", {className: "days"});
      (this.calendar_day_grid[cell_index] = days_row.build("td", {
          calendar_date_select: this,
          onmouseover: function () { this.calendar_date_select.dayHover(this); },
          onmouseout: function () { this.calendar_date_select.dayHoverOut(this) },
          onclick: function() { this.calendar_date_select.updateSelectedDate(this); },
          className: (weekday==0) || (weekday==6) ? " weekend" : "" //clear the class
        },
        { cursor: "pointer" }
      )).build("div");
      this.calendar_day_grid[cell_index];
    }
    this.refresh();
  },
  initButtonsDiv: function()
  {
    buttons_div = this.buttons_div;

    buttons_div.build("input", {
      value: (this.options["time"] ? "Now" : "Today" ),
      onclick: this.today.bindAsEventListener(this),
      type: "button"
    });

    if (this.allowCloseButtons())
    {
      buttons_div.build("input", {
        value: "OK",
        onclick: this.close.bindAsEventListener(this),
        type: "button"
      });
    }
  },
  initTimeDiv: function()
  {
    time_div = this.time_div;
    // make the time div
    if (this.options["time"])
    {
      time_div.build("span", {innerHTML:" @ "})
      this.hour_select = time_div.build("select", {
        calendar_date_select: this,
        onchange: function() { this.calendar_date_select.updateSelectedDate( { hour: this.value });}
      });
      time_div.build("span", {innerHTML:"  : "});
      this.minute_select = time_div.build("select", {
        calendar_date_select: this,
        onchange: function() { this.calendar_date_select.updateSelectedDate( {minute: this.value }) }
      });
      t=new Date();
      // populate hours
      for(x=0;x<=23;x++) { t.setHours(x); this.hour_select.options[x] = new Option( "" + t.getAMPMHour() + " " + t.getAMPM(), x ) }
      // populate minutes
      x=0; for(m=0;m<=60;m+=this.options["minute_interval"]) { this.minute_select.options[x++] = new Option( Date.padded2(m), m ) }
    } else (time_div.remove());
  },
  allowCloseButtons: function() { return ( !this.options["embedded"] && this.options["time"]); },
  dateString: function() {
    return (this.selection_made) ? this.selected_date.toFormattedString(this.options['time']) : " ";
  },
  navMonth: function(month) {
    prev_day = this.date.getDate();
    this.date.setMonth(month);

    this.refresh();
  },
  navYear: function(year) {
    this.date.setYear(year);
    this.refresh();
  },
  refresh: function ()
  {
    // set the month
    this.month_select.selectedIndex = this.date.getMonth();

    // set the year,
    range=this.options["year_range"];
    this.year_select.purgeChildren();
    for( x=0; x<=range*2; x++)
    {
      year = x+(this.date.getFullYear() - range);
      this.year_select.options[x]=new Option(year,year);
    }

    this.year_select.selectedIndex = range;

    // populate the calendar_day_grid
    this.beginning_date = new Date(this.date).stripTime();
    this.beginning_date.setDate(1);
    pre_days = this.beginning_date.getDay() // draw some days before the fact
    if (pre_days < 3) pre_days+=7;
    this.beginning_date.setDate(1 - pre_days);

    iterator = new Date(this.beginning_date);

    today = new Date().stripTime();
    this_month = this.date.getMonth();
    for (cell_index=0;cell_index<42; cell_index++)
    {

      day = iterator.getDate(); month = iterator.getMonth();
      cell = this.calendar_day_grid[cell_index];
      Element.remove(cell.childNodes[0]); div = cell.build("div", {innerHTML:day});
      if (month!=this_month) div.className = "other";
      cell.day=day; cell.month = month; cell.year = iterator.getFullYear();
      iterator.setDate( day + 1);
    }

    if (this.today_cell) this.today_cell.removeClassName("today");

    if ( $R(0,42).include(days_until = this.beginning_date.daysDistance(today)) ) {
      this.today_cell = this.calendar_day_grid[days_until];
      this.today_cell.addClassName("today");
    }

    // set the time
    if (this.options["time"]) {
      this.hour_select.selectedIndex = this.selected_date.getHours();
      this.minute_select.selectedIndex = this.selected_date.getMinutes() / this.options["minute_interval"];

      this.hour_select.onchange();
      this.minute_select.onchange();
    }

    this.setSelectedClass();
    this.updateFooter();
  },
  dayHover: function(element) {
    element.addClassName("hover");
    hover_date = new Date(this.selected_date);
    hover_date.setYear(element.year); hover_date.setMonth(element.month); hover_date.setDate(element.day);
    this.updateFooter(hover_date.toFormattedString(this.options['time']));
  },
  dayHoverOut: function(element) { element.removeClassName("hover"); this.updateFooter(); },
  setSelectedClass: function() {
    if (!this.selection_made) return;

    // clear selection
    if (this.selected_cell) this.selected_cell.removeClassName("selected");

    if ($R(0,42).include( days_until = this.beginning_date.daysDistance(this.selected_date.stripTime()) )) {
      this.selected_cell = this.calendar_day_grid[days_until];
      this.selected_cell.addClassName("selected");
    }
  },
  reparse: function() { this.parseDate(); this.refresh(); },
  parseDate: function()
  {
    this.date = Date.parseFormattedString(this.options['date'] || $F(this.target_element));
    if (isNaN(this.date.getDate())) this.date = new Date();
    this.selected_date = new Date(this.date);
    this.date.setDate(1);
  },
  updateFooter:function(text) { if (!text) text=this.dateString(); this.footer_div.purgeChildren(); this.footer_div.build("text", {innerHTML: text }); },
  updateSelectedDate:function(parts) {
    if (parts.day) {
      this.selection_made = true;
      for (x=0; x<=1; x++) {
      this.selected_date.setDate(parts.day);
      this.selected_date.setMonth(parts.month);
      this.selected_date.setYear(parts.year);}
    }

    if (parts.hour) this.selected_date.setHours(parts.hour);
    if (parts.minute) this.selected_date.setMinutes(parts.minute);

    if (this.selection_made) this.target_element.value = this.dateString();
    if (this.options.close_on_click) { this.close(); }

    this.updateFooter();
    this.setSelectedClass();
  },
  today: function() {
    this.date = new Date();
    d=new Date(); this.updateSelectedDate( { day: d.getDate(), month: d.getMonth(), year: d.getFullYear(), hour: d.getHours(), minute: d.getMinutes() } );
    this.refresh();
  },
  close: function() {
    this.target_element.calendar_date_select = nil;
    Event.stopObserving(document.body, "mousedown", this.bodyClick_handler);
    this.calendar_div.remove();
    this.target_element.focus();
  },
  bodyClick: function(e) { // checks to see if somewhere other than calendar date select grid was clicked.  in which case, close
    if (! $(Event.element(e)).descendantOf(this.calendar_div) ) this.close();
  }
}<|endoftext|>