<commit_before>'use strict'

const {EventEmitter} = require('events')
const electron = require('electron')
const path = require('path')
const url = require('url')
const {app, ipcMain, session, NavigationController, deprecate} = electron

// session is not used here, the purpose is to make sure session is initalized
// before the webContents module.
// eslint-disable-next-line
session

let nextId = 0
const getNextId = function () {
  return ++nextId
}

// Stock page sizes
const PDFPageSizes = {
  A5: {
    custom_display_name: 'A5',
    height_microns: 210000,
    name: 'ISO_A5',
    width_microns: 148000
  },
  A4: {
    custom_display_name: 'A4',
    height_microns: 297000,
    name: 'ISO_A4',
    is_default: 'true',
    width_microns: 210000
  },
  A3: {
    custom_display_name: 'A3',
    height_microns: 420000,
    name: 'ISO_A3',
    width_microns: 297000
  },
  Legal: {
    custom_display_name: 'Legal',
    height_microns: 355600,
    name: 'NA_LEGAL',
    width_microns: 215900
  },
  Letter: {
    custom_display_name: 'Letter',
    height_microns: 279400,
    name: 'NA_LETTER',
    width_microns: 215900
  },
  Tabloid: {
    height_microns: 431800,
    name: 'NA_LEDGER',
    width_microns: 279400,
    custom_display_name: 'Tabloid'
  }
}

// Default printing setting
const defaultPrintingSetting = {
  pageRage: [],
  mediaSize: {},
  landscape: false,
  color: 2,
  headerFooterEnabled: false,
  marginsType: 0,
  isFirstRequest: false,
  requestID: getNextId(),
  previewModifiable: true,
  printToPDF: true,
  printWithCloudPrint: false,
  printWithPrivet: false,
  printWithExtension: false,
  deviceName: 'Save as PDF',
  generateDraftData: true,
  fitToPageEnabled: false,
  scaleFactor: 1,
  dpiHorizontal: 72,
  dpiVertical: 72,
  rasterizePDF: false,
  duplex: 0,
  copies: 1,
  collate: true,
  shouldPrintBackgrounds: false,
  shouldPrintSelectionOnly: false
}

// JavaScript implementations of WebContents.
const binding = process.atomBinding('web_contents')
const {WebContents} = binding

Object.setPrototypeOf(NavigationController.prototype, EventEmitter.prototype)
Object.setPrototypeOf(WebContents.prototype, NavigationController.prototype)

// WebContents::send(channel, args..)
// WebContents::sendToAll(channel, args..)
WebContents.prototype.send = function (channel, ...args) {
  if (channel == null) throw new Error('Missing required channel argument')
  return this._send(false, channel, args)
}
WebContents.prototype.sendToAll = function (channel, ...args) {
  if (channel == null) throw new Error('Missing required channel argument')
  return this._send(true, channel, args)
}

// Following methods are mapped to webFrame.
const webFrameMethods = [
  'insertCSS',
  'insertText',
  'setLayoutZoomLevelLimits',
  'setVisualZoomLevelLimits'
]
const webFrameMethodsWithResult = []

const errorConstructors = {
  Error,
  EvalError,
  RangeError,
  ReferenceError,
  SyntaxError,
  TypeError,
  URIError
}

const asyncWebFrameMethods = function (requestId, method, callback, ...args) {
  return new Promise((resolve, reject) => {
    this.send('ELECTRON_INTERNAL_RENDERER_ASYNC_WEB_FRAME_METHOD', requestId, method, args)
    ipcMain.once(`ELECTRON_INTERNAL_BROWSER_ASYNC_WEB_FRAME_RESPONSE_${requestId}`, function (event, error, result) {
      if (error == null) {
        if (typeof callback === 'function') callback(result)
        resolve(result)
      } else {
        if (error.__ELECTRON_SERIALIZED_ERROR__ && errorConstructors[error.name]) {
          const rehydratedError = new errorConstructors[error.name](error.message)
          rehydratedError.stack = error.stack

          reject(rehydratedError)
        } else {
          reject(error)
        }
      }
    })
  })
}

const syncWebFrameMethods = function (requestId, method, callback, ...args) {
  this.send('ELECTRON_INTERNAL_RENDERER_SYNC_WEB_FRAME_METHOD', requestId, method, args)
  ipcMain.once(`ELECTRON_INTERNAL_BROWSER_SYNC_WEB_FRAME_RESPONSE_${requestId}`, function (event, result) {
    if (callback) callback(result)
  })
}

for (const method of webFrameMethods) {
  WebContents.prototype[method] = function (...args) {
    this.send('ELECTRON_INTERNAL_RENDERER_WEB_FRAME_METHOD', method, args)
  }
}

for (const method of webFrameMethodsWithResult) {
  WebContents.prototype[method] = function (...args) {
    const callback = args[args.length - 1]
    const actualArgs = args.slice(0, args.length - 2)
    syncWebFrameMethods.call(this, getNextId(), method, callback, ...actualArgs)
  }
}

// Make sure WebContents::executeJavaScript would run the code only when the
// WebContents has been loaded.
WebContents.prototype.executeJavaScript = function (code, hasUserGesture, callback) {
  const requestId = getNextId()

  if (typeof hasUserGesture === 'function') {
    // Shift.
    callback = hasUserGesture
    hasUserGesture = null
  }

  if (hasUserGesture == null) {
    hasUserGesture = false
  }

  if (this.getURL() && !this.isLoadingMainFrame()) {
    return asyncWebFrameMethods.call(this, requestId, 'executeJavaScript', callback, code, hasUserGesture)
  } else {
    return new Promise((resolve, reject) => {
      this.once('did-finish-load', () => {
        asyncWebFrameMethods.call(this, requestId, 'executeJavaScript', callback, code, hasUserGesture).then(resolve).catch(reject)
      })
    })
  }
}

// Translate the options of printToPDF.
WebContents.prototype.printToPDF = function (options, callback) {
  const printingSetting = Object.assign({}, defaultPrintingSetting)
  if (options.landscape) {
    printingSetting.landscape = options.landscape
  }
  if (options.marginsType) {
    printingSetting.marginsType = options.marginsType
  }
  if (options.printSelectionOnly) {
    printingSetting.shouldPrintSelectionOnly = options.printSelectionOnly
  }
  if (options.printBackground) {
    printingSetting.shouldPrintBackgrounds = options.printBackground
  }

  if (options.pageSize) {
    const pageSize = options.pageSize
    if (typeof pageSize === 'object') {
      if (!pageSize.height || !pageSize.width) {
        return callback(new Error('Must define height and width for pageSize'))
      }
      // Dimensions in Microns
      // 1 meter = 10^6 microns
      printingSetting.mediaSize = {
        name: 'CUSTOM',
        custom_display_name: 'Custom',
        height_microns: Math.ceil(pageSize.height),
        width_microns: Math.ceil(pageSize.width)
      }
    } else if (PDFPageSizes[pageSize]) {
      printingSetting.mediaSize = PDFPageSizes[pageSize]
    } else {
      return callback(new Error(`Does not support pageSize with ${pageSize}`))
    }
  } else {
    printingSetting.mediaSize = PDFPageSizes['A4']
  }

  this._printToPDF(printingSetting, callback)
}

WebContents.prototype.getZoomLevel = function (callback) {
  if (typeof callback !== 'function') {
    throw new Error('Must pass function as an argument')
  }
  process.nextTick(() => {
    const zoomLevel = this._getZoomLevel()
    callback(zoomLevel)
  })
}

WebContents.prototype.loadFile = function (filePath) {
  if (typeof filePath !== 'string') {
    throw new Error('Must pass filePath as a string')
  }
  return this.loadURL(url.format({
    protocol: 'file',
    slashes: true,
    pathname: path.resolve(app.getAppPath(), filePath)
  }))
}

WebContents.prototype.getZoomFactor = function (callback) {
  if (typeof callback !== 'function') {
    throw new Error('Must pass function as an argument')
  }
  process.nextTick(() => {
    const zoomFactor = this._getZoomFactor()
    callback(zoomFactor)
  })
}

// Add JavaScript wrappers for WebContents class.
WebContents.prototype._init = function () {
  // The navigation controller.
  NavigationController.call(this, this)

  // Every remote callback from renderer process would add a listenter to the
  // render-view-deleted event, so ignore the listenters warning.
  this.setMaxListeners(0)

  // Dispatch IPC messages to the ipc module.
  this.on('ipc-message', function (event, [channel, ...args]) {
    ipcMain.emit(channel, event, ...args)
  })
  this.on('ipc-message-sync', function (event, [channel, ...args]) {
    Object.defineProperty(event, 'returnValue', {
      set: function (value) {
        return event.sendReply([value])
      },
      get: function () {}
    })
    ipcMain.emit(channel, event, ...args)
  })

  // Handle context menu action request from pepper plugin.
  this.on('pepper-context-menu', function (event, params, callback) {
    // Access Menu via electron.Menu to prevent circular require.
    const menu = electron.Menu.buildFromTemplate(params.menu)
    menu.popup({
      window: event.sender.getOwnerBrowserWindow(),
      x: params.x,
      y: params.y,
      callback
    })
  })

  deprecate.event(this, 'did-get-response-details', '-did-get-response-details')
  deprecate.event(this, 'did-get-redirect-request', '-did-get-redirect-request')

  // The devtools requests the webContents to reload.
  this.on('devtools-reload-page', function () {
    this.reload()
  })

  app.emit('web-contents-created', {}, this)
}

// JavaScript wrapper of Debugger.
const {Debugger} = process.atomBinding('debugger')

Object.setPrototypeOf(Debugger.prototype, EventEmitter.prototype)

// Public APIs.
module.exports = {
  create (options = {}) {
    return binding.create(options)
  },

  fromId (id) {
    return binding.fromId(id)
  },

  getFocusedWebContents () {
    let focused = null
    for (let contents of binding.getAllWebContents()) {
      if (!contents.isFocused()) continue
      if (focused == null) focused = contents
      // Return webview web contents which may be embedded inside another
      // web contents that is also reporting as focused
      if (contents.getType() === 'webview') return contents
    }
    return focused
  },

  getAllWebContents () {
    return binding.getAllWebContents()
  }
}
<commit_msg>fix: remove race condition for executeJavaScript (#13691)<commit_after>'use strict'

const {EventEmitter} = require('events')
const electron = require('electron')
const path = require('path')
const url = require('url')
const {app, ipcMain, session, NavigationController, deprecate} = electron

// session is not used here, the purpose is to make sure session is initalized
// before the webContents module.
// eslint-disable-next-line
session

let nextId = 0
const getNextId = function () {
  return ++nextId
}

// Stock page sizes
const PDFPageSizes = {
  A5: {
    custom_display_name: 'A5',
    height_microns: 210000,
    name: 'ISO_A5',
    width_microns: 148000
  },
  A4: {
    custom_display_name: 'A4',
    height_microns: 297000,
    name: 'ISO_A4',
    is_default: 'true',
    width_microns: 210000
  },
  A3: {
    custom_display_name: 'A3',
    height_microns: 420000,
    name: 'ISO_A3',
    width_microns: 297000
  },
  Legal: {
    custom_display_name: 'Legal',
    height_microns: 355600,
    name: 'NA_LEGAL',
    width_microns: 215900
  },
  Letter: {
    custom_display_name: 'Letter',
    height_microns: 279400,
    name: 'NA_LETTER',
    width_microns: 215900
  },
  Tabloid: {
    height_microns: 431800,
    name: 'NA_LEDGER',
    width_microns: 279400,
    custom_display_name: 'Tabloid'
  }
}

// Default printing setting
const defaultPrintingSetting = {
  pageRage: [],
  mediaSize: {},
  landscape: false,
  color: 2,
  headerFooterEnabled: false,
  marginsType: 0,
  isFirstRequest: false,
  requestID: getNextId(),
  previewModifiable: true,
  printToPDF: true,
  printWithCloudPrint: false,
  printWithPrivet: false,
  printWithExtension: false,
  deviceName: 'Save as PDF',
  generateDraftData: true,
  fitToPageEnabled: false,
  scaleFactor: 1,
  dpiHorizontal: 72,
  dpiVertical: 72,
  rasterizePDF: false,
  duplex: 0,
  copies: 1,
  collate: true,
  shouldPrintBackgrounds: false,
  shouldPrintSelectionOnly: false
}

// JavaScript implementations of WebContents.
const binding = process.atomBinding('web_contents')
const {WebContents} = binding

Object.setPrototypeOf(NavigationController.prototype, EventEmitter.prototype)
Object.setPrototypeOf(WebContents.prototype, NavigationController.prototype)

// WebContents::send(channel, args..)
// WebContents::sendToAll(channel, args..)
WebContents.prototype.send = function (channel, ...args) {
  if (channel == null) throw new Error('Missing required channel argument')
  return this._send(false, channel, args)
}
WebContents.prototype.sendToAll = function (channel, ...args) {
  if (channel == null) throw new Error('Missing required channel argument')
  return this._send(true, channel, args)
}

// Following methods are mapped to webFrame.
const webFrameMethods = [
  'insertCSS',
  'insertText',
  'setLayoutZoomLevelLimits',
  'setVisualZoomLevelLimits'
]
const webFrameMethodsWithResult = []

const errorConstructors = {
  Error,
  EvalError,
  RangeError,
  ReferenceError,
  SyntaxError,
  TypeError,
  URIError
}

const asyncWebFrameMethods = function (requestId, method, callback, ...args) {
  return new Promise((resolve, reject) => {
    this.send('ELECTRON_INTERNAL_RENDERER_ASYNC_WEB_FRAME_METHOD', requestId, method, args)
    ipcMain.once(`ELECTRON_INTERNAL_BROWSER_ASYNC_WEB_FRAME_RESPONSE_${requestId}`, function (event, error, result) {
      if (error == null) {
        if (typeof callback === 'function') callback(result)
        resolve(result)
      } else {
        if (error.__ELECTRON_SERIALIZED_ERROR__ && errorConstructors[error.name]) {
          const rehydratedError = new errorConstructors[error.name](error.message)
          rehydratedError.stack = error.stack

          reject(rehydratedError)
        } else {
          reject(error)
        }
      }
    })
  })
}

const syncWebFrameMethods = function (requestId, method, callback, ...args) {
  this.send('ELECTRON_INTERNAL_RENDERER_SYNC_WEB_FRAME_METHOD', requestId, method, args)
  ipcMain.once(`ELECTRON_INTERNAL_BROWSER_SYNC_WEB_FRAME_RESPONSE_${requestId}`, function (event, result) {
    if (callback) callback(result)
  })
}

for (const method of webFrameMethods) {
  WebContents.prototype[method] = function (...args) {
    this.send('ELECTRON_INTERNAL_RENDERER_WEB_FRAME_METHOD', method, args)
  }
}

for (const method of webFrameMethodsWithResult) {
  WebContents.prototype[method] = function (...args) {
    const callback = args[args.length - 1]
    const actualArgs = args.slice(0, args.length - 2)
    syncWebFrameMethods.call(this, getNextId(), method, callback, ...actualArgs)
  }
}

// Make sure WebContents::executeJavaScript would run the code only when the
// WebContents has been loaded.
WebContents.prototype.executeJavaScript = function (code, hasUserGesture, callback) {
  const requestId = getNextId()

  if (typeof hasUserGesture === 'function') {
    // Shift.
    callback = hasUserGesture
    hasUserGesture = null
  }

  if (hasUserGesture == null) {
    hasUserGesture = false
  }

  if (this.getURL() && !this.isLoadingMainFrame()) {
    return asyncWebFrameMethods.call(this, requestId, 'executeJavaScript', callback, code, hasUserGesture)
  } else {
    return new Promise((resolve, reject) => {
      this.once('did-stop-loading', () => {
        asyncWebFrameMethods.call(this, requestId, 'executeJavaScript', callback, code, hasUserGesture).then(resolve).catch(reject)
      })
    })
  }
}

// Translate the options of printToPDF.
WebContents.prototype.printToPDF = function (options, callback) {
  const printingSetting = Object.assign({}, defaultPrintingSetting)
  if (options.landscape) {
    printingSetting.landscape = options.landscape
  }
  if (options.marginsType) {
    printingSetting.marginsType = options.marginsType
  }
  if (options.printSelectionOnly) {
    printingSetting.shouldPrintSelectionOnly = options.printSelectionOnly
  }
  if (options.printBackground) {
    printingSetting.shouldPrintBackgrounds = options.printBackground
  }

  if (options.pageSize) {
    const pageSize = options.pageSize
    if (typeof pageSize === 'object') {
      if (!pageSize.height || !pageSize.width) {
        return callback(new Error('Must define height and width for pageSize'))
      }
      // Dimensions in Microns
      // 1 meter = 10^6 microns
      printingSetting.mediaSize = {
        name: 'CUSTOM',
        custom_display_name: 'Custom',
        height_microns: Math.ceil(pageSize.height),
        width_microns: Math.ceil(pageSize.width)
      }
    } else if (PDFPageSizes[pageSize]) {
      printingSetting.mediaSize = PDFPageSizes[pageSize]
    } else {
      return callback(new Error(`Does not support pageSize with ${pageSize}`))
    }
  } else {
    printingSetting.mediaSize = PDFPageSizes['A4']
  }

  this._printToPDF(printingSetting, callback)
}

WebContents.prototype.getZoomLevel = function (callback) {
  if (typeof callback !== 'function') {
    throw new Error('Must pass function as an argument')
  }
  process.nextTick(() => {
    const zoomLevel = this._getZoomLevel()
    callback(zoomLevel)
  })
}

WebContents.prototype.loadFile = function (filePath) {
  if (typeof filePath !== 'string') {
    throw new Error('Must pass filePath as a string')
  }
  return this.loadURL(url.format({
    protocol: 'file',
    slashes: true,
    pathname: path.resolve(app.getAppPath(), filePath)
  }))
}

WebContents.prototype.getZoomFactor = function (callback) {
  if (typeof callback !== 'function') {
    throw new Error('Must pass function as an argument')
  }
  process.nextTick(() => {
    const zoomFactor = this._getZoomFactor()
    callback(zoomFactor)
  })
}

// Add JavaScript wrappers for WebContents class.
WebContents.prototype._init = function () {
  // The navigation controller.
  NavigationController.call(this, this)

  // Every remote callback from renderer process would add a listenter to the
  // render-view-deleted event, so ignore the listenters warning.
  this.setMaxListeners(0)

  // Dispatch IPC messages to the ipc module.
  this.on('ipc-message', function (event, [channel, ...args]) {
    ipcMain.emit(channel, event, ...args)
  })
  this.on('ipc-message-sync', function (event, [channel, ...args]) {
    Object.defineProperty(event, 'returnValue', {
      set: function (value) {
        return event.sendReply([value])
      },
      get: function () {}
    })
    ipcMain.emit(channel, event, ...args)
  })

  // Handle context menu action request from pepper plugin.
  this.on('pepper-context-menu', function (event, params, callback) {
    // Access Menu via electron.Menu to prevent circular require.
    const menu = electron.Menu.buildFromTemplate(params.menu)
    menu.popup({
      window: event.sender.getOwnerBrowserWindow(),
      x: params.x,
      y: params.y,
      callback
    })
  })

  deprecate.event(this, 'did-get-response-details', '-did-get-response-details')
  deprecate.event(this, 'did-get-redirect-request', '-did-get-redirect-request')

  // The devtools requests the webContents to reload.
  this.on('devtools-reload-page', function () {
    this.reload()
  })

  app.emit('web-contents-created', {}, this)
}

// JavaScript wrapper of Debugger.
const {Debugger} = process.atomBinding('debugger')

Object.setPrototypeOf(Debugger.prototype, EventEmitter.prototype)

// Public APIs.
module.exports = {
  create (options = {}) {
    return binding.create(options)
  },

  fromId (id) {
    return binding.fromId(id)
  },

  getFocusedWebContents () {
    let focused = null
    for (let contents of binding.getAllWebContents()) {
      if (!contents.isFocused()) continue
      if (focused == null) focused = contents
      // Return webview web contents which may be embedded inside another
      // web contents that is also reporting as focused
      if (contents.getType() === 'webview') return contents
    }
    return focused
  },

  getAllWebContents () {
    return binding.getAllWebContents()
  }
}
<|endoftext|>


<commit_before>/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @author       Felipe Alfonso <@bitnenfer>
 * @copyright    2022 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Class = require('../../../utils/Class');
var GetFastValue = require('../../../utils/object/GetFastValue');
var ShaderSourceFS = require('../shaders/BitmapMask-frag.js');
var ShaderSourceVS = require('../shaders/BitmapMask-vert.js');
var WEBGL_CONST = require('../const');
var WebGLPipeline = require('../WebGLPipeline');

/**
 * @classdesc
 * The Bitmap Mask Pipeline handles all of the bitmap mask rendering in WebGL for applying
 * alpha masks to Game Objects. It works by sampling two texture on the fragment shader and
 * using the fragments alpha to clip the region.
 *
 * The fragment shader it uses can be found in `shaders/src/BitmapMask.frag`.
 * The vertex shader it uses can be found in `shaders/src/BitmapMask.vert`.
 *
 * The default shader attributes for this pipeline are:
 *
 * `inPosition` (vec2, offset 0)
 *
 * The default shader uniforms for this pipeline are:
 *
 * `uResolution` (vec2)
 * `uMainSampler` (sampler2D)
 * `uMaskSampler` (sampler2D)
 * `uInvertMaskAlpha` (bool)
 *
 * @class BitmapMaskPipeline
 * @extends Phaser.Renderer.WebGL.WebGLPipeline
 * @memberof Phaser.Renderer.WebGL.Pipelines
 * @constructor
 * @since 3.0.0
 *
 * @param {Phaser.Types.Renderer.WebGL.WebGLPipelineConfig} config - The configuration options for this pipeline.
 */
var BitmapMaskPipeline = new Class({

    Extends: WebGLPipeline,

    initialize:

    function BitmapMaskPipeline (config)
    {
        config.fragShader = GetFastValue(config, 'fragShader', ShaderSourceFS),
        config.vertShader = GetFastValue(config, 'vertShader', ShaderSourceVS),
        config.batchSize = GetFastValue(config, 'batchSize', 1),
        config.vertices = GetFastValue(config, 'vertices', [ -1, 1, -1, -7, 7, 1 ]),
        config.attributes = GetFastValue(config, 'attributes', [
            {
                name: 'inPosition',
                size: 2,
                type: WEBGL_CONST.FLOAT
            }
        ]);

        WebGLPipeline.call(this, config);
    },

    boot: function ()
    {
        WebGLPipeline.prototype.boot.call(this);

        this.set1i('uMainSampler', 0);
        this.set1i('uMaskSampler', 1);
    },

    resize: function (width, height)
    {
        WebGLPipeline.prototype.resize.call(this, width, height);

        this.set2f('uResolution', width, height);
    },

    /**
     * Binds necessary resources and renders the mask to a separated framebuffer.
     * The framebuffer for the masked object is also bound for further use.
     *
     * @method Phaser.Renderer.WebGL.Pipelines.BitmapMaskPipeline#beginMask
     * @since 3.0.0
     *
     * @param {Phaser.GameObjects.GameObject} mask - GameObject used as mask.
     * @param {Phaser.GameObjects.GameObject} maskedObject - GameObject masked by the mask GameObject.
     * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera rendering the current mask.
     */
    beginMask: function (mask, maskedObject, camera)
    {
        var gl = this.gl;

        //  The renderable Game Object that is being used for the bitmap mask
        if (mask.bitmapMask && gl)
        {
            var renderer = this.renderer;

            renderer.flush();

            renderer.pushFramebuffer(mask.mainFramebuffer);

            gl.disable(gl.STENCIL_TEST);
            gl.clearColor(0, 0, 0, 0);
            gl.clear(gl.COLOR_BUFFER_BIT);

            if (renderer.currentCameraMask.mask !== mask)
            {
                renderer.currentMask.mask = mask;
                renderer.currentMask.camera = camera;
            }
        }
    },

    /**
     * The masked game objects framebuffer is unbound and its texture
     * is bound together with the mask texture and the mask shader and
     * a draw call with a single quad is processed. Here is where the
     * masking effect is applied.
     *
     * @method Phaser.Renderer.WebGL.Pipelines.BitmapMaskPipeline#endMask
     * @since 3.0.0
     *
     * @param {Phaser.GameObjects.GameObject} mask - GameObject used as a mask.
     * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to render to.
     * @param {Phaser.Renderer.WebGL.RenderTarget} [renderTarget] - Optional WebGL RenderTarget.
     */
    endMask: function (mask, camera, renderTarget)
    {
        var gl = this.gl;
        var renderer = this.renderer;

        //  The renderable Game Object that is being used for the bitmap mask
        var bitmapMask = mask.bitmapMask;

        if (bitmapMask && gl)
        {
            //  mask.mainFramebuffer should now contain all the Game Objects we want masked
            renderer.flush();

            //  Swap to the mask framebuffer (push, in case the bitmapMask GO has a post-pipeline)
            renderer.pushFramebuffer(mask.maskFramebuffer);

            //  Clear it and draw the Game Object that is acting as a mask to it
            gl.clearColor(0, 0, 0, 0);
            gl.clear(gl.COLOR_BUFFER_BIT);

            renderer.setBlendMode(0, true);

            bitmapMask.renderWebGL(renderer, bitmapMask, camera);

            renderer.flush();

            //  Clear the mask framebuffer + main framebuffer
            renderer.popFramebuffer();
            renderer.popFramebuffer();

            //  Is there a stencil further up the stack?
            var prev = renderer.getCurrentStencilMask();

            if (prev)
            {
                gl.enable(gl.STENCIL_TEST);

                prev.mask.applyStencil(renderer, prev.camera, true);
            }
            else
            {
                renderer.currentMask.mask = null;
            }

            //  Bind this pipeline and draw
            renderer.pipelines.set(this);

            if (renderTarget)
            {
                this.set2f('uResolution', renderTarget.width, renderTarget.height);
            }

            gl.activeTexture(gl.TEXTURE1);
            gl.bindTexture(gl.TEXTURE_2D, mask.maskTexture);

            gl.activeTexture(gl.TEXTURE0);
            gl.bindTexture(gl.TEXTURE_2D, mask.mainTexture);

            this.set1i('uInvertMaskAlpha', mask.invertAlpha);

            //  Finally, draw a triangle filling the whole screen
            gl.drawArrays(this.topology, 0, 3);

            if (renderTarget)
            {
                this.set2f('uResolution', this.width, this.height);
            }

            renderer.resetTextures();
        }
    }

});

module.exports = BitmapMaskPipeline;
<commit_msg>The `BitmapMaskPipeline` now hands over most control of the framebuffers to the WebGLRenderer.<commit_after>/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @author       Felipe Alfonso <@bitnenfer>
 * @copyright    2022 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Class = require('../../../utils/Class');
var GetFastValue = require('../../../utils/object/GetFastValue');
var ShaderSourceFS = require('../shaders/BitmapMask-frag.js');
var ShaderSourceVS = require('../shaders/BitmapMask-vert.js');
var WEBGL_CONST = require('../const');
var WebGLPipeline = require('../WebGLPipeline');

/**
 * @classdesc
 * The Bitmap Mask Pipeline handles all of the bitmap mask rendering in WebGL for applying
 * alpha masks to Game Objects. It works by sampling two texture on the fragment shader and
 * using the fragments alpha to clip the region.
 *
 * The fragment shader it uses can be found in `shaders/src/BitmapMask.frag`.
 * The vertex shader it uses can be found in `shaders/src/BitmapMask.vert`.
 *
 * The default shader attributes for this pipeline are:
 *
 * `inPosition` (vec2, offset 0)
 *
 * The default shader uniforms for this pipeline are:
 *
 * `uResolution` (vec2)
 * `uMainSampler` (sampler2D)
 * `uMaskSampler` (sampler2D)
 * `uInvertMaskAlpha` (bool)
 *
 * @class BitmapMaskPipeline
 * @extends Phaser.Renderer.WebGL.WebGLPipeline
 * @memberof Phaser.Renderer.WebGL.Pipelines
 * @constructor
 * @since 3.0.0
 *
 * @param {Phaser.Types.Renderer.WebGL.WebGLPipelineConfig} config - The configuration options for this pipeline.
 */
var BitmapMaskPipeline = new Class({

    Extends: WebGLPipeline,

    initialize:

    function BitmapMaskPipeline (config)
    {
        config.fragShader = GetFastValue(config, 'fragShader', ShaderSourceFS),
        config.vertShader = GetFastValue(config, 'vertShader', ShaderSourceVS),
        config.batchSize = GetFastValue(config, 'batchSize', 1),
        config.vertices = GetFastValue(config, 'vertices', [ -1, 1, -1, -7, 7, 1 ]),
        config.attributes = GetFastValue(config, 'attributes', [
            {
                name: 'inPosition',
                size: 2,
                type: WEBGL_CONST.FLOAT
            }
        ]);

        WebGLPipeline.call(this, config);
    },

    boot: function ()
    {
        WebGLPipeline.prototype.boot.call(this);

        this.set1i('uMainSampler', 0);
        this.set1i('uMaskSampler', 1);
    },

    resize: function (width, height)
    {
        WebGLPipeline.prototype.resize.call(this, width, height);

        this.set2f('uResolution', width, height);
    },

    /**
     * Binds necessary resources and renders the mask to a separated framebuffer.
     * The framebuffer for the masked object is also bound for further use.
     *
     * @method Phaser.Renderer.WebGL.Pipelines.BitmapMaskPipeline#beginMask
     * @since 3.0.0
     *
     * @param {Phaser.Display.Masks.BitmapMask} mask - The BitmapMask instance that called beginMask.
     * @param {Phaser.GameObjects.GameObject} maskedObject - GameObject masked by the mask GameObject.
     * @param {Phaser.Cameras.Scene2D.Camera} camera - The camera rendering the current mask.
     */
    beginMask: function (mask, maskedObject, camera)
    {
        this.renderer.enableBitmapMask(mask, camera);
    },

    /**
     * The masked game objects framebuffer is unbound and its texture
     * is bound together with the mask texture and the mask shader and
     * a draw call with a single quad is processed. Here is where the
     * masking effect is applied.
     *
     * @method Phaser.Renderer.WebGL.Pipelines.BitmapMaskPipeline#endMask
     * @since 3.0.0
     *
     * @param {Phaser.Display.Masks.BitmapMask} mask - The BitmapMask instance that called endMask.
     * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to render to.
     * @param {Phaser.Renderer.WebGL.RenderTarget} [renderTarget] - Optional WebGL RenderTarget.
     */
    endMask: function (mask, camera, renderTarget)
    {
        var gl = this.gl;
        var renderer = this.renderer;

        //  The renderable Game Object that is being used for the bitmap mask
        var bitmapMask = mask.bitmapMask;

        if (bitmapMask && gl)
        {
            renderer.drawBitmapMask(bitmapMask, camera, this);

            if (renderTarget)
            {
                this.set2f('uResolution', renderTarget.width, renderTarget.height);
            }

            this.set1i('uInvertMaskAlpha', mask.invertAlpha);

            //  Finally, draw a triangle filling the whole screen
            gl.drawArrays(this.topology, 0, 3);

            if (renderTarget)
            {
                this.set2f('uResolution', this.width, this.height);
            }

            renderer.resetTextures();
        }
    }

});

module.exports = BitmapMaskPipeline;
<|endoftext|>


<commit_before>import $ from 'jquery'
import Dropdown from '../../com/dropdown'
import NavTree from '../../com/nav-tree'
import './api.scss'

const DEFAULT_VERSION = '1.3';
const LOCAL_STORAGE_KEY = 'targetApi';
const PLATFORM_AVAILABILITY = {
    'jvm': '1.0',
    'common': '1.2',
    'js': '1.1',
    'native': '1.3'
  };

const PLATFORM_ENRICH = {
    'jvm': ['JUnit', 'JUnit5', 'testng', 'JRE7', 'JRE8'].map((tag) => tag.toLowerCase())
};

function hideByTags($elements, state, checkTags, cls) {
  $elements.each((ind, element) => {
      const $element = $(element);
      $element.toggleClass(cls ? cls : 'hidden', !checkTags($element));
  });
}

function getMinVersion(a, b) {
  if (a > b) return b;
  return a;
}

function getTagPlatformName($tagElement) {
    return $tagElement
        .attr("class")
        .split(' ')
        .find((cls) => cls.startsWith('tag-value-'))
        .replace('tag-value-', '')
        .toLowerCase()
}

function updateState(state) {
  localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(state));

  const stateVersion = state.version ? state.version : DEFAULT_VERSION;
  const statePlatforms =
      state.platform
          .filter((platform) => PLATFORM_AVAILABILITY[platform] <= stateVersion)
          .reduce((acc, platform) => {
              const enrich = PLATFORM_ENRICH[platform];
              if (enrich) {
                  return acc.concat([platform, ...enrich]);
              }
              return acc.concat([platform]);
          }, []);

  for (const platform in PLATFORM_AVAILABILITY) {
    const $toggleElement = $(".toggle-platform." + platform);
    $toggleElement.toggleClass("disabled", PLATFORM_AVAILABILITY[platform] > stateVersion)
  }
  const minVersion = statePlatforms.map((platform) => PLATFORM_AVAILABILITY[platform]).reduce(getMinVersion, '1.0');

  hideByTags($('[data-platform]'), state, ($element) => {
    const versions = $element.attr('data-kotlin-version')
        .toLowerCase()
        .split(", ");
    return $element.attr('data-platform')
        .toLowerCase()
        .split(", ")
        .filter((tag, index) => versions[index] <= stateVersion)
        .some((tag) => statePlatforms.includes(tag))
  });
  hideByTags($('.tags__tag.platform'), state, ($element) => {
    if ($element.attr('data-tag-version') > stateVersion) return false;

    return statePlatforms.includes(getTagPlatformName($element))
  });

  $(".tags").each(
    (index, element) => {

      const $element = $(element);
      const activeVersions =
          $.map($element.find(".tags__tag:not(.hidden-version)"), (versionContainer) => $(versionContainer).attr('data-tag-version'));
      if (activeVersions.length === 0) return;
      const minVersion = activeVersions.reduce(getMinVersion);

      $element.children(".kotlin-version").text(minVersion);
    }
  );

  hideByTags($('.tags__tag.kotlin-version'), state, ($element) => $element.text() > minVersion, 'hidden-version');
}

function addSelectToPanel(panelElement, title, config) {
  const selectElement = $(`<div class="api-panel__select"><span class="api-panel__dropdown-title">${title}</span></div>`);
  $(panelElement).append(selectElement);
  new Dropdown(selectElement, config);
}

function addPlatformSelectToPanel(panelElement, config) {
  const selectElement = $(`<div class="api-panel_toggle"></div>`);
  $.each(config.items, (value, item) => {
    const itemElement = $(`<div class="toggle-platform ${value} ${item}"><span>`+item+`</span></div>`);
    selectElement.append(itemElement);
    if (!config.selected.includes(value)) {
      itemElement.addClass('off');
    }
    itemElement.click(() => {
      if (itemElement.hasClass('disabled')) return;
      itemElement.toggleClass('off');
      itemElement.addClass("pressed")
          .delay(200)
          .queue((next) => {
            itemElement.removeClass("pressed");
            next()
          });
      config.onSelect(value);
    });
  });
  $(panelElement).append(selectElement);

}

function fixPlatformsAvailability() {

    // TODO: This is hack to fix broken tag versions generated by Dokka :(
    $('.tags__tag.platform').each((index, element) => {
      const $element = $(element);
      const platformName = getTagPlatformName($element);
      const availability = PLATFORM_AVAILABILITY[platformName];
      if ($element.attr('data-tag-version') < availability) {
          $element.attr('data-tag-version', availability)
      }
    });
}

function initializeSelects() {
  const $breadcrumbs = $('.api-docs-breadcrumbs');
  if ($breadcrumbs.length > 0) {
    $breadcrumbs
      .wrap('

')
      .before('

');
  } else {
    $('.page-content').prepend('

');
  }

  const switchersPanel = $('.api-panel__switchers')[0];

  const state = localStorage.getItem(LOCAL_STORAGE_KEY) ?
    JSON.parse(localStorage.getItem(LOCAL_STORAGE_KEY)) :
    {
      platform: 'all'
    };
  if (state.platform === 'all') {
    state.platform = ['common', 'jvm', 'js', 'native'];
  }
  if ((typeof state.platform) === 'string') {
      state.platform = [state.platform];
  }

  addPlatformSelectToPanel(switchersPanel, {
    items: {
      'common': 'Common',
      'jvm': 'JVM',
      'js': 'JS',
      'native': 'Native'
    },
    selected: state.platform,
    onSelect: (platform) => {
      const index = state.platform.indexOf(platform);
      if (index !== -1) {
        state.platform.splice(index, 1);
      } else {
        state.platform.push(platform);
      }

      updateState(state);
    }
  });

  addSelectToPanel(switchersPanel, "Version", {
    items: {
      '1.0': '1.0',
      '1.1': '1.1',
      '1.2': '1.2',
      '1.3': '1.3'
    },
    selected: state.version != null ? state.version : DEFAULT_VERSION,
    onSelect: (version) => {
      if(version !== DEFAULT_VERSION){
        state.version = version;
      } else {
        delete state.version;
      }

      updateState(state)
    }
  });

  updateState(state);
}

function initializeSections() {
  $(".declarations").click((event) => {
    window.location.href = $(event.currentTarget).find("a:first").attr("href")
  });
}

$(document).ready(() => {
  fixPlatformsAvailability();
  initializeSelects();
  initializeSections();
  new NavTree(document.querySelector('.js-side-tree-nav'));
});
<commit_msg>chore(api docs): add 1.4 to api version selector and make it default<commit_after>import $ from 'jquery'
import Dropdown from '../../com/dropdown'
import NavTree from '../../com/nav-tree'
import './api.scss'

const DEFAULT_VERSION = '1.4';
const LOCAL_STORAGE_KEY = 'targetApi';
const PLATFORM_AVAILABILITY = {
    'jvm': '1.0',
    'common': '1.2',
    'js': '1.1',
    'native': '1.3'
  };

const PLATFORM_ENRICH = {
    'jvm': ['JUnit', 'JUnit5', 'testng', 'JRE7', 'JRE8'].map((tag) => tag.toLowerCase())
};

function hideByTags($elements, state, checkTags, cls) {
  $elements.each((ind, element) => {
      const $element = $(element);
      $element.toggleClass(cls ? cls : 'hidden', !checkTags($element));
  });
}

function getMinVersion(a, b) {
  if (a > b) return b;
  return a;
}

function getTagPlatformName($tagElement) {
    return $tagElement
        .attr("class")
        .split(' ')
        .find((cls) => cls.startsWith('tag-value-'))
        .replace('tag-value-', '')
        .toLowerCase()
}

function updateState(state) {
  localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(state));

  const stateVersion = state.version ? state.version : DEFAULT_VERSION;
  const statePlatforms =
      state.platform
          .filter((platform) => PLATFORM_AVAILABILITY[platform] <= stateVersion)
          .reduce((acc, platform) => {
              const enrich = PLATFORM_ENRICH[platform];
              if (enrich) {
                  return acc.concat([platform, ...enrich]);
              }
              return acc.concat([platform]);
          }, []);

  for (const platform in PLATFORM_AVAILABILITY) {
    const $toggleElement = $(".toggle-platform." + platform);
    $toggleElement.toggleClass("disabled", PLATFORM_AVAILABILITY[platform] > stateVersion)
  }
  const minVersion = statePlatforms.map((platform) => PLATFORM_AVAILABILITY[platform]).reduce(getMinVersion, '1.0');

  hideByTags($('[data-platform]'), state, ($element) => {
    const versions = $element.attr('data-kotlin-version')
        .toLowerCase()
        .split(", ");
    return $element.attr('data-platform')
        .toLowerCase()
        .split(", ")
        .filter((tag, index) => versions[index] <= stateVersion)
        .some((tag) => statePlatforms.includes(tag))
  });
  hideByTags($('.tags__tag.platform'), state, ($element) => {
    if ($element.attr('data-tag-version') > stateVersion) return false;

    return statePlatforms.includes(getTagPlatformName($element))
  });

  $(".tags").each(
    (index, element) => {

      const $element = $(element);
      const activeVersions =
          $.map($element.find(".tags__tag:not(.hidden-version)"), (versionContainer) => $(versionContainer).attr('data-tag-version'));
      if (activeVersions.length === 0) return;
      const minVersion = activeVersions.reduce(getMinVersion);

      $element.children(".kotlin-version").text(minVersion);
    }
  );

  hideByTags($('.tags__tag.kotlin-version'), state, ($element) => $element.text() > minVersion, 'hidden-version');
}

function addSelectToPanel(panelElement, title, config) {
  const selectElement = $(`<div class="api-panel__select"><span class="api-panel__dropdown-title">${title}</span></div>`);
  $(panelElement).append(selectElement);
  new Dropdown(selectElement, config);
}

function addPlatformSelectToPanel(panelElement, config) {
  const selectElement = $(`<div class="api-panel_toggle"></div>`);
  $.each(config.items, (value, item) => {
    const itemElement = $(`<div class="toggle-platform ${value} ${item}"><span>`+item+`</span></div>`);
    selectElement.append(itemElement);
    if (!config.selected.includes(value)) {
      itemElement.addClass('off');
    }
    itemElement.click(() => {
      if (itemElement.hasClass('disabled')) return;
      itemElement.toggleClass('off');
      itemElement.addClass("pressed")
          .delay(200)
          .queue((next) => {
            itemElement.removeClass("pressed");
            next()
          });
      config.onSelect(value);
    });
  });
  $(panelElement).append(selectElement);

}

function fixPlatformsAvailability() {

    // TODO: This is hack to fix broken tag versions generated by Dokka :(
    $('.tags__tag.platform').each((index, element) => {
      const $element = $(element);
      const platformName = getTagPlatformName($element);
      const availability = PLATFORM_AVAILABILITY[platformName];
      if ($element.attr('data-tag-version') < availability) {
          $element.attr('data-tag-version', availability)
      }
    });
}

function initializeSelects() {
  const $breadcrumbs = $('.api-docs-breadcrumbs');
  if ($breadcrumbs.length > 0) {
    $breadcrumbs
      .wrap('

')
      .before('

');
  } else {
    $('.page-content').prepend('

');
  }

  const switchersPanel = $('.api-panel__switchers')[0];

  const state = localStorage.getItem(LOCAL_STORAGE_KEY) ?
    JSON.parse(localStorage.getItem(LOCAL_STORAGE_KEY)) :
    {
      platform: 'all'
    };
  if (state.platform === 'all') {
    state.platform = ['common', 'jvm', 'js', 'native'];
  }
  if ((typeof state.platform) === 'string') {
      state.platform = [state.platform];
  }

  addPlatformSelectToPanel(switchersPanel, {
    items: {
      'common': 'Common',
      'jvm': 'JVM',
      'js': 'JS',
      'native': 'Native'
    },
    selected: state.platform,
    onSelect: (platform) => {
      const index = state.platform.indexOf(platform);
      if (index !== -1) {
        state.platform.splice(index, 1);
      } else {
        state.platform.push(platform);
      }

      updateState(state);
    }
  });

  addSelectToPanel(switchersPanel, "Version", {
    items: {
      '1.0': '1.0',
      '1.1': '1.1',
      '1.2': '1.2',
      '1.3': '1.3',
      '1.4': '1.4'
    },
    selected: state.version != null ? state.version : DEFAULT_VERSION,
    onSelect: (version) => {
      if(version !== DEFAULT_VERSION){
        state.version = version;
      } else {
        delete state.version;
      }

      updateState(state)
    }
  });

  updateState(state);
}

function initializeSections() {
  $(".declarations").click((event) => {
    window.location.href = $(event.currentTarget).find("a:first").attr("href")
  });
}

$(document).ready(() => {
  fixPlatformsAvailability();
  initializeSelects();
  initializeSections();
  new NavTree(document.querySelector('.js-side-tree-nav'));
});
<|endoftext|>


<commit_before>function read(URL, callback) {
    /**
    reads the contents of the file at the URL,
    converts it into a string, and then
    calls the callback function (which has no arguments)
    with "this" equalling the responseText
    */
    var file = new XMLHttpRequest();
    file.open("GET", URL);  // Don't add false as an extra argument (browsers don't like it). (default: asynchronous=true)
    file.onreadystatechange = function () {
        if(file.readyState === 4) {  // Is it done?
            if(file.status === 200 || file.status == 0) {  // Was it successful?
                // file.responseXML might have something
                callback.call(file.responseText);  // .call(calling object / value of "this", function arguments (listed individually))  .apply has function arguments in an array
                // You could also use callback(argument(s)) like a normal function, but it wouldn't change the value of "this".
            }
        }
    }
    file.send();
}

function pageJump(ID) {
    /**
    makes a section to jump to certain parts of the page
    */
    document.getElementsByTagName("h1")[0].id = "top";
    var division = document.getElementById(ID);
    var contents = document.createElement("div");
    contents.className = "list";
    contents.innerHTML = "

Jump to:
";
    var sections = division.getElementsByTagName("h2");
    var toTop = document.createElement("a");
    toTop.href = "#top";
    toTop.innerHTML = "To top";
    var listItems = "";  // I need this variable to hold the list items because trying to add
 at the beginning and
 at the end separately causes it to fill in the
 immediately after the
 and omit the real

    for (var index=0; index<sections.length; index++) {  // I would use (var in array), but index exceeds entries.length for no apparent reason
        var inside = sections[index].innerHTML.trim();  // The inner HTML has a bunch of whitespace for no apparent reason.
        sections[index].id = inside;
        listItems += "
" + inside + "
";
        division.insertBefore(toTop.cloneNode(true), division.getElementsByTagName("h2")[index].nextSibling);  // inserts after

        // toTop needs to be cloned so it doesn't keep getting reasigned to the next place (it also needs to have true to clone all children of the node, although it doesn't apply here)
    }
    contents.innerHTML += "
" + listItems + "

";
    document.body.insertBefore(contents, division);  // .insertBefore() only works for the immediate descendants of the parent
}

//This is able to run without waiting for anything else to load.

// makes my custom tag which overlines things
document.createElement("over");

// adds the universal formatting
var style = document.createElement("link");
style.rel = "stylesheet";
style.href = "https://coolprogramminguser.github.io/Standards/formatting.css";
document.head.insertBefore(style, document.head.children[0]);

// links a favicon
var faviconNumber = 1;
var icon = document.createElement("link");
icon.rel = "icon";
var circleColors = ["Red", "Yellow", "Green", "Cyan", "Blue", "Magenta"];
icon.href = "https://coolprogramminguser.github.io/Standards/favicons/Red Circle.ico";
document.head.insertBefore(icon, document.head.children[0]);

window.addEventListener("load", function() {  // This waits for everything past the script import to load before running.

    // surrounds the  content with a
 tag
    document.body.innerHTML = "
" + document.body.innerHTML + "
";

    // surrounds every list with

    var orderedLists = document.getElementsByTagName("ol");
    var unorderedLists = document.getElementsByTagName("ul");
    for (var index=0; index<orderedLists.length; index++) {
        orderedLists[index].outerHTML = "
" + orderedLists[index].outerHTML + "
";
    }
    for (var index=0; index<unorderedLists.length; index++) {
        unorderedLists[index].outerHTML = "
" + unorderedLists[index].outerHTML + "
";
    }

    // cycles the favicon
    setInterval(function() {
        icon.href = "https://coolprogramminguser.github.io/Standards/favicons/" + circleColors[faviconNumber] + " Circle.ico";
        faviconNumber = faviconNumber<circleColors.length-1 ? faviconNumber+1 : 0;
    }, 1000);
});
<commit_msg>made automatic title generation<commit_after>function read(URL, callback) {
    /**
    reads the contents of the file at the URL,
    converts it into a string, and then
    calls the callback function (which has no arguments)
    with "this" equalling the responseText
    */
    var file = new XMLHttpRequest();
    file.open("GET", URL);  // Don't add false as an extra argument (browsers don't like it). (default: asynchronous=true)
    file.onreadystatechange = function () {
        if(file.readyState === 4) {  // Is it done?
            if(file.status === 200 || file.status == 0) {  // Was it successful?
                // file.responseXML might have something
                callback.call(file.responseText);  // .call(calling object / value of "this", function arguments (listed individually))  .apply has function arguments in an array
                // You could also use callback(argument(s)) like a normal function, but it wouldn't change the value of "this".
            }
        }
    }
    file.send();
}

function pageJump(ID) {
    /**
    makes a section to jump to certain parts of the page
    */
    document.getElementsByTagName("h1")[0].id = "top";
    var division = document.getElementById(ID);
    var contents = document.createElement("div");
    contents.className = "list";
    contents.innerHTML = "

Jump to:
";
    var sections = division.getElementsByTagName("h2");
    var toTop = document.createElement("a");
    toTop.href = "#top";
    toTop.innerHTML = "To top";
    var listItems = "";  // I need this variable to hold the list items because trying to add
 at the beginning and
 at the end separately causes it to fill in the
 immediately after the
 and omit the real

    for (var index=0; index<sections.length; index++) {  // I would use (var in array), but index exceeds entries.length for no apparent reason
        var inside = sections[index].innerHTML.trim();  // The inner HTML has a bunch of whitespace for no apparent reason.
        sections[index].id = inside;
        listItems += "
" + inside + "
";
        division.insertBefore(toTop.cloneNode(true), division.getElementsByTagName("h2")[index].nextSibling);  // inserts after

        // toTop needs to be cloned so it doesn't keep getting reasigned to the next place (it also needs to have true to clone all children of the node, although it doesn't apply here)
    }
    contents.innerHTML += "
" + listItems + "

";
    document.body.insertBefore(contents, division);  // .insertBefore() only works for the immediate descendants of the parent
}

//This is able to run without waiting for anything else to load.

// makes my custom tag which overlines things
document.createElement("over");

// adds the universal formatting
var style = document.createElement("link");
style.rel = "stylesheet";
style.href = "https://coolprogramminguser.github.io/Standards/formatting.css";
document.head.insertBefore(style, document.head.children[0]);

// links a favicon
var faviconNumber = 1;
var icon = document.createElement("link");
icon.rel = "icon";
var circleColors = ["Red", "Yellow", "Green", "Cyan", "Blue", "Magenta"];
icon.href = "https://coolprogramminguser.github.io/Standards/favicons/Red Circle.ico";
document.head.insertBefore(icon, document.head.children[0]);

window.addEventListener("load", function() {  // This waits for everything past the script import to load before running.

    // surrounds the  content with a
 tag
    document.body.innerHTML = "
" + document.body.innerHTML + "
";

    // adds a title to the page
    var title = document.createElement("h1");
    title.innerHTML = document.getElementsByTagName("title")[0].innerHTML;
    document.body.insertBefore(title, document.body.children[0]);

    // surrounds every list with

    var orderedLists = document.getElementsByTagName("ol");
    var unorderedLists = document.getElementsByTagName("ul");
    for (var index=0; index<orderedLists.length; index++) {
        orderedLists[index].outerHTML = "
" + orderedLists[index].outerHTML + "
";
    }
    for (var index=0; index<unorderedLists.length; index++) {
        unorderedLists[index].outerHTML = "
" + unorderedLists[index].outerHTML + "
";
    }

    // cycles the favicon
    setInterval(function() {
        icon.href = "https://coolprogramminguser.github.io/Standards/favicons/" + circleColors[faviconNumber] + " Circle.ico";
        faviconNumber = faviconNumber<circleColors.length-1 ? faviconNumber+1 : 0;
    }, 1000);
});
<|endoftext|>


<commit_before>angular.module('team-task')
    .factory('SearchFactory', function SearchFactory(Pessoa, Projeto, Atividade, Time, $filter, $q) {
        SearchFactory.searchAll = function (text, scope) {
            scope.loadingSearch = true;
            var proms = [];
            scope.resultadoBusca = [];
            var proQuery = {
                "nome": {
                    "$regex": text + ".*",
                    "$options": "gi"
                }
            };
            proms.push(Projeto.query(proQuery).then(function (projetos) {

                angular.forEach(projetos, function (projeto) {
                    scope.resultadoBusca.push(
                        {
                            "nome": projeto.nome,
                            "tipo": "project",
                            "id": projeto._id.$oid
                        }
                    );
                });
            }));
            var proAtvQuery = {
                "atividades.nome": {
                    "$regex": text + ".*",
                    "$options": "gi"
                }
            };
            proms.push(Projeto.query(proAtvQuery).then(function (projetos) {
                angular.forEach(projetos, function (projeto) {
                    var proAtividades = $filter('filter')(projeto.atividades, {"nome": text});
                    if (proAtividades) {
                        angular.forEach(proAtividades, function (atividade) {
                            scope.resultadoBusca.push(
                                {
                                    "nome": projeto.nome + "/" + atividade.nome,
                                    "tipo": "project",
                                    "id": projeto._id.$oid
                                }
                            );
                        });
                    }
                });
            }));

            var nQuery = {
                "nome": {
                    "$regex": text + ".*",
                    "$options": "gi"
                }

            };
            proms.push(Atividade.query(nQuery).then(function (atividades) {
                angular.forEach(atividades, function (atividade) {
                    if(atividade.time) {
                        Time.getById(atividade.time).then(function (time) {
                            atividade.timeObj = time;
                            scope.resultadoBusca.push(
                                {
                                    "nome": time.nome + " / " + atividade.nome,
                                    "tipo": "team-activity",
                                    "id": atividade.time,
                                    "atividade": atividade
                                }
                            );
                        });
                    }
                });
            }));
            proms.push(Pessoa.query(nQuery).then(function (pessoas) {

                angular.forEach(pessoas, function (pessoa) {
                    scope.resultadoBusca.push(
                        {
                            "nome": pessoa.nome,
                            "tipo": "workforce",
                            "id": pessoa._id.$oid
                        }
                    );
                });
            }));

            proms.push(Time.query(nQuery).then(function (times) {
                angular.forEach(times, function (time) {
                    scope.resultadoBusca.push(
                        {
                            "nome": time.nome,
                            "tipo": "team-activities",
                            "id": time._id.$oid
                        }
                    );
                });
            }));
            $q.all(proms).then(function () {
                scope.loadingSearch = false;
            });

        };
        return SearchFactory;
    });<commit_msg>nova busca para atividades de time<commit_after>angular.module('team-task')
    .factory('SearchFactory', function SearchFactory(Pessoa, Projeto, Atividade, Time, $filter, $q, $rootScope) {
        SearchFactory.searchAll = function (text, scope) {
            scope.loadingSearch = true;
            var idusuario = $rootScope.usuarioLogado._id.$oid;
            var proms = [];
            scope.resultadoBusca = [];
            var proQuery = {
                "nome": {
                    "$regex": text + ".*",
                    "$options": "gi"
                },
                "$or": [
                    {"administrador": idusuario}
                    , {"atividades.designado": idusuario}]
            };
            proms.push(Projeto.query(proQuery).then(function (projetos) {

                angular.forEach(projetos, function (projeto) {
                    scope.resultadoBusca.push(
                        {
                            "nome": projeto.nome,
                            "tipo": "project",
                            "id": projeto._id.$oid
                        }
                    );
                });
            }));
            var proAtvQuery = {
                "atividades.nome": {
                    "$regex": text + ".*",
                    "$options": "gi"
                },
                "$or": [
                    {"administrador": idusuario}
                    , {"atividades.designado": idusuario}]
            };
            proms.push(Projeto.query(proAtvQuery).then(function (projetos) {
                angular.forEach(projetos, function (projeto) {
                    var proAtividades = $filter('filter')(projeto.atividades, {"nome": text});
                    if (proAtividades) {
                        angular.forEach(proAtividades, function (atividade) {
                            scope.resultadoBusca.push(
                                {
                                    "nome": projeto.nome + "/" + atividade.nome,
                                    "tipo": "project",
                                    "id": projeto._id.$oid
                                }
                            );
                        });
                    }
                });
            }));

            var aQuery = {
                "nome": {
                    "$regex": text + ".*",
                    "$options": "gi"
                }
            };
            proms.push(Atividade.query(aQuery).then(function (atividades) {
                angular.forEach(atividades, function (atividade) {
                    if(atividade.time) {
                        Time.getById(atividade.time).then(function (time) {
                            if(atividade.designado === idusuario || time.lider === idusuario) {
                                atividade.timeObj = time;
                                scope.resultadoBusca.push(
                                    {
                                        "nome": time.nome + " / " + atividade.nome,
                                        "tipo": "team-activity",
                                        "id": atividade.time,
                                        "atividade": atividade
                                    }
                                );
                            }
                        });
                    }
                });
            }));
            var peQuery = {
                "nome": {
                    "$regex": text + ".*",
                    "$options": "gi"
                },
                "$or": [
                    {"cadastrado": idusuario},
                    {"_id": { "$oid": idusuario } }
                ]
            };
            proms.push(Pessoa.query(peQuery).then(function (pessoas) {

                angular.forEach(pessoas, function (pessoa) {
                    scope.resultadoBusca.push(
                        {
                            "nome": pessoa.nome,
                            "tipo": "workforce",
                            "id": pessoa._id.$oid
                        }
                    );
                });
            }));

            var tQuery = {
                "nome": {
                    "$regex": text + ".*",
                    "$options": "gi"
                },
                "$or": [
                    {"lider": idusuario},
                    {"recursos": idusuario}
                ]
            };
            proms.push(Time.query(tQuery).then(function (times) {
                angular.forEach(times, function (time) {
                    scope.resultadoBusca.push(
                        {
                            "nome": time.nome,
                            "tipo": "team-activities",
                            "id": time._id.$oid
                        }
                    );
                });
            }));
            $q.all(proms).then(function () {
                scope.loadingSearch = false;
            });

        };
        return SearchFactory;
    });<|endoftext|>


<commit_before>import React, { Component, PropTypes } from 'react'
import './FirebaseChat.scss'

import Messages from './Messages'

export default class FirebaseChat extends Component {
  componentWillMount () {
    this.props.checkAuthentication()
  }

  componentDidMount () {
    let user = this.props.chat.user ? this.props.chat.user : prompt('What is your name?')
    user = user === null ? `user${Math.floor(Math.random() * 9000) + 1000}` : user
    this.props.addUser(user)
    this.messageInput.focus()
  }

  shouldComponentUpdate (nextProps) {
    // No Firebase Authentication Found
    if (this.props.chat.isAuthenticated === null && nextProps.chat.isAuthenticated === false) {
      return true
    }

    // Skip First Update Render
    if (!this.props.chat.isAuthenticated && !nextProps.chat.isAuthenticated) {
      return false
    }

    return true
  }

  componentWillUpdate (nextProps) {
    if (this.props.chat.isAuthenticated === null && nextProps.chat.isAuthenticated === false) {
      this.props.authenticateUser()
    }

    // Load Chat History
    if (!this.props.chat.isAuthenticated && nextProps.chat.isAuthenticated) {
      this.props.loadMessages()
    }
  }

  render () {
    const user = this.props.chat.user ? `@${this.props.chat.user}` : ''
    return (

{user}

                <input type='text' className='input is-medium is-expanded' placeholder='Message'
                  ref={(input) => { this.messageInput = input }}
                  onChange={this.props.handleChange} value={this.props.chat.message}
                  onKeyDown={this.props.handleSubmit} />

                  Send

            <Messages user={this.props.chat.user} messages={this.props.chat.messages} />

    )
  }
}

FirebaseChat.propTypes = {
  chat : PropTypes.object.isRequired,
  checkAuthentication: PropTypes.func.isRequired,
  authenticateUser: PropTypes.func.isRequired,
  loadMessages: PropTypes.func.isRequired,
  addUser: PropTypes.func.isRequired,
  handleChange : PropTypes.func.isRequired,
  handleSubmit : PropTypes.func.isRequired
}
<commit_msg>Fixed Empty User Input<commit_after>import React, { Component, PropTypes } from 'react'
import './FirebaseChat.scss'

import Messages from './Messages'

export default class FirebaseChat extends Component {
  componentWillMount () {
    this.props.checkAuthentication()
  }

  componentDidMount () {
    let user = this.props.chat.user ? this.props.chat.user : prompt('Hello! What is your name?')
    user = user === null || user === '' ? `user${Math.floor(Math.random() * 9000) + 1000}` : user
    this.props.addUser(user)
    this.messageInput.focus()
  }

  shouldComponentUpdate (nextProps) {
    // No Firebase Authentication Found
    if (this.props.chat.isAuthenticated === null && nextProps.chat.isAuthenticated === false) {
      return true
    }

    // Skip First Update Render
    if (!this.props.chat.isAuthenticated && !nextProps.chat.isAuthenticated) {
      return false
    }

    return true
  }

  componentWillUpdate (nextProps) {
    // No Firebase Authentication Found
    if (this.props.chat.isAuthenticated === null && nextProps.chat.isAuthenticated === false) {
      this.props.authenticateUser()
    }

    // Load Chat History
    if (!this.props.chat.isAuthenticated && nextProps.chat.isAuthenticated) {
      this.props.loadMessages()
    }
  }

  render () {
    const user = this.props.chat.user ? `@${this.props.chat.user}` : ''
    return (

{user}

                <input type='text' className='input is-medium is-expanded' placeholder='Message'
                  ref={(input) => { this.messageInput = input }}
                  onChange={this.props.handleChange} value={this.props.chat.message}
                  onKeyDown={this.props.handleSubmit} />

                  Send

            <Messages user={this.props.chat.user} messages={this.props.chat.messages} />

    )
  }
}

FirebaseChat.propTypes = {
  chat : PropTypes.object.isRequired,
  checkAuthentication: PropTypes.func.isRequired,
  authenticateUser: PropTypes.func.isRequired,
  loadMessages: PropTypes.func.isRequired,
  addUser: PropTypes.func.isRequired,
  handleChange : PropTypes.func.isRequired,
  handleSubmit : PropTypes.func.isRequired
}
<|endoftext|>


<commit_before>if (typeof sheltr === 'undefined' || !sheltr) {
  var sheltr = {};
}
sheltr.locations = (function ($) {
  var settings = {
        listRoot: $('ul.locations')
      },
      _self;

  function hasStatus(stat) {
    if (stat) {
      return '
Status: ' + stat + '
';
    } else {
      return '';
    }
  }

  function buildLocationsHTML(location) {
    var name = location.name ? location.name : '',
        addr = location.address1,
        id =  location.id,
        icon = _self.selectMarkerIcon(location),
        url = location.id,
        stat = location.status ? location.status : '',
        distance = _self.distanceFromUser(location);

    return '

' + name + '
<address>' + addr + '</address>
Distance: ' + distance + ' miles
' + hasStatus(stat) + '(View map)
';
  }

  _self = {
    list: function (locations) {
      var locationsHTML = '';
      _.each(locations, function(loc) {
        // TODO convert 'Y' to true in data
        if (sheltr.state.showFood == true && loc.isFood == 'Y' ||
          sheltr.state.showMedical == true && loc.isMedical == 'Y' ||
          sheltr.state.showShelter == true && loc.isShelter == 'Y') {
          locationsHTML += buildLocationsHTML(loc);
        }
      });
      if (sheltr.state.showFood == false && sheltr.state.showShelter == false) {
        $('#userMsg').show().empty().prepend("Please select Shelter and/or Food to see nearby locations.");
      }
      settings.listRoot.empty();
      settings.listRoot.addClass('visible');
      settings.listRoot.append(locationsHTML);

      $('ul.locations > li > a').click(function(){
        sheltr.map.zoomToMarker($(this).attr('id'));
        return false;
      });
    },

    selectMarkerIcon: function(location) {
      var icon

      if (location.isShelter === "Y" && location.isFood === "Y") {
        icon = '/img/shelter_food.png';
      } else if (location.isIntake === "Y") {
        icon = '/img/intake.png';
      } else if (location.isShelter === "Y") {
        icon = '/img/shelter.png';
      } else if (location.isFood === "Y") {
        icon = '/img/food.png';
      } else if (location.isMedical === "Y") {
        icon = '/img/medical.png';
      } else {
        icon = '/img/shelter.png'; //Mill Creek Baptist Church currently doesn't meet any of these conditions. This will give it the shelter icon (I'm assuming its a shelter).
      }
      return icon;
    },

    distanceFromUser: function(location) {
      var distance;
      distance = _self.distance(sheltr.state.userLocation.lat(),sheltr.state.userLocation.lng(), location.location.latitude, location.location.longitude);
      cleanDistance = Math.round(distance*10)/10
      return cleanDistance.toString();
    },

    /* Calculates distance between two points, original from: http://www.barattalo.it/examples/ruler.js */
    distance: function(lat1,lon1,lat2,lon2) {
      var R = 3959; // m (change this constant to get miles)
      var dLat = (lat2-lat1) * Math.PI / 180;
      var dLon = (lon2-lon1) * Math.PI / 180;
      var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
        Math.cos(lat1 * Math.PI / 180 ) * Math.cos(lat2 * Math.PI / 180 ) *
        Math.sin(dLon/2) * Math.sin(dLon/2);
      var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
      var d = R * c;
      return d;
    }

  };

  return _self;
})(jQuery);
<commit_msg>Fixed medical checkbox<commit_after>if (typeof sheltr === 'undefined' || !sheltr) {
  var sheltr = {};
}
sheltr.locations = (function ($) {
  var settings = {
        listRoot: $('ul.locations')
      },
      _self;

  function hasStatus(stat) {
    if (stat) {
      return '
Status: ' + stat + '
';
    } else {
      return '';
    }
  }

  function buildLocationsHTML(location) {
    var name = location.name ? location.name : '',
        addr = location.address1,
        id =  location.id,
        icon = _self.selectMarkerIcon(location),
        url = location.id,
        stat = location.status ? location.status : '',
        distance = _self.distanceFromUser(location);

    return '

' + name + '
<address>' + addr + '</address>
Distance: ' + distance + ' miles
' + hasStatus(stat) + '(View map)
';
  }

  _self = {
    list: function (locations) {
      var locationsHTML = '';
      _.each(locations, function(loc) {
        // TODO convert 'Y' to true in data
        if (sheltr.state.showFood == true && loc.isFood == 'Y' ||
          sheltr.state.showMedical == true && loc.isMedical == 'Y' ||
          sheltr.state.showShelter == true && loc.isShelter == 'Y') {
          locationsHTML += buildLocationsHTML(loc);
        }
      });
      if (sheltr.state.showFood == false && sheltr.state.showShelter == false && sheltr.state.showMedical == false) {
        $('#userMsg').show().empty().prepend("Please select Shelter, Food, or Medical to see nearby locations.");
      }
      settings.listRoot.empty();
      settings.listRoot.addClass('visible');
      settings.listRoot.append(locationsHTML);

      $('ul.locations > li > a').click(function(){
        sheltr.map.zoomToMarker($(this).attr('id'));
        return false;
      });
    },

    selectMarkerIcon: function(location) {
      var icon

      if (location.isShelter === "Y" && location.isFood === "Y") {
        icon = '/img/shelter_food.png';
      } else if (location.isIntake === "Y") {
        icon = '/img/intake.png';
      } else if (location.isShelter === "Y") {
        icon = '/img/shelter.png';
      } else if (location.isFood === "Y") {
        icon = '/img/food.png';
      } else if (location.isMedical === "Y") {
        icon = '/img/medical.png';
      } else {
        icon = '/img/shelter.png'; //Mill Creek Baptist Church currently doesn't meet any of these conditions. This will give it the shelter icon (I'm assuming its a shelter).
      }
      return icon;
    },

    distanceFromUser: function(location) {
      var distance;
      distance = _self.distance(sheltr.state.userLocation.lat(),sheltr.state.userLocation.lng(), location.location.latitude, location.location.longitude);
      cleanDistance = Math.round(distance*10)/10
      return cleanDistance.toString();
    },

    /* Calculates distance between two points, original from: http://www.barattalo.it/examples/ruler.js */
    distance: function(lat1,lon1,lat2,lon2) {
      var R = 3959; // m (change this constant to get miles)
      var dLat = (lat2-lat1) * Math.PI / 180;
      var dLon = (lon2-lon1) * Math.PI / 180;
      var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
        Math.cos(lat1 * Math.PI / 180 ) * Math.cos(lat2 * Math.PI / 180 ) *
        Math.sin(dLon/2) * Math.sin(dLon/2);
      var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
      var d = R * c;
      return d;
    }

  };

  return _self;
})(jQuery);
<|endoftext|>


<commit_before>'use strict';

const Promise  = require('bluebird');

module.exports = function (context) {
  return Promise.resolve().then(() => {
    const UglifyJS = require('uglify-js');

    let result = UglifyJS.minify(context.asset.source);

    if (result.error) throw result.error;

    // Special case for "browser-pack/prelude.js": if source will be empty after
    // compression - skip compression, because file may be included by macros.
    if (result.code !== '') {
      context.asset.source = result.code;
    }
  });
};
<commit_msg>Fix minification issue<commit_after>'use strict';

const Promise  = require('bluebird');

module.exports = function (context) {
  return Promise.resolve().then(() => {
    const UglifyJS = require('uglify-js');

    let result = UglifyJS.minify(context.asset.source, {
      // turn off side effects to prevent uglify from simplifying
      // "browser-pack/prelude.js" IIFE down to a constant
      compress: { side_effects: false }
    });

    if (result.error) throw result.error;

    // Special case for "browser-pack/prelude.js": if source will be empty after
    // compression - skip compression, because file may be included by macros.
    if (result.code !== '') {
      context.asset.source = result.code;
    }
  });
};
<|endoftext|>


<commit_before>'use strict';

var dependencies = [
    'ngRoute',
    'ngSanitize',
];

var app = angular.module('searchResults', dependencies);

app.controller('SearchCtrl', ['$location', '$http', '$scope', function($location, $http, $scope) {
    var controller = this
    controller.siteHits = [];
    controller.lineHits = [];

    var siteSearch = function(q) {
        var postBody = {
            _source: ['url', 'title'],
            query: {
                match_phrase: {
                    content: q
                }
            },
            highlight: {
                fields: {
                    content: {}
                },
                pre_tags: [''], post_tags: ['']
            }
        }
        $http.post('/lines/api/sitemap/_search', postBody).then(
            function(response) {
                controller.siteHits = response.data.hits;
            }
        );
    }

    var linesSearch = function(q) {
        var postBody = {
            query: {
                multi_match: {
                    query: q,
                    fields: ['searchable.free', 'searchable.fixed^3'],
                    type: "most_fields",
                }
            }
        }
        $http.post('/lines/api/cellLine/_search', postBody).then(
            function(response) {
                controller.lineHits = response.data.hits;
            }
        );
    }

    var search = function() {
        controller.searchPhrase = $location.search().q;
        if (controller.searchPhrase) {
            siteSearch(controller.searchPhrase)
            linesSearch(controller.searchPhrase)
        }
        else {
            controller.siteHits = [];
            controller.lineHits = [];
        }
    };

    $scope.$on('$locationChangeStart', search);
    search();
}]);

app.directive('lineHits', function() {
    return {
        restrict: 'E',
        scope: 'false',
        template:
  '
'
+ '
 matching cell line 1">s
'
+ '
'
+ '

'
+ '
'
+ 'Cell line search results in the lines and data browser'
+ '
'
    };
});
<commit_msg>search results styling<commit_after>'use strict';

var dependencies = [
    'ngRoute',
    'ngSanitize',
];

var app = angular.module('searchResults', dependencies);

app.controller('SearchCtrl', ['$location', '$http', '$scope', function($location, $http, $scope) {
    var controller = this
    controller.siteHits = [];
    controller.lineHits = [];

    var siteSearch = function(q) {
        var postBody = {
            _source: ['url', 'title'],
            query: {
                match_phrase: {
                    content: q
                }
            },
            highlight: {
                fields: {
                    content: {}
                },
                pre_tags: [''], post_tags: ['']
            }
        }
        $http.post('/lines/api/sitemap/_search', postBody).then(
            function(response) {
                controller.siteHits = response.data.hits;
            }
        );
    }

    var linesSearch = function(q) {
        var postBody = {
            query: {
                multi_match: {
                    query: q,
                    fields: ['searchable.free', 'searchable.fixed^3'],
                    type: "most_fields",
                }
            }
        }
        $http.post('/lines/api/cellLine/_search', postBody).then(
            function(response) {
                controller.lineHits = response.data.hits;
            }
        );
    }

    var search = function() {
        controller.searchPhrase = $location.search().q;
        if (controller.searchPhrase) {
            siteSearch(controller.searchPhrase)
            linesSearch(controller.searchPhrase)
        }
        else {
            controller.siteHits = [];
            controller.lineHits = [];
        }
    };

    $scope.$on('$locationChangeStart', search);
    search();
}]);

app.directive('lineHits', function() {
    return {
        restrict: 'E',
        scope: 'false',
        template:
  '
'
+ '
 matching cell line 1">s
'
+ '

'
+ '

'
+ '
'
+ '

Cell line search results in the lines and data browser

'
+ '

'
    };
});
<|endoftext|>


<commit_before>import PropTypes from 'prop-types'
import React from 'react'
import Icon from 'components/Icon'
import './SongItem.css'

export const SongItem = (props) => (

      {toMMSS(props.duration)}

      {props.title} {props.numMedia > 1 ? `(${props.numMedia})` : ''}

      <Icon size={32} icon='MORE_HORIZ' styleName='infoIcon' />

      <Icon size={44} icon={props.isStarred ? 'STAR_FULL' : 'STAR_EMPTY'}
        styleName={props.isStarred ? 'starIconFull' : 'starIcon'}
      />

{props.numStars}

)

SongItem.propTypes = {
  title: PropTypes.string.isRequired,
  duration: PropTypes.number.isRequired,
  style: PropTypes.object,
  onSongClick: PropTypes.func.isRequired,
  onSongStarClick: PropTypes.func.isRequired,
  isQueued: PropTypes.bool.isRequired,
  isStarred: PropTypes.bool.isRequired,
  numStars: PropTypes.number.isRequired,
  numMedia: PropTypes.number.isRequired,
}

export default SongItem

// convert seconds to mm:ss
function toMMSS (duration) {
  const min = Math.floor(duration / 60)
  const sec = duration - (min * 60)
  return min + ':' + (sec < 10 ? '0' + sec : sec)
}
<commit_msg>Italicize song media count<commit_after>import PropTypes from 'prop-types'
import React from 'react'
import Icon from 'components/Icon'
import './SongItem.css'

export const SongItem = (props) => (

      {toMMSS(props.duration)}

      {props.title}
      {props.numMedia > 1 &&
         ({props.numMedia})
      }

      <Icon size={32} icon='MORE_HORIZ' styleName='infoIcon' />

      <Icon size={44} icon={props.isStarred ? 'STAR_FULL' : 'STAR_EMPTY'}
        styleName={props.isStarred ? 'starIconFull' : 'starIcon'}
      />

{props.numStars}

)

SongItem.propTypes = {
  title: PropTypes.string.isRequired,
  duration: PropTypes.number.isRequired,
  style: PropTypes.object,
  onSongClick: PropTypes.func.isRequired,
  onSongStarClick: PropTypes.func.isRequired,
  isQueued: PropTypes.bool.isRequired,
  isStarred: PropTypes.bool.isRequired,
  numStars: PropTypes.number.isRequired,
  numMedia: PropTypes.number.isRequired,
}

export default SongItem

// convert seconds to mm:ss
function toMMSS (duration) {
  const min = Math.floor(duration / 60)
  const sec = duration - (min * 60)
  return min + ':' + (sec < 10 ? '0' + sec : sec)
}
<|endoftext|>


<commit_before>/*  Super Search
    Author: Kushagra Gour (http://kushagragour.in)
    MIT Licensed
*/

(function () {
    var isSearchOpen = false,
        searchEl = document.querySelector('#js-search'),
        searchInputEl = document.querySelector('#js-search__input'),
        searchResultsEl = document.querySelector('#js-search__results'),
        currentInputValue = '',
        lastSearchResultHash,
        posts = [],
        sitemap = 'http://www.abheyrana.me/sitemap.xml';

    // Changes XML to JSON
    // Modified version from here: http://davidwalsh.name/convert-xml-json
    function xmlToJson(xml) {

        // Create the return object
        var obj = {};

        if (xml.nodeType == 1) { // element
            // do attributes
            if (xml.attributes.length > 0) {
            obj["@attributes"] = {};
                for (var j = 0; j < xml.attributes.length; j++) {
                    var attribute = xml.attributes.item(j);
                    obj["@attributes"][attribute.nodeName] = attribute.nodeValue;
                }
            }
        } else if (xml.nodeType == 3) { // text
            obj = xml.nodeValue;
        }

        // do children
        // If all text nodes inside, get concatenated text from them.
        var textNodes = [].slice.call(xml.childNodes).filter(function (node) { return node.nodeType === 3; });
        if (xml.hasChildNodes() && xml.childNodes.length === textNodes.length) {
            obj = [].slice.call(xml.childNodes).reduce(function (text, node) { return text + node.nodeValue; }, '');
        }
        else if (xml.hasChildNodes()) {
            for(var i = 0; i < xml.childNodes.length; i++) {
                var item = xml.childNodes.item(i);
                var nodeName = item.nodeName;
                if (typeof(obj[nodeName]) == "undefined") {
                    obj[nodeName] = xmlToJson(item);
                } else {
                    if (typeof(obj[nodeName].push) == "undefined") {
                        var old = obj[nodeName];
                        obj[nodeName] = [];
                        obj[nodeName].push(old);
                    }
                    obj[nodeName].push(xmlToJson(item));
                }
            }
        }
        return obj;
    }

    function getPostsFromXml(xml) {
        var json = xmlToJson(xml);
        return json.channel.item;
    }

    var xmlhttp=new XMLHttpRequest();
    xmlhttp.open("GET",sitemap);
    xmlhttp.onreadystatechange = function () {
        if (xmlhttp.readyState != 4) return;
        if (xmlhttp.status != 200 && xmlhttp.status != 304) { return; }
        var node = (new DOMParser).parseFromString(xmlhttp.responseText, 'text/xml');
        node = node.children[0];
        posts = getPostsFromXml(node);
    }
    xmlhttp.send();

    window.toggleSearch = function toggleSearch() {
        _gaq.push(['_trackEvent', 'supersearch', searchEl.classList.contains('is-active')]);
        searchEl.classList.toggle('is-active');
        if (searchEl.classList.contains('is-active')) {
            // while opening
            searchInputEl.value = '';
        } else {
            // while closing
            searchResultsEl.classList.add('is-hidden');
        }
        setTimeout(function () {
            searchInputEl.focus();
        }, 210);
    }

    window.addEventListener('keyup', function onKeyPress(e) {
        if (e.which === 27) {
            toggleSearch();
        }
    });
    window.addEventListener('keypress', function onKeyPress(e) {
        if (e.which === 47 && !searchEl.classList.contains('is-active')) {
            toggleSearch();
        }
    });

    searchInputEl.addEventListener('input', function onInputChange() {
        var currentResultHash, d;

        currentInputValue = (searchInputEl.value + '').toLowerCase();
        if (!currentInputValue || currentInputValue.length < 3) {
            lastSearchResultHash = '';
            searchResultsEl.classList.add('is-hidden');
            return;
        }
        searchResultsEl.style.offsetWidth;

        var matchingPosts = posts.filter(function (post) {
            if ((post.title + '').toLowerCase().indexOf(currentInputValue) !== -1 || (post.description + '').toLowerCase().indexOf(currentInputValue) !== -1) {
                return true;
            }
        });
        if (!matchingPosts.length) {
            searchResultsEl.classList.add('is-hidden');
        }
        currentResultHash = matchingPosts.reduce(function(hash, post) { return post.title + hash; }, '');
        if (matchingPosts.length && currentResultHash !== lastSearchResultHash) {
            searchResultsEl.classList.remove('is-hidden');
            searchResultsEl.innerHTML = matchingPosts.map(function (post) {
                d = new Date(post.pubDate);
                return '
' + post.title + '' + d.toUTCString().replace(/.*(\d{2})\s+(\w{3})\s+(\d{4}).*/,'$2 $1, $3') + '
';
            }).join('');
        }
        lastSearchResultHash = currentResultHash;
    });

})();<commit_msg>Trying more to resolve super search bug - 4<commit_after>/*  Super Search
    Author: Kushagra Gour (http://kushagragour.in)
    MIT Licensed
*/

(function () {
    var isSearchOpen = false,
        searchEl = document.querySelector('#js-search'),
        searchInputEl = document.querySelector('#js-search__input'),
        searchResultsEl = document.querySelector('#js-search__results'),
        currentInputValue = '',
        lastSearchResultHash,
        posts = [],
        sitemap = 'http://www.abheyrana.me/sitemap.xml';

    // Changes XML to JSON
    // Modified version from here: http://davidwalsh.name/convert-xml-json
    function xmlToJson(xml) {

        // Create the return object
        var obj = {};

        if (xml.nodeType == 1) { // element
            // do attributes
            if (xml.attributes.length > 0) {
            obj["@attributes"] = {};
                for (var j = 0; j < xml.attributes.length; j++) {
                    var attribute = xml.attributes.item(j);
                    obj["@attributes"][attribute.nodeName] = attribute.nodeValue;
                }
            }
        } else if (xml.nodeType == 3) { // text
            obj = xml.nodeValue;
        }

        // do children
        // If all text nodes inside, get concatenated text from them.
        var textNodes = [].slice.call(xml.childNodes).filter(function (node) { return node.nodeType === 3; });
        if (xml.hasChildNodes() && xml.childNodes.length === textNodes.length) {
            obj = [].slice.call(xml.childNodes).reduce(function (text, node) { return text + node.nodeValue; }, '');
        }
        else if (xml.hasChildNodes()) {
            for(var i = 0; i < xml.childNodes.length; i++) {
                var item = xml.childNodes.item(i);
                var nodeName = item.nodeName;
                if (typeof(obj[nodeName]) == "undefined") {
                    obj[nodeName] = xmlToJson(item);
                } else {
                    if (typeof(obj[nodeName].push) == "undefined") {
                        var old = obj[nodeName];
                        obj[nodeName] = [];
                        obj[nodeName].push(old);
                    }
                    obj[nodeName].push(xmlToJson(item));
                }
            }
        }
        return obj;
    }

    function getPostsFromXml(xml) {
        var json = xmlToJson(xml);
        return json.channel.item;
    }

    var xmlhttp=new XMLHttpRequest();
    xmlhttp.open("GET",sitemap);
    xmlhttp.onreadystatechange = function () {
        if (xmlhttp.readyState != 4) return;
        if (xmlhttp.status != 200 && xmlhttp.status != 304) { return; }
        var node = (new DOMParser).parseFromString(xmlhttp.responseText, 'text/xml');
        node = node.children[0];
        posts = getPostsFromXml(node);
    }
    xmlhttp.send();

    window.toggleSearch = function toggleSearch() {
        _gaq.push(['_trackEvent', 'supersearch', searchEl.classList.contains('is-active')]);
        searchEl.classList.toggle('is-active');
        if (searchEl.classList.contains('is-active')) {
            // while opening
            searchInputEl.value = '';
        } else {
            // while closing
            searchResultsEl.classList.add('is-hidden');
        }
        setTimeout(function () {
            searchInputEl.focus();
        }, 210);
    }

    window.addEventListener('keyup', function onKeyPress(e) {
        if (e.which === 27) {
            toggleSearch();
        }
    });
    window.addEventListener('keypress', function onKeyPress(e) {
        if (e.which === 47 && !searchEl.classList.contains('is-active')) {
            toggleSearch();
        }
    });

    searchInputEl.addEventListener('input', function onInputChange() {
        var currentResultHash, d;

        currentInputValue = (searchInputEl.value + '').toLowerCase();
        if (!currentInputValue || currentInputValue.length < 3) {
            lastSearchResultHash = '';
            searchResultsEl.classList.add('is-hidden');
            return;
        }
        searchResultsEl.style.offsetWidth;

        var matchingPosts = posts.filter(function (post) {
            if ((post.title + '').toLowerCase().indexOf(currentInputValue) !== -1 || (post.description + '').toLowerCase().indexOf(currentInputValue) !== -1) {
                return true;
            }
        });
        if (!matchingPosts.length) {
            searchResultsEl.classList.add('is-hidden');
        }
        currentResultHash = matchingPosts.reduce(function(hash, post) { return post.title + hash; }, '');
        if (matchingPosts.length && currentResultHash !== lastSearchResultHash) {
            searchResultsEl.classList.remove('is-hidden');
            searchResultsEl.innerHTML = matchingPosts.map(function (post) {
                d = new Date(post.pubDate);
                str = post.link.substr(0,5);
                if(str == 'https')
                    return '
' + post.title + '' + d.toUTCString().replace(/.*(\d{2})\s+(\w{3})\s+(\d{4}).*/,'$2 $1, $3') + '
';
                else
                    return '
' + post.title + '' + d.toUTCString().replace(/.*(\d{2})\s+(\w{3})\s+(\d{4}).*/,'$2 $1, $3') + '
';
            }).join('');
        }
        lastSearchResultHash = currentResultHash;
    });

})();<|endoftext|>