<commit_before>import {
  callApiSync
} from '../util'

import {
  invoke
} from '../../bridge'

let waiting
let waitingTimeout
let toast = false
let toastTimeout

export function showLoading (args) {
  return callApiSync(showToast, args, 'showToast', 'showLoading')
}

export function hideLoading () {
  return callApiSync(hideToast, Object.create(null), 'hideToast', 'hideLoading')
}

export function showToast ({
  title = '',
  icon = 'success',
  image = '',
  duration = 1500,
  mask = false,
  position = ''
} = {}) {
  if (position) {
    if (toast) {
      toastTimeout && clearTimeout(toastTimeout)
      plus.nativeUI.closeToast()
    }
    if (waiting) {
      waitingTimeout && clearTimeout(waitingTimeout)
      waiting.close()
    }
    if (~['top', 'center', 'bottom'].indexOf(position)) {
      const richText = `<span>${title}</span>`
      plus.nativeUI.toast(richText, {
        verticalAlign: position,
        type: 'richtext'
      })
      toast = true
      toastTimeout = setTimeout(() => {
        hideToast()
      }, 2000)
      return {
        errMsg: 'showToast:ok'
      }
    }
    console.warn('uni.showToast 传入的 "position" 值 "' + position + '" 无效')
  }

  if (duration) {
    if (waiting) {
      waitingTimeout && clearTimeout(waitingTimeout)
      waiting.close()
    }
    if (toast) {
      toastTimeout && clearTimeout(toastTimeout)
      plus.nativeUI.closeToast()
    }
    if (icon && !~['success', 'loading', 'none'].indexOf(icon)) {
      icon = 'success'
    }
    const waitingOptions = {
      modal: mask,
      back: 'transmit',
      padding: '10px',
      size: '16px' // 固定字体大小
    }
    if (!image && (!icon || icon === 'none')) { // 无图
      //       waitingOptions.width = '120px'
      //       waitingOptions.height = '40px'
      waitingOptions.loading = {
        display: 'none'
      }
    } else { // 有图
      waitingOptions.width = '140px'
      waitingOptions.height = '112px'
    }
    if (image) {
      waitingOptions.loading = {
        display: 'block',
        height: '55px',
        icon: image,
        interval: duration
      }
    } else {
      if (icon === 'success') {
        waitingOptions.loading = {
          display: 'block',
          height: '55px',
          icon: '__uniappsuccess.png',
          interval: duration

        }
      }
    }

    waiting = plus.nativeUI.showWaiting(title, waitingOptions)
    waitingTimeout = setTimeout(() => {
      hideToast()
    }, duration)
  }
  return {
    errMsg: 'showToast:ok'
  }
}

export function hideToast () {
  if (toast) {
    toastTimeout && clearTimeout(toastTimeout)
    plus.nativeUI.closeToast()
    toast = false
  }
  if (waiting) {
    waitingTimeout && clearTimeout(waitingTimeout)
    waiting.close()
    waiting = null
    waitingTimeout = null
  }
  return {
    errMsg: 'hideToast:ok'
  }
}
export function showModal ({
  title = '',
  content = ' ',
  showCancel = true,
  cancelText = '取消',
  cancelColor = '#000000',
  confirmText = '确定',
  confirmColor = '#3CC51F'
} = {}, callbackId) {
  plus.nativeUI.confirm(content, (e) => {
    if (showCancel) {
      invoke(callbackId, {
        errMsg: 'showModal:ok',
        confirm: e.index === 1,
        cancel: e.index === 0 || e.index === -1
      })
    } else {
      invoke(callbackId, {
        errMsg: 'showModal:ok',
        confirm: e.index === 0,
        cancel: false
      })
    }
  }, title, showCancel ? [cancelText, confirmText] : [confirmText])
}
export function showActionSheet ({
  itemList = [],
  itemColor = '#000000',
  title = '',
  popover
}, callbackId) {
  const options = {
    buttons: itemList.map(item => ({
      title: item,
      color: itemColor
    }))
  }
  if (title) {
    options.title = title
  }

  if (plus.os.name === 'iOS') {
    options.cancel = ''
  }

  plus.nativeUI.actionSheet(Object.assign(options, { popover }), (e) => {
    if (e.index > 0) {
      invoke(callbackId, {
        errMsg: 'showActionSheet:ok',
        tapIndex: e.index - 1
      })
    } else {
      invoke(callbackId, {
        errMsg: 'showActionSheet:fail cancel'
      })
    }
  })
}
<commit_msg>chore: update showModal<commit_after>import {
  callApiSync
} from '../util'

import {
  invoke
} from '../../bridge'

let waiting
let waitingTimeout
let toast = false
let toastTimeout

export function showLoading (args) {
  return callApiSync(showToast, args, 'showToast', 'showLoading')
}

export function hideLoading () {
  return callApiSync(hideToast, Object.create(null), 'hideToast', 'hideLoading')
}

export function showToast ({
  title = '',
  icon = 'success',
  image = '',
  duration = 1500,
  mask = false,
  position = ''
} = {}) {
  if (position) {
    if (toast) {
      toastTimeout && clearTimeout(toastTimeout)
      plus.nativeUI.closeToast()
    }
    if (waiting) {
      waitingTimeout && clearTimeout(waitingTimeout)
      waiting.close()
    }
    if (~['top', 'center', 'bottom'].indexOf(position)) {
      const richText = `<span>${title}</span>`
      plus.nativeUI.toast(richText, {
        verticalAlign: position,
        type: 'richtext'
      })
      toast = true
      toastTimeout = setTimeout(() => {
        hideToast()
      }, 2000)
      return {
        errMsg: 'showToast:ok'
      }
    }
    console.warn('uni.showToast 传入的 "position" 值 "' + position + '" 无效')
  }

  if (duration) {
    if (waiting) {
      waitingTimeout && clearTimeout(waitingTimeout)
      waiting.close()
    }
    if (toast) {
      toastTimeout && clearTimeout(toastTimeout)
      plus.nativeUI.closeToast()
    }
    if (icon && !~['success', 'loading', 'none'].indexOf(icon)) {
      icon = 'success'
    }
    const waitingOptions = {
      modal: mask,
      back: 'transmit',
      padding: '10px',
      size: '16px' // 固定字体大小
    }
    if (!image && (!icon || icon === 'none')) { // 无图
      //       waitingOptions.width = '120px'
      //       waitingOptions.height = '40px'
      waitingOptions.loading = {
        display: 'none'
      }
    } else { // 有图
      waitingOptions.width = '140px'
      waitingOptions.height = '112px'
    }
    if (image) {
      waitingOptions.loading = {
        display: 'block',
        height: '55px',
        icon: image,
        interval: duration
      }
    } else {
      if (icon === 'success') {
        waitingOptions.loading = {
          display: 'block',
          height: '55px',
          icon: '__uniappsuccess.png',
          interval: duration

        }
      }
    }

    waiting = plus.nativeUI.showWaiting(title, waitingOptions)
    waitingTimeout = setTimeout(() => {
      hideToast()
    }, duration)
  }
  return {
    errMsg: 'showToast:ok'
  }
}

export function hideToast () {
  if (toast) {
    toastTimeout && clearTimeout(toastTimeout)
    plus.nativeUI.closeToast()
    toast = false
  }
  if (waiting) {
    waitingTimeout && clearTimeout(waitingTimeout)
    waiting.close()
    waiting = null
    waitingTimeout = null
  }
  return {
    errMsg: 'hideToast:ok'
  }
}
export function showModal ({
  title = '',
  content = '',
  showCancel = true,
  cancelText = '取消',
  cancelColor = '#000000',
  confirmText = '确定',
  confirmColor = '#3CC51F'
} = {}, callbackId) {
  content = content || ' '
  plus.nativeUI.confirm(content, (e) => {
    if (showCancel) {
      invoke(callbackId, {
        errMsg: 'showModal:ok',
        confirm: e.index === 1,
        cancel: e.index === 0 || e.index === -1
      })
    } else {
      invoke(callbackId, {
        errMsg: 'showModal:ok',
        confirm: e.index === 0,
        cancel: false
      })
    }
  }, title, showCancel ? [cancelText, confirmText] : [confirmText])
}
export function showActionSheet ({
  itemList = [],
  itemColor = '#000000',
  title = '',
  popover
}, callbackId) {
  const options = {
    buttons: itemList.map(item => ({
      title: item,
      color: itemColor
    }))
  }
  if (title) {
    options.title = title
  }

  if (plus.os.name === 'iOS') {
    options.cancel = ''
  }

  plus.nativeUI.actionSheet(Object.assign(options, { popover }), (e) => {
    if (e.index > 0) {
      invoke(callbackId, {
        errMsg: 'showActionSheet:ok',
        tapIndex: e.index - 1
      })
    } else {
      invoke(callbackId, {
        errMsg: 'showActionSheet:fail cancel'
      })
    }
  })
}
<|endoftext|>


<commit_before>import _ from 'lodash';
import WrappingQueryBuilderOperation from './WrappingQueryBuilderOperation';

export default class SelectOperation extends WrappingQueryBuilderOperation {

  constructor(name, opt) {
    super(name, opt);
    this.selections = [];
  }

  static parseSelection(selection) {
    if (!_.isString(selection)) {
      return null;
    }

    // Discard the possible alias.
    selection = selection.split(/\s+as\s+}/i)[0].trim();
    const dotIdx = selection.indexOf('.');

    if (dotIdx !== -1) {
      return {
        table: selection.substr(0, dotIdx),
        column: selection.substr(dotIdx + 1)
      };
    } else {
      return {
        table: null,
        column: selection
      };
    }
  }

  call(builder, args) {
    const selections = _.flatten(args);

    // Don't add an empty selection.
    if (selections.length === 0) {
      return false;
    }

    const ret = super.call(builder, selections);

    for (let i = 0, l = selections.length; i < l; ++i) {
      const selection = SelectOperation.parseSelection(selections[i]);

      if (selection) {
        this.selections.push(selection);
      }
    }

    return ret;
  }

  onBuild(builder) {
    builder[this.name].apply(builder, this.args);
  }

  hasSelection(fromTable, selection) {
    const testSelect = SelectOperation.parseSelection(selection);

    if (!testSelect) {
      return false;
    }

    const testTable = testSelect.table || fromTable;
    const testColumn = testSelect.column;

    for (let i = 0, l = this.selections.length; i < l; ++i) {
      const table = this.selections[i].table || fromTable;
      const column = this.selections[i].column;

      if (testTable == table && (column === testColumn || column === '*')) {
        return true;
      }
    }

    return false;
  }
}<commit_msg>fix borked regex in SelectOperation<commit_after>import _ from 'lodash';
import WrappingQueryBuilderOperation from './WrappingQueryBuilderOperation';

export default class SelectOperation extends WrappingQueryBuilderOperation {

  constructor(name, opt) {
    super(name, opt);
    this.selections = [];
  }

  static parseSelection(selection) {
    if (!_.isString(selection)) {
      return null;
    }

    // Discard the possible alias.
    selection = selection.split(/\s+as\s+/i)[0].trim();
    const dotIdx = selection.indexOf('.');

    if (dotIdx !== -1) {
      return {
        table: selection.substr(0, dotIdx),
        column: selection.substr(dotIdx + 1)
      };
    } else {
      return {
        table: null,
        column: selection
      };
    }
  }

  call(builder, args) {
    const selections = _.flatten(args);

    // Don't add an empty selection.
    if (selections.length === 0) {
      return false;
    }

    const ret = super.call(builder, selections);

    for (let i = 0, l = selections.length; i < l; ++i) {
      const selection = SelectOperation.parseSelection(selections[i]);

      if (selection) {
        this.selections.push(selection);
      }
    }

    return ret;
  }

  onBuild(builder) {
    builder[this.name].apply(builder, this.args);
  }

  hasSelection(fromTable, selection) {
    const testSelect = SelectOperation.parseSelection(selection);

    if (!testSelect) {
      return false;
    }

    const testTable = testSelect.table || fromTable;
    const testColumn = testSelect.column;

    for (let i = 0, l = this.selections.length; i < l; ++i) {
      const table = this.selections[i].table || fromTable;
      const column = this.selections[i].column;

      if (testTable == table && (column === testColumn || column === '*')) {
        return true;
      }
    }

    return false;
  }
}<|endoftext|>


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

var Class = require('../../../utils/Class');
var GetFastValue = require('../../../utils/object/GetFastValue');
var ModelViewProjection = require('./components/ModelViewProjection');
var MultiPipeline = require('./MultiPipeline');
var ShaderSourceFS = require('../shaders/Single-frag.js');
var ShaderSourceVS = require('../shaders/Single-vert.js');
var WebGLPipeline = require('../WebGLPipeline');

/**
 * @classdesc
 *
 * The Single Pipeline is a special version of the Multi Pipeline that only ever
 * uses one single texture, bound to texture unit zero. Although not as efficient as the
 * Multi Pipeline, it provides an easier way to create custom pipelines that only require
 * a single bound texture.
 *
 * Prior to Phaser v3.50 this pipeline didn't exist, but could be compared to the old `TextureTintPipeline`.
 *
 * The fragment shader it uses can be found in `shaders/src/Single.frag`.
 * The vertex shader it uses can be found in `shaders/src/Single.vert`.
 *
 * The default shader attributes for this pipeline are:
 *
 * `inPosition` (vec2, offset 0)
 * `inTexCoord` (vec2, offset 8)
 * `inTintEffect` (float, offset 16)
 * `inTint` (vec4, offset 20, normalized)
 *
 * The default shader uniforms for this pipeline are:
 *
 * `uProjectionMatrix` (mat4)
 * `uViewMatrix` (mat4)
 * `uModelMatrix` (mat4)
 * `uMainSampler` (sampler2D)
 *
 * @class SinglePipeline
 * @extends Phaser.Renderer.WebGL.Pipelines.MultiPipeline
 * @memberof Phaser.Renderer.WebGL.Pipelines
 * @constructor
 * @since 3.50.0
 *
 * @param {Phaser.Types.Renderer.WebGL.WebGLPipelineConfig} config - The configuration options for this pipeline.
 */
var SinglePipeline = new Class({

    Extends: MultiPipeline,

    Mixins: [
        ModelViewProjection
    ],

    initialize:

    function SinglePipeline (config)
    {
        var gl = config.game.renderer.gl;

        config.fragShader = GetFastValue(config, 'fragShader', ShaderSourceFS),
        config.vertShader = GetFastValue(config, 'vertShader', ShaderSourceVS),
        config.vertexSize = GetFastValue(config, 'vertexSize', 24),
        config.attributes = GetFastValue(config, 'attributes', [
            {
                name: 'inPosition',
                size: 2,
                type: gl.FLOAT,
                normalized: false,
                offset: 0,
                enabled: false,
                location: -1
            },
            {
                name: 'inTexCoord',
                size: 2,
                type: gl.FLOAT,
                normalized: false,
                offset: 8,
                enabled: false,
                location: -1
            },
            {
                name: 'inTintEffect',
                size: 1,
                type: gl.FLOAT,
                normalized: false,
                offset: 16,
                enabled: false,
                location: -1
            },
            {
                name: 'inTint',
                size: 4,
                type: gl.UNSIGNED_BYTE,
                normalized: true,
                offset: 20,
                enabled: false,
                location: -1
            }
        ]);

        MultiPipeline.call(this, config);

        this.forceZero = true;
    },

    /**
     * Adds the vertices data into the batch and flushes if full.
     *
     * Assumes 6 vertices in the following arrangement:
     *
     * ```
     * 0----3
     * |\  B|
     * | \  |
     * |  \ |
     * | A \|
     * |    \
     * 1----2
     * ```
     *
     * Where tx0/ty0 = 0, tx1/ty1 = 1, tx2/ty2 = 2 and tx3/ty3 = 3
     *
     * @method Phaser.Renderer.WebGL.Pipelines.SinglePipeline#batchQuad
     * @since 3.50.0
     *
     * @param {number} x0 - The top-left x position.
     * @param {number} y0 - The top-left y position.
     * @param {number} x1 - The bottom-left x position.
     * @param {number} y1 - The bottom-left y position.
     * @param {number} x2 - The bottom-right x position.
     * @param {number} y2 - The bottom-right y position.
     * @param {number} x3 - The top-right x position.
     * @param {number} y3 - The top-right y position.
     * @param {number} u0 - UV u0 value.
     * @param {number} v0 - UV v0 value.
     * @param {number} u1 - UV u1 value.
     * @param {number} v1 - UV v1 value.
     * @param {number} tintTL - The top-left tint color value.
     * @param {number} tintTR - The top-right tint color value.
     * @param {number} tintBL - The bottom-left tint color value.
     * @param {number} tintBR - The bottom-right tint color value.
     * @param {(number|boolean)} tintEffect - The tint effect for the shader to use.
     * @param {WebGLTexture} [texture] - WebGLTexture that will be assigned to the current batch if a flush occurs.
     * @param {integer} [unit=0] - This parameter isn't used by this pipeline, but is retained for TTP support.
     *
     * @return {boolean} `true` if this method caused the batch to flush, otherwise `false`.
     */
    batchQuad: function (x0, y0, x1, y1, x2, y2, x3, y3, u0, v0, u1, v1, tintTL, tintTR, tintBL, tintBR, tintEffect, texture, unit)
    {
        if (unit === undefined) { unit = this.currentUnit; }

        var hasFlushed = false;

        if (this.vertexCount + 6 > this.vertexCapacity)
        {
            this.flush();

            hasFlushed = true;

            unit = this.setTexture2D(texture);
        }

        var vertexViewF32 = this.vertexViewF32;
        var vertexViewU32 = this.vertexViewU32;

        var vertexOffset = (this.vertexCount * this.vertexComponentCount) - 1;

        vertexViewF32[++vertexOffset] = x0;
        vertexViewF32[++vertexOffset] = y0;
        vertexViewF32[++vertexOffset] = u0;
        vertexViewF32[++vertexOffset] = v0;
        vertexViewF32[++vertexOffset] = tintEffect;
        vertexViewU32[++vertexOffset] = tintTL;

        vertexViewF32[++vertexOffset] = x1;
        vertexViewF32[++vertexOffset] = y1;
        vertexViewF32[++vertexOffset] = u0;
        vertexViewF32[++vertexOffset] = v1;
        vertexViewF32[++vertexOffset] = tintEffect;
        vertexViewU32[++vertexOffset] = tintBL;

        vertexViewF32[++vertexOffset] = x2;
        vertexViewF32[++vertexOffset] = y2;
        vertexViewF32[++vertexOffset] = u1;
        vertexViewF32[++vertexOffset] = v1;
        vertexViewF32[++vertexOffset] = tintEffect;
        vertexViewU32[++vertexOffset] = tintBR;

        vertexViewF32[++vertexOffset] = x0;
        vertexViewF32[++vertexOffset] = y0;
        vertexViewF32[++vertexOffset] = u0;
        vertexViewF32[++vertexOffset] = v0;
        vertexViewF32[++vertexOffset] = tintEffect;
        vertexViewU32[++vertexOffset] = tintTL;

        vertexViewF32[++vertexOffset] = x2;
        vertexViewF32[++vertexOffset] = y2;
        vertexViewF32[++vertexOffset] = u1;
        vertexViewF32[++vertexOffset] = v1;
        vertexViewF32[++vertexOffset] = tintEffect;
        vertexViewU32[++vertexOffset] = tintBR;

        vertexViewF32[++vertexOffset] = x3;
        vertexViewF32[++vertexOffset] = y3;
        vertexViewF32[++vertexOffset] = u1;
        vertexViewF32[++vertexOffset] = v0;
        vertexViewF32[++vertexOffset] = tintEffect;
        vertexViewU32[++vertexOffset] = tintTR;

        this.vertexCount += 6;

        return hasFlushed;
    },

    /**
     * Adds the vertices data into the batch and flushes if full.
     *
     * Assumes 3 vertices in the following arrangement:
     *
     * ```
     * 0
     * |\
     * | \
     * |  \
     * |   \
     * |    \
     * 1-----2
     * ```
     *
     * @method Phaser.Renderer.WebGL.Pipelines.SinglePipeline#batchTri
     * @since 3.50.0
     *
     * @param {number} x1 - The bottom-left x position.
     * @param {number} y1 - The bottom-left y position.
     * @param {number} x2 - The bottom-right x position.
     * @param {number} y2 - The bottom-right y position.
     * @param {number} x3 - The top-right x position.
     * @param {number} y3 - The top-right y position.
     * @param {number} u0 - UV u0 value.
     * @param {number} v0 - UV v0 value.
     * @param {number} u1 - UV u1 value.
     * @param {number} v1 - UV v1 value.
     * @param {number} tintTL - The top-left tint color value.
     * @param {number} tintTR - The top-right tint color value.
     * @param {number} tintBL - The bottom-left tint color value.
     * @param {(number|boolean)} tintEffect - The tint effect for the shader to use.
     * @param {WebGLTexture} [texture] - WebGLTexture that will be assigned to the current batch if a flush occurs.
     * @param {integer} [unit=0] - This parameter isn't used by this pipeline, but is retained for TTP support.
     *
     * @return {boolean} `true` if this method caused the batch to flush, otherwise `false`.
     */
    batchTri: function (x1, y1, x2, y2, x3, y3, u0, v0, u1, v1, tintTL, tintTR, tintBL, tintEffect, texture, unit)
    {
        if (unit === undefined) { unit = this.currentUnit; }

        var hasFlushed = false;

        if (this.vertexCount + 3 > this.vertexCapacity)
        {
            this.flush();

            hasFlushed = true;

            unit = this.setTexture2D(texture);
        }

        var vertexViewF32 = this.vertexViewF32;
        var vertexViewU32 = this.vertexViewU32;

        var vertexOffset = (this.vertexCount * this.vertexComponentCount) - 1;

        vertexViewF32[++vertexOffset] = x1;
        vertexViewF32[++vertexOffset] = y1;
        vertexViewF32[++vertexOffset] = u0;
        vertexViewF32[++vertexOffset] = v0;
        vertexViewF32[++vertexOffset] = tintEffect;
        vertexViewU32[++vertexOffset] = tintTL;

        vertexViewF32[++vertexOffset] = x2;
        vertexViewF32[++vertexOffset] = y2;
        vertexViewF32[++vertexOffset] = u0;
        vertexViewF32[++vertexOffset] = v1;
        vertexViewF32[++vertexOffset] = tintEffect;
        vertexViewU32[++vertexOffset] = tintTR;

        vertexViewF32[++vertexOffset] = x3;
        vertexViewF32[++vertexOffset] = y3;
        vertexViewF32[++vertexOffset] = u1;
        vertexViewF32[++vertexOffset] = v1;
        vertexViewF32[++vertexOffset] = tintEffect;
        vertexViewU32[++vertexOffset] = tintBL;

        this.vertexCount += 3;

        return hasFlushed;
    },

    /**
     * Called every time the pipeline is bound by the renderer.
     * Sets the shader program, vertex buffer and other resources.
     * Should only be called when changing pipeline.
     *
     * @method Phaser.Renderer.WebGL.Pipelines.SinglePipeline#bind
     * @since 3.50.0
     *
     * @param {boolean} [reset=false] - Should the pipeline be fully re-bound after a renderer pipeline clear?
     *
     * @return {this} This WebGLPipeline instance.
     */
    bind: function (reset)
    {
        if (reset === undefined) { reset = false; }

        WebGLPipeline.prototype.bind.call(this, reset);

        return this;
    }

});

module.exports = SinglePipeline;
<commit_msg>Use `shouldFlush`<commit_after>/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2020 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Class = require('../../../utils/Class');
var GetFastValue = require('../../../utils/object/GetFastValue');
var ModelViewProjection = require('./components/ModelViewProjection');
var MultiPipeline = require('./MultiPipeline');
var ShaderSourceFS = require('../shaders/Single-frag.js');
var ShaderSourceVS = require('../shaders/Single-vert.js');
var WebGLPipeline = require('../WebGLPipeline');

/**
 * @classdesc
 *
 * The Single Pipeline is a special version of the Multi Pipeline that only ever
 * uses one single texture, bound to texture unit zero. Although not as efficient as the
 * Multi Pipeline, it provides an easier way to create custom pipelines that only require
 * a single bound texture.
 *
 * Prior to Phaser v3.50 this pipeline didn't exist, but could be compared to the old `TextureTintPipeline`.
 *
 * The fragment shader it uses can be found in `shaders/src/Single.frag`.
 * The vertex shader it uses can be found in `shaders/src/Single.vert`.
 *
 * The default shader attributes for this pipeline are:
 *
 * `inPosition` (vec2, offset 0)
 * `inTexCoord` (vec2, offset 8)
 * `inTintEffect` (float, offset 16)
 * `inTint` (vec4, offset 20, normalized)
 *
 * The default shader uniforms for this pipeline are:
 *
 * `uProjectionMatrix` (mat4)
 * `uViewMatrix` (mat4)
 * `uModelMatrix` (mat4)
 * `uMainSampler` (sampler2D)
 *
 * @class SinglePipeline
 * @extends Phaser.Renderer.WebGL.Pipelines.MultiPipeline
 * @memberof Phaser.Renderer.WebGL.Pipelines
 * @constructor
 * @since 3.50.0
 *
 * @param {Phaser.Types.Renderer.WebGL.WebGLPipelineConfig} config - The configuration options for this pipeline.
 */
var SinglePipeline = new Class({

    Extends: MultiPipeline,

    Mixins: [
        ModelViewProjection
    ],

    initialize:

    function SinglePipeline (config)
    {
        var gl = config.game.renderer.gl;

        config.fragShader = GetFastValue(config, 'fragShader', ShaderSourceFS),
        config.vertShader = GetFastValue(config, 'vertShader', ShaderSourceVS),
        config.vertexSize = GetFastValue(config, 'vertexSize', 24),
        config.attributes = GetFastValue(config, 'attributes', [
            {
                name: 'inPosition',
                size: 2,
                type: gl.FLOAT,
                normalized: false,
                offset: 0,
                enabled: false,
                location: -1
            },
            {
                name: 'inTexCoord',
                size: 2,
                type: gl.FLOAT,
                normalized: false,
                offset: 8,
                enabled: false,
                location: -1
            },
            {
                name: 'inTintEffect',
                size: 1,
                type: gl.FLOAT,
                normalized: false,
                offset: 16,
                enabled: false,
                location: -1
            },
            {
                name: 'inTint',
                size: 4,
                type: gl.UNSIGNED_BYTE,
                normalized: true,
                offset: 20,
                enabled: false,
                location: -1
            }
        ]);

        MultiPipeline.call(this, config);

        this.forceZero = true;
    },

    /**
     * Adds the vertices data into the batch and flushes if full.
     *
     * Assumes 6 vertices in the following arrangement:
     *
     * ```
     * 0----3
     * |\  B|
     * | \  |
     * |  \ |
     * | A \|
     * |    \
     * 1----2
     * ```
     *
     * Where tx0/ty0 = 0, tx1/ty1 = 1, tx2/ty2 = 2 and tx3/ty3 = 3
     *
     * @method Phaser.Renderer.WebGL.Pipelines.SinglePipeline#batchQuad
     * @since 3.50.0
     *
     * @param {number} x0 - The top-left x position.
     * @param {number} y0 - The top-left y position.
     * @param {number} x1 - The bottom-left x position.
     * @param {number} y1 - The bottom-left y position.
     * @param {number} x2 - The bottom-right x position.
     * @param {number} y2 - The bottom-right y position.
     * @param {number} x3 - The top-right x position.
     * @param {number} y3 - The top-right y position.
     * @param {number} u0 - UV u0 value.
     * @param {number} v0 - UV v0 value.
     * @param {number} u1 - UV u1 value.
     * @param {number} v1 - UV v1 value.
     * @param {number} tintTL - The top-left tint color value.
     * @param {number} tintTR - The top-right tint color value.
     * @param {number} tintBL - The bottom-left tint color value.
     * @param {number} tintBR - The bottom-right tint color value.
     * @param {(number|boolean)} tintEffect - The tint effect for the shader to use.
     * @param {WebGLTexture} [texture] - WebGLTexture that will be assigned to the current batch if a flush occurs.
     * @param {integer} [unit=0] - This parameter isn't used by this pipeline, but is retained for TTP support.
     *
     * @return {boolean} `true` if this method caused the batch to flush, otherwise `false`.
     */
    batchQuad: function (x0, y0, x1, y1, x2, y2, x3, y3, u0, v0, u1, v1, tintTL, tintTR, tintBL, tintBR, tintEffect, texture, unit)
    {
        if (unit === undefined) { unit = this.currentUnit; }

        var hasFlushed = false;

        if (this.shouldFlush(6))
        {
            this.flush();

            hasFlushed = true;

            unit = this.setTexture2D(texture);
        }

        var vertexViewF32 = this.vertexViewF32;
        var vertexViewU32 = this.vertexViewU32;

        var vertexOffset = (this.vertexCount * this.vertexComponentCount) - 1;

        vertexViewF32[++vertexOffset] = x0;
        vertexViewF32[++vertexOffset] = y0;
        vertexViewF32[++vertexOffset] = u0;
        vertexViewF32[++vertexOffset] = v0;
        vertexViewF32[++vertexOffset] = tintEffect;
        vertexViewU32[++vertexOffset] = tintTL;

        vertexViewF32[++vertexOffset] = x1;
        vertexViewF32[++vertexOffset] = y1;
        vertexViewF32[++vertexOffset] = u0;
        vertexViewF32[++vertexOffset] = v1;
        vertexViewF32[++vertexOffset] = tintEffect;
        vertexViewU32[++vertexOffset] = tintBL;

        vertexViewF32[++vertexOffset] = x2;
        vertexViewF32[++vertexOffset] = y2;
        vertexViewF32[++vertexOffset] = u1;
        vertexViewF32[++vertexOffset] = v1;
        vertexViewF32[++vertexOffset] = tintEffect;
        vertexViewU32[++vertexOffset] = tintBR;

        vertexViewF32[++vertexOffset] = x0;
        vertexViewF32[++vertexOffset] = y0;
        vertexViewF32[++vertexOffset] = u0;
        vertexViewF32[++vertexOffset] = v0;
        vertexViewF32[++vertexOffset] = tintEffect;
        vertexViewU32[++vertexOffset] = tintTL;

        vertexViewF32[++vertexOffset] = x2;
        vertexViewF32[++vertexOffset] = y2;
        vertexViewF32[++vertexOffset] = u1;
        vertexViewF32[++vertexOffset] = v1;
        vertexViewF32[++vertexOffset] = tintEffect;
        vertexViewU32[++vertexOffset] = tintBR;

        vertexViewF32[++vertexOffset] = x3;
        vertexViewF32[++vertexOffset] = y3;
        vertexViewF32[++vertexOffset] = u1;
        vertexViewF32[++vertexOffset] = v0;
        vertexViewF32[++vertexOffset] = tintEffect;
        vertexViewU32[++vertexOffset] = tintTR;

        this.vertexCount += 6;

        return hasFlushed;
    },

    /**
     * Adds the vertices data into the batch and flushes if full.
     *
     * Assumes 3 vertices in the following arrangement:
     *
     * ```
     * 0
     * |\
     * | \
     * |  \
     * |   \
     * |    \
     * 1-----2
     * ```
     *
     * @method Phaser.Renderer.WebGL.Pipelines.SinglePipeline#batchTri
     * @since 3.50.0
     *
     * @param {number} x1 - The bottom-left x position.
     * @param {number} y1 - The bottom-left y position.
     * @param {number} x2 - The bottom-right x position.
     * @param {number} y2 - The bottom-right y position.
     * @param {number} x3 - The top-right x position.
     * @param {number} y3 - The top-right y position.
     * @param {number} u0 - UV u0 value.
     * @param {number} v0 - UV v0 value.
     * @param {number} u1 - UV u1 value.
     * @param {number} v1 - UV v1 value.
     * @param {number} tintTL - The top-left tint color value.
     * @param {number} tintTR - The top-right tint color value.
     * @param {number} tintBL - The bottom-left tint color value.
     * @param {(number|boolean)} tintEffect - The tint effect for the shader to use.
     * @param {WebGLTexture} [texture] - WebGLTexture that will be assigned to the current batch if a flush occurs.
     * @param {integer} [unit=0] - This parameter isn't used by this pipeline, but is retained for TTP support.
     *
     * @return {boolean} `true` if this method caused the batch to flush, otherwise `false`.
     */
    batchTri: function (x1, y1, x2, y2, x3, y3, u0, v0, u1, v1, tintTL, tintTR, tintBL, tintEffect, texture, unit)
    {
        if (unit === undefined) { unit = this.currentUnit; }

        var hasFlushed = false;

        if (this.shouldFlush(3))
        {
            this.flush();

            hasFlushed = true;

            unit = this.setTexture2D(texture);
        }

        var vertexViewF32 = this.vertexViewF32;
        var vertexViewU32 = this.vertexViewU32;

        var vertexOffset = (this.vertexCount * this.vertexComponentCount) - 1;

        vertexViewF32[++vertexOffset] = x1;
        vertexViewF32[++vertexOffset] = y1;
        vertexViewF32[++vertexOffset] = u0;
        vertexViewF32[++vertexOffset] = v0;
        vertexViewF32[++vertexOffset] = tintEffect;
        vertexViewU32[++vertexOffset] = tintTL;

        vertexViewF32[++vertexOffset] = x2;
        vertexViewF32[++vertexOffset] = y2;
        vertexViewF32[++vertexOffset] = u0;
        vertexViewF32[++vertexOffset] = v1;
        vertexViewF32[++vertexOffset] = tintEffect;
        vertexViewU32[++vertexOffset] = tintTR;

        vertexViewF32[++vertexOffset] = x3;
        vertexViewF32[++vertexOffset] = y3;
        vertexViewF32[++vertexOffset] = u1;
        vertexViewF32[++vertexOffset] = v1;
        vertexViewF32[++vertexOffset] = tintEffect;
        vertexViewU32[++vertexOffset] = tintBL;

        this.vertexCount += 3;

        return hasFlushed;
    },

    /**
     * Called every time the pipeline is bound by the renderer.
     * Sets the shader program, vertex buffer and other resources.
     * Should only be called when changing pipeline.
     *
     * @method Phaser.Renderer.WebGL.Pipelines.SinglePipeline#bind
     * @since 3.50.0
     *
     * @param {boolean} [reset=false] - Should the pipeline be fully re-bound after a renderer pipeline clear?
     *
     * @return {this} This WebGLPipeline instance.
     */
    bind: function (reset)
    {
        if (reset === undefined) { reset = false; }

        WebGLPipeline.prototype.bind.call(this, reset);

        return this;
    }

});

module.exports = SinglePipeline;
<|endoftext|>


<commit_before>/**
 * @file Structure Representation
 * @author Alexander Rose <alexander.rose@weirdbyte.de>
 * @private
 */

import { ExtensionFragDepth, Mobile } from "../globals.js";
import { defaults } from "../utils.js";
import Representation from "./representation.js";
import Selection from "../selection.js";
import RadiusFactory from "../utils/radius-factory.js";

/**
 * Structure representation parameter object.
 * @typedef {Object} StructureRepresentationParameters - structure representation parameters
 * @mixes RepresentationParameters
 *
 * @property {String} radiusType - A list of possible sources of the radius used for rendering the representation. The radius can be based on the *vdW radius*, the *covalent radius* or the *B-factor* value of the corresponding atom. Additionally the radius can be based on the *secondary structure*. Alternatively, when set to *size*, the value from the *radius* parameter is used for all atoms.
 * @property {Float} radius - A number providing a fixed radius used for rendering the representation.
 * @property {Float} scale - A number that scales the value defined by the *radius* or the *radiusType* parameter.
 * @property {String} assembly - name of an assembly object. Included are the asymmetric unit (*AU*) corresponding to the coordinates given in the structure file, biological assemblies from *PDB*, *mmCIF* or *MMTF* files (*BU1*, *BU2*, ...), a filled (crystallographic) unitcell of a given space group (*UNITCELL*), a supercell consisting of a center unitcell and its 26 direct neighbors (*SUPERCELL*). Set to *default* to use the default asemmbly of the structure object.
 */

/**
 * Structure representation object
 * @class
 * @extends Representation
 * @param {Structure} structure - the structure to be represented
 * @param {Viewer} viewer - a viewer object
 * @param {StructureRepresentationParameters} params - structure representation parameters
 */
function StructureRepresentation( structure, viewer, params ){

    var p = params || {};

    /**
     * @member {Selection}
     * @private
     */
    this.selection = new Selection( p.sele );

    /**
     * @member {Array}
     * @private
     */
    this.dataList = [];

    /**
     * @member {Structure}
     */
    this.structure = structure;

    /**
     * @member {StructureView}
     */
    this.structureView = this.structure.getView( this.selection );

    Representation.call( this, structure, viewer, p );

    if( structure.biomolDict ){
        var biomolOptions = {
            "default": "default",
            "": ( structure.unitcell ? "AU" : "FULL" )
        };
        Object.keys( structure.biomolDict ).forEach( function( k ){
            biomolOptions[ k ] = k;
        } );
        this.parameters.assembly = {
            type: "select",
            options: biomolOptions,
            rebuild: true
        };
    }else{
        this.parameters.assembly = null;
    }

    // must come after structureView to ensure selection change signals
    // have already updated the structureView
    this.selection.signals.stringChanged.add( function(){
        this.build();
    }.bind( this ) );

    this.build();

}

StructureRepresentation.prototype = Object.assign( Object.create(

    Representation.prototype ), {

    constructor: StructureRepresentation,

    type: "structure",

    parameters: Object.assign( {

        radiusType: {
            type: "select", options: RadiusFactory.types
        },
        radius: {
            type: "number", precision: 3, max: 10.0, min: 0.001
        },
        scale: {
            type: "number", precision: 3, max: 10.0, min: 0.001
        },
        assembly: null,
        defaultAssembly: {
            type: "hidden"
        }

    }, Representation.prototype.parameters ),

    defaultScale: {
        "vdw": 1.0,
        "covalent": 1.0,
        "bfactor": 0.01,
        "sstruc": 1.0
    },

    defaultSize: 1.0,

    init: function( params ){

        var p = params || {};
        p.colorScheme = defaults( p.colorScheme, "element" );

        this.radius = defaults( p.radius, "vdw" );
        this.scale = defaults( p.scale, 1.0 );
        this.assembly = defaults( p.assembly, "default" );
        this.defaultAssembly = defaults( p.defaultAssembly, "" );

        if( p.quality === "auto" ){
            var atomCount;
            var s = this.structureView;
            var assembly = this.getAssembly();
            if( assembly ){
                atomCount = assembly.getAtomCount( s );
            }else{
                atomCount = s.atomCount
            }
            if( Mobile ){
                atomCount *= 4;
            }
            var backboneOnly = s.atomStore.count / s.residueStore.count < 2;
            if( backboneOnly ){
                atomCount *= 10;
            }
            if( atomCount < 15000 ){
                p.quality = "high";
            }else if( atomCount < 80000 ){
                p.quality = "medium";
            }else{
                p.quality = "low";
            }
        }

        Representation.prototype.init.call( this, p );

    },

    getAssembly: function(){

        var name = this.assembly === "default" ? this.defaultAssembly : this.assembly;
        return this.structure.biomolDict[ name ];

    },

    create: function(){

        if( this.structureView.atomCount === 0 ) return;

        var assembly = this.getAssembly();

        if( assembly ){
            assembly.partList.forEach( function( part, i ){
                var sview = part.getView( this.structureView );
                if( sview.atomCount === 0 ) return;
                var data = this.createData( sview, i );
                if( data ){
                    data.sview = sview;
                    data.instanceList = part.getInstanceList();
                    this.dataList.push( data );
                }
            }, this );
        }else{
            var data = this.createData( this.structureView, 0 );
            if( data ){
                data.sview = this.structureView;
                this.dataList.push( data );
            }
        }

    },

    createData: function( /*sview*/ ){

        console.error( "createData not implemented" );

    },

    update: function( what ){

        if( this.lazy && !this.visible ){
            Object.assign( this.lazyProps.what, what );
            return;
        }

        this.dataList.forEach( function( data ){
            if( data.bufferList.length > 0 ){
                this.updateData( what, data );
            }
        }, this );

    },

    updateData: function( /*what, data*/ ){

        console.error( "updateData not implemented" );

    },

    getColorParams: function(){

        var p = Representation.prototype.getColorParams.call( this );
        p.structure = this.structure;

        return p;

    },

    getAtomParams: function( what, params ){

        return Object.assign( {
            what: what,
            colorParams: this.getColorParams(),
            radiusParams: { "radius": this.radius, "scale": this.scale }
        }, params );

    },

    getBondParams: function( what, params ){

        return Object.assign( {
            what: what,
            colorParams: this.getColorParams(),
            radiusParams: { "radius": this.radius, "scale": this.scale }
        }, params );

    },

    /**
     * Set representation parameters
     * @alias StructureRepresentation#setSelection
     * @param {String} string - selection string, see {@tutorial selection-language}
     * @param {Boolean} [silent] - don't trigger a change event in the selection
     * @return {StructureRepresentation} this object
     */
    setSelection: function( string, silent ){

        this.selection.setString( string, silent );

        return this;

    },

    /**
     * Set representation parameters
     * @alias StructureRepresentation#setParameters
     * @param {StructureRepresentationParameters} params - structure parameter object
     * @param {Object} [what] - buffer data attributes to be updated,
     *                        note that this needs to be implemented in the
     *                        derived classes. Generally it allows more
     *                        fine-grained control over updating than
     *                        forcing a rebuild.
     * @param {Boolean} what.position - update position data
     * @param {Boolean} what.color - update color data
     * @param {Boolean} [rebuild] - whether or not to rebuild the representation
     * @return {StructureRepresentation} this object
     */
    setParameters: function( params, what, rebuild ){

        what = what || {};

        if( params && params.radiusType !== undefined ){
            if( params.radiusType === "size" ){
                this.radius = this.defaultSize;
            }else{
                this.radius = params.radiusType;
            }
            what.radius = true;
            if( !ExtensionFragDepth || this.disableImpostor ){
                rebuild = true;
            }
        }

        if( params && params.radius !== undefined ){
            what.radius = true;
            if( !ExtensionFragDepth || this.disableImpostor ){
                rebuild = true;
            }
        }

        if( params && params.scale !== undefined ){
            what.radius = true;
            if( !ExtensionFragDepth || this.disableImpostor ){
                rebuild = true;
            }
        }

        if( params && params.defaultAssembly !== undefined ){
            rebuild = true;
        }

        Representation.prototype.setParameters.call(
            this, params, what, rebuild
        );

        return this;

    },

    getParameters: function(){

        var params = Object.assign(
            Representation.prototype.getParameters.call( this ),
            {
                sele: this.selection ? this.selection.string : undefined,
                defaultAssembly: this.defaultAssembly
            }
        );

        return params;

    },

    attach: function( callback ){

        var viewer = this.viewer;
        var bufferList = this.bufferList;

        this.dataList.forEach( function( data ){
            data.bufferList.forEach( function( buffer ){
                bufferList.push( buffer );
                viewer.add( buffer, data.instanceList );
            } );
        } );

        this.setVisibility( this.visible );
        callback();

    },

    clear: function(){

        this.dataList.length = 0;

        Representation.prototype.clear.call( this );

    },

    dispose: function(){

        this.structureView.dispose();

        delete this.structure;
        delete this.structureView;

        Representation.prototype.dispose.call( this );

    }

} );

export default StructureRepresentation;
<commit_msg>cleanup, factored out code into method<commit_after>/**
 * @file Structure Representation
 * @author Alexander Rose <alexander.rose@weirdbyte.de>
 * @private
 */

import { ExtensionFragDepth, Mobile } from "../globals.js";
import { defaults } from "../utils.js";
import Representation from "./representation.js";
import Selection from "../selection.js";
import RadiusFactory from "../utils/radius-factory.js";

/**
 * Structure representation parameter object.
 * @typedef {Object} StructureRepresentationParameters - structure representation parameters
 * @mixes RepresentationParameters
 *
 * @property {String} radiusType - A list of possible sources of the radius used for rendering the representation. The radius can be based on the *vdW radius*, the *covalent radius* or the *B-factor* value of the corresponding atom. Additionally the radius can be based on the *secondary structure*. Alternatively, when set to *size*, the value from the *radius* parameter is used for all atoms.
 * @property {Float} radius - A number providing a fixed radius used for rendering the representation.
 * @property {Float} scale - A number that scales the value defined by the *radius* or the *radiusType* parameter.
 * @property {String} assembly - name of an assembly object. Included are the asymmetric unit (*AU*) corresponding to the coordinates given in the structure file, biological assemblies from *PDB*, *mmCIF* or *MMTF* files (*BU1*, *BU2*, ...), a filled (crystallographic) unitcell of a given space group (*UNITCELL*), a supercell consisting of a center unitcell and its 26 direct neighbors (*SUPERCELL*). Set to *default* to use the default asemmbly of the structure object.
 */

/**
 * Structure representation object
 * @class
 * @extends Representation
 * @param {Structure} structure - the structure to be represented
 * @param {Viewer} viewer - a viewer object
 * @param {StructureRepresentationParameters} params - structure representation parameters
 */
function StructureRepresentation( structure, viewer, params ){

    var p = params || {};

    /**
     * @member {Selection}
     * @private
     */
    this.selection = new Selection( p.sele );

    /**
     * @member {Array}
     * @private
     */
    this.dataList = [];

    /**
     * @member {Structure}
     */
    this.structure = structure;

    /**
     * @member {StructureView}
     */
    this.structureView = this.structure.getView( this.selection );

    Representation.call( this, structure, viewer, p );

    if( structure.biomolDict ){
        var biomolOptions = {
            "default": "default",
            "": ( structure.unitcell ? "AU" : "FULL" )
        };
        Object.keys( structure.biomolDict ).forEach( function( k ){
            biomolOptions[ k ] = k;
        } );
        this.parameters.assembly = {
            type: "select",
            options: biomolOptions,
            rebuild: true
        };
    }else{
        this.parameters.assembly = null;
    }

    // must come after structureView to ensure selection change signals
    // have already updated the structureView
    this.selection.signals.stringChanged.add( function(){
        this.build();
    }.bind( this ) );

    this.build();

}

StructureRepresentation.prototype = Object.assign( Object.create(

    Representation.prototype ), {

    constructor: StructureRepresentation,

    type: "structure",

    parameters: Object.assign( {

        radiusType: {
            type: "select", options: RadiusFactory.types
        },
        radius: {
            type: "number", precision: 3, max: 10.0, min: 0.001
        },
        scale: {
            type: "number", precision: 3, max: 10.0, min: 0.001
        },
        assembly: null,
        defaultAssembly: {
            type: "hidden"
        }

    }, Representation.prototype.parameters ),

    defaultScale: {
        "vdw": 1.0,
        "covalent": 1.0,
        "bfactor": 0.01,
        "sstruc": 1.0
    },

    defaultSize: 1.0,

    init: function( params ){

        var p = params || {};
        p.colorScheme = defaults( p.colorScheme, "element" );

        this.radius = defaults( p.radius, "vdw" );
        this.scale = defaults( p.scale, 1.0 );
        this.assembly = defaults( p.assembly, "default" );
        this.defaultAssembly = defaults( p.defaultAssembly, "" );

        if( p.quality === "auto" ){
            p.quality = this.getQuality();
        }

        Representation.prototype.init.call( this, p );

    },

    getAssembly: function(){

        var name = this.assembly === "default" ? this.defaultAssembly : this.assembly;
        return this.structure.biomolDict[ name ];

    },

    getQuality: function(){

        var atomCount;
        var s = this.structureView;
        var assembly = this.getAssembly();
        if( assembly ){
            atomCount = assembly.getAtomCount( s );
        }else{
            atomCount = s.atomCount
        }
        if( Mobile ){
            atomCount *= 4;
        }
        var backboneOnly = s.atomStore.count / s.residueStore.count < 2;
        if( backboneOnly ){
            atomCount *= 10;
        }

        if( atomCount < 15000 ){
            return "high";
        }else if( atomCount < 80000 ){
            return "medium";
        }else{
            return "low";
        }

    },

    create: function(){

        if( this.structureView.atomCount === 0 ) return;

        var assembly = this.getAssembly();

        if( assembly ){
            assembly.partList.forEach( function( part, i ){
                var sview = part.getView( this.structureView );
                if( sview.atomCount === 0 ) return;
                var data = this.createData( sview, i );
                if( data ){
                    data.sview = sview;
                    data.instanceList = part.getInstanceList();
                    this.dataList.push( data );
                }
            }, this );
        }else{
            var data = this.createData( this.structureView, 0 );
            if( data ){
                data.sview = this.structureView;
                this.dataList.push( data );
            }
        }

    },

    createData: function( /*sview*/ ){

        console.error( "createData not implemented" );

    },

    update: function( what ){

        if( this.lazy && !this.visible ){
            Object.assign( this.lazyProps.what, what );
            return;
        }

        this.dataList.forEach( function( data ){
            if( data.bufferList.length > 0 ){
                this.updateData( what, data );
            }
        }, this );

    },

    updateData: function( /*what, data*/ ){

        console.error( "updateData not implemented" );

    },

    getColorParams: function(){

        var p = Representation.prototype.getColorParams.call( this );
        p.structure = this.structure;

        return p;

    },

    getAtomParams: function( what, params ){

        return Object.assign( {
            what: what,
            colorParams: this.getColorParams(),
            radiusParams: { "radius": this.radius, "scale": this.scale }
        }, params );

    },

    getBondParams: function( what, params ){

        return Object.assign( {
            what: what,
            colorParams: this.getColorParams(),
            radiusParams: { "radius": this.radius, "scale": this.scale }
        }, params );

    },

    /**
     * Set representation parameters
     * @alias StructureRepresentation#setSelection
     * @param {String} string - selection string, see {@tutorial selection-language}
     * @param {Boolean} [silent] - don't trigger a change event in the selection
     * @return {StructureRepresentation} this object
     */
    setSelection: function( string, silent ){

        this.selection.setString( string, silent );

        return this;

    },

    /**
     * Set representation parameters
     * @alias StructureRepresentation#setParameters
     * @param {StructureRepresentationParameters} params - structure parameter object
     * @param {Object} [what] - buffer data attributes to be updated,
     *                        note that this needs to be implemented in the
     *                        derived classes. Generally it allows more
     *                        fine-grained control over updating than
     *                        forcing a rebuild.
     * @param {Boolean} what.position - update position data
     * @param {Boolean} what.color - update color data
     * @param {Boolean} [rebuild] - whether or not to rebuild the representation
     * @return {StructureRepresentation} this object
     */
    setParameters: function( params, what, rebuild ){

        what = what || {};

        if( params && params.radiusType !== undefined ){
            if( params.radiusType === "size" ){
                this.radius = this.defaultSize;
            }else{
                this.radius = params.radiusType;
            }
            what.radius = true;
            if( !ExtensionFragDepth || this.disableImpostor ){
                rebuild = true;
            }
        }

        if( params && params.radius !== undefined ){
            what.radius = true;
            if( !ExtensionFragDepth || this.disableImpostor ){
                rebuild = true;
            }
        }

        if( params && params.scale !== undefined ){
            what.radius = true;
            if( !ExtensionFragDepth || this.disableImpostor ){
                rebuild = true;
            }
        }

        if( params && params.defaultAssembly !== undefined ){
            rebuild = true;
        }

        Representation.prototype.setParameters.call(
            this, params, what, rebuild
        );

        return this;

    },

    getParameters: function(){

        var params = Object.assign(
            Representation.prototype.getParameters.call( this ),
            {
                sele: this.selection ? this.selection.string : undefined,
                defaultAssembly: this.defaultAssembly
            }
        );

        return params;

    },

    attach: function( callback ){

        var viewer = this.viewer;
        var bufferList = this.bufferList;

        this.dataList.forEach( function( data ){
            data.bufferList.forEach( function( buffer ){
                bufferList.push( buffer );
                viewer.add( buffer, data.instanceList );
            } );
        } );

        this.setVisibility( this.visible );
        callback();

    },

    clear: function(){

        this.dataList.length = 0;

        Representation.prototype.clear.call( this );

    },

    dispose: function(){

        this.structureView.dispose();

        delete this.structure;
        delete this.structureView;

        Representation.prototype.dispose.call( this );

    }

} );

export default StructureRepresentation;
<|endoftext|>


<commit_before>var fnObj = {};
var ACTIONS = axboot.actionExtend(fnObj, {
    PAGE_SEARCH: "PAGE_SEARCH",
    PAGE_SAVE: "PAGE_SAVE",
    TREEITEM_CLICK: "TREEITEM_CLICK",
    TREE_ROOTNODE_ADD: "TREE_ROOTNODE_ADD",
    dispatch: function (caller, act, data) {
        var _this = this;
        switch (act) {
            case ACTIONS.PAGE_SEARCH:
                var searchData = this.searchView.getData();
                axboot.ajax({
                    type: "GET",
                    url: "/api/v1/manual",
                    data: this.searchView.getData()
                }, function (res) {
                    _this.treeView01.setData(searchData, res.list);

                }, {
                    onError: function (err) {
                        console.log(err);
                    }
                });
                break;
            case ACTIONS.TREEITEM_CLICK:

                if (typeof data.manualId === "undefined") {
                    this.formView01.clear();
                    if(confirm("신규 생성된 목차는 저장 후 편집 할수 있습니다. 지금 저장 하시겠습니까? (저장 후에 다시 선택해주세요)")){
                        ACTIONS.dispatch(ACTIONS.PAGE_SAVE);
                    }
                    return;
                }

                axboot.ajax({
                    type: "GET",
                    url: "/api/v1/manual/" + data.manualId,
                    data: ""
                }, function (res) {
                    _this.formView01.setData(res);
                });

                break;
            case ACTIONS.TREEITEM_DESELECTE:
                this.formView01.clear();
                break;

            case ACTIONS.TREE_ROOTNODE_ADD:
                this.treeView01.addRootNode();
                break;
            case ACTIONS.PAGE_SAVE:

                var obj = {
                    list: this.treeView01.getData(),
                    deletedList: this.treeView01.getDeletedList()
                };

                axboot
                    .call({
                        type: "PUT",
                        url: "/api/v1/manual",
                        data: JSON.stringify(obj),
                        callback: function(){
                            _this.treeView01.clearDeletedList();
                            axToast.push("목차가 저장 되었습니다");
                        }
                    })
                    .done(function(){
                        var data = _this.formView01.getData();

                        if(data.manualId) {
                            axboot.ajax({
                                type: "PUT",
                                url: "/api/v1/manual/detail",
                                data: JSON.stringify(data)
                            }, function (res) {
                                axToast.push("매뉴얼 내용이 저장 되었습니다");
                            });
                        }
                    });

                break;
            case ACTIONS.FORM_CLEAR:
                var _this = this;
                axDialog.confirm({
                    msg: "정말 양식을 초기화 하시겠습니까?"
                }, function () {
                    if (this.key == "ok") {
                        _this.formView01.clear();
                    }
                });
                break;
            default:
                return false;
        }
        return false;
    }
});
var CODE = {};

// fnObj 기본 함수 스타트와 리사이즈
fnObj.pageStart = function () {

    var _this = this;

    axboot
        .call({
            type: "GET", url: "/api/v1/commonCodes", data: {groupCd: "MANUAL_GROUP", useYn: "Y"},
            callback: function (res) {
                var manualGroup = [];
                res.list.forEach(function (n) {
                    manualGroup.push({
                        value: n.code, text: n.name + "(" + n.code + ")",
                        grpAuthCd: n.code, grpAuthNm: n.name,
                        data: n
                    });
                });
                this.authGroup = manualGroup;
            }
        })
        .done(function () {
            CODE = this; // this는 call을 통해 수집된 데이터들.

            _this.pageButtonView.initView();
            _this.searchView.initView();
            _this.treeView01.initView();
            _this.formView01.initView();

            ACTIONS.dispatch(ACTIONS.PAGE_SEARCH);
        });
};

fnObj.pageResize = function () {
    setTimeout(function(){
        fnObj.formView01.resize();
    }, 100);
};

fnObj.pageButtonView = axboot.viewExtend({
    initView: function () {
        var _this = this;
        $('[data-page-btn]').click(function () {
            _this.onClick(this.getAttribute("data-page-btn"));
        });
    },
    onClick: function (_act) {
        var _root = fnObj;
        switch (_act) {
            case "search":
                ACTIONS.dispatch(ACTIONS.PAGE_SEARCH);
                break;
            case "save":
                ACTIONS.dispatch(ACTIONS.PAGE_SAVE);
                break;
            case "excel":
                break;
            case "fn1":
                break;
            case "fn2":
                break;
            case "fn3":
                break;
            case "fn4":
                break;
            case "fn5":
                break;
        }
    }
});

//== view 시작
/**
 * searchView
 */
fnObj.searchView = axboot.viewExtend(axboot.searchView, {
    initView: function () {
        this.target = $(document["searchView0"]);
        this.target.attr("onsubmit", "return ACTIONS.dispatch(ACTIONS.PAGE_SEARCH);");
        this.manualGrpCd = $("#manualGrpCd");
    },
    getData: function () {
        return {
            pageNumber: 0,
            pageSize: 99999,
            manualGrpCd: this.manualGrpCd.val()
        }
    }
});

/**
 * treeView
 */
fnObj.treeView01 = axboot.viewExtend(axboot.treeView, {
    param: {},
    deletedList: [],
    newCount: 0,
    addRootNode: function () {
        var _this = this;
        var nodes = _this.target.zTree.getSelectedNodes();
        var treeNode = nodes[0];

        // root
        treeNode = _this.target.zTree.addNodes(null, {
            id: "_isnew_" + (++_this.newCount),
            pId: 0,
            name: "새 메뉴",
            __created__: true,
            manualGrpCd: _this.param.manualGrpCd
        });

        if (treeNode) {
            _this.target.zTree.editName(treeNode[0]);
        }
        fnObj.treeView01.deselectNode();
    },
    initView: function () {
        var _this = this;

        $('[data-tree-view-01-btn]').click(function () {
            var _act = this.getAttribute("data-tree-view-01-btn");
            switch (_act) {
                case "add":
                    ACTIONS.dispatch(ACTIONS.TREE_ROOTNODE_ADD);
                    break;
                case "delete":
                    //ACTIONS.dispatch(ACTIONS.ITEM_DEL);
                    break;
            }
        });

        this.target = axboot.treeBuilder($('[data-z-tree="tree-view-01"]'), {
            view: {
                dblClickExpand: false,
                addHoverDom: function (treeId, treeNode) {
                    var sObj = $("#" + treeNode.tId + "_span");
                    if (treeNode.editNameFlag || $("#addBtn_" + treeNode.tId).length > 0) return;
                    var addStr = "";
                    sObj.after(addStr);
                    var btn = $("#addBtn_" + treeNode.tId);
                    if (btn) {
                        btn.bind("click", function () {
                            _this.target.zTree.addNodes(
                                treeNode,
                                {
                                    id: "_isnew_" + (++_this.newCount),
                                    pId: treeNode.id,
                                    name: "새 메뉴",
                                    __created__: true,
                                    manualGrpCd: _this.param.manualGrpCd
                                }
                            );
                            _this.target.zTree.selectNode(treeNode.children[treeNode.children.length - 1]);
                            _this.target.editName();
                            fnObj.treeView01.deselectNode();
                            return false;
                        });
                    }
                },
                removeHoverDom: function (treeId, treeNode) {
                    $("#addBtn_" + treeNode.tId).unbind().remove();
                }
            },
            edit: {
                enable: true,
                editNameSelectAll: true
            },
            callback: {
                beforeDrag: function () {
                    //return false;
                },
                onClick: function (e, treeId, treeNode, isCancel) {
                    ACTIONS.dispatch(ACTIONS.TREEITEM_CLICK, treeNode);
                },
                onRename: function (e, treeId, treeNode, isCancel) {
                    treeNode.__modified__ = true;
                },
                onRemove: function (e, treeId, treeNode, isCancel) {
                    if (!treeNode.__created__) {
                        treeNode.__deleted__ = true;
                        _this.deletedList.push(treeNode);
                    }
                }
            }
        }, []);
    },
    setData: function (_searchData, _tree) {
        this.param = $.extend({}, _searchData);
        this.target.setData(_tree);
    },
    getData: function () {
        var _this = this;
        var tree = this.target.getData();

        var convertList = function (_tree) {
            var _newTree = [];
            _tree.forEach(function (n, nidx) {
                var item = {};
                if (n.__created__ || n.__modified__) {
                    item = {
                        __created__: n.__created__,
                        __modified__: n.__modified__,
                        manualId: n.manualId,
                        manualGrpCd: _this.param.manualGrpCd,
                        manualNm: n.name,
                        parentId: n.parentId,
                        sort: nidx,
                        progCd: n.progCd,
                        level: n.level
                    };
                } else {
                    item = {
                        manualId: n.manualId,
                        manualGrpCd: n.manualGrpCd,
                        manualNm: n.name,
                        parentId: n.parentId,
                        sort: nidx,
                        progCd: n.progCd,
                        level: n.level
                    };
                }
                if (n.children && n.children.length) {
                    item.children = convertList(n.children);
                }
                _newTree.push(item);
            });
            return _newTree;
        };
        var newTree = convertList(tree);
        return newTree;
    },
    getDeletedList: function () {
        return this.deletedList;
    },
    clearDeletedList: function () {
        this.deletedList = [];
        return true;
    },
    updateNode: function (data) {
        var treeNodes = this.target.getSelectedNodes();
        if (treeNodes[0]) {
            treeNodes[0].progCd = data.progCd;
        }
    },
    deselectNode: function () {
        ACTIONS.dispatch(ACTIONS.TREEITEM_DESELECTE);
    }
});

/**
 * formView01
 */
fnObj.formView01 = axboot.viewExtend(axboot.formView, {
    getDefaultData: function () {
        return $.extend({}, axboot.formView.defaultData, {});
    },
    initView: function () {
        var _this = this;

        this.mask = new ax5.ui.mask({
            theme: "form-mask",
            target: $('#split-panel-form'),
            content: '좌측 메뉴를 선택해주세요.'
        });
        this.mask.open();

        this.manualGroup = CODE.manualGroup;

        this.summernote = $('#summernote');
        this.summernote.summernote({
            height: ($('#summernote').height() - 50),                 // set editor height
            minHeight: null,             // set minimum height of editor
            maxHeight: null,             // set maximum height of editor
            focus: true,                  // set focus to editable area after initializing summernote,
            lang: 'ko-KR',
            airMode: false,
            toolbar: [
                ['style', ['style']],
                ['font', ['bold', 'italic', 'underline', 'clear']],
                ['fontname', ['fontname']],
                ['color', ['color']],
                ['para', ['ul', 'ol', 'paragraph']],
                ['height', ['height']],
                ['table', ['table']],
                ['insert', ['link', 'picture', 'hr']],
                ['view', ['codeview']],
                ['help', ['help']]
            ]
        });

        this.target = $("#formView01");
        this.model = new ax5.ui.binder();
        this.model.setModel(this.getDefaultData(), this.target);
        this.modelFormatter = new axboot.modelFormatter(this.model); // 모델 포메터 시작

        this.initEvent();

        $('[data-form-view-01-btn]').click(function () {
            var _root = fnObj;
            switch (this.getAttribute("data-form-view-01-btn")) {
                case "form-clear":
                    ACTIONS.dispatch(ACTIONS.FORM_CLEAR);
                    break;
            }
        });
    },
    initEvent: function () {
        var _this = this;
    },
    getData: function () {
        var data = this.modelFormatter.getClearData(this.model.get()); // 모델의 값을 포멧팅 전 값으로 치환.

        data.content = this.summernote.summernote("code");

        return data;
    },
    setData: function (data) {
        this.mask.close();
        $.extend(true, data, this.getDefaultData());
        this.model.setModel(data);
        console.log(this.summernote.summernote("code", data.content||""));
    },
    resize: function(){
        $('.note-editable.panel-body').height(($('#summernote').height() - 200));
    },
    clear: function () {
        this.mask.open();
        this.model.setModel(this.getDefaultData());
    }
});<commit_msg>매뉴얼관리<commit_after>var fnObj = {};
var ACTIONS = axboot.actionExtend(fnObj, {
    PAGE_SEARCH: "PAGE_SEARCH",
    PAGE_SAVE: "PAGE_SAVE",
    TREEITEM_CLICK: "TREEITEM_CLICK",
    TREE_ROOTNODE_ADD: "TREE_ROOTNODE_ADD",
    dispatch: function (caller, act, data) {
        var _this = this;
        switch (act) {
            case ACTIONS.PAGE_SEARCH:
                var searchData = this.searchView.getData();
                axboot.ajax({
                    type: "GET",
                    url: "/api/v1/manual",
                    data: this.searchView.getData()
                }, function (res) {
                    _this.treeView01.setData(searchData, res.list);

                }, {
                    onError: function (err) {
                        console.log(err);
                    }
                });
                break;
            case ACTIONS.TREEITEM_CLICK:

                if (typeof data.manualId === "undefined") {
                    this.formView01.clear();
                    if(confirm("신규 생성된 목차는 저장 후 편집 할수 있습니다. 지금 저장 하시겠습니까? (저장 후에 다시 선택해주세요)")){
                        ACTIONS.dispatch(ACTIONS.PAGE_SAVE);
                    }
                    return;
                }

                axboot.ajax({
                    type: "GET",
                    url: "/api/v1/manual/" + data.manualId,
                    data: ""
                }, function (res) {
                    _this.formView01.setData(res);
                });

                break;
            case ACTIONS.TREEITEM_DESELECTE:
                this.formView01.clear();
                break;

            case ACTIONS.TREE_ROOTNODE_ADD:
                this.treeView01.addRootNode();
                break;
            case ACTIONS.PAGE_SAVE:

                var obj = {
                    list: this.treeView01.getData(),
                    deletedList: this.treeView01.getDeletedList()
                };

                axboot
                    .call({
                        type: "PUT",
                        url: "/api/v1/manual",
                        data: JSON.stringify(obj),
                        callback: function(){
                            _this.treeView01.clearDeletedList();
                            axToast.push("목차가 저장 되었습니다");
                        }
                    })
                    .done(function(){
                        var data = _this.formView01.getData();

                        if(data.manualId) {
                            axboot.ajax({
                                type: "PUT",
                                url: "/api/v1/manual/detail",
                                data: JSON.stringify(data)
                            }, function (res) {
                                axToast.push("매뉴얼 내용이 저장 되었습니다");
                                ACTIONS.dispatch(ACTIONS.PAGE_SEARCH);
                            });
                        }else{
                            ACTIONS.dispatch(ACTIONS.PAGE_SEARCH);
                        }

                    });

                break;
            case ACTIONS.FORM_CLEAR:
                var _this = this;
                axDialog.confirm({
                    msg: "정말 양식을 초기화 하시겠습니까?"
                }, function () {
                    if (this.key == "ok") {
                        _this.formView01.clear();
                    }
                });
                break;
            default:
                return false;
        }
        return false;
    }
});
var CODE = {};

// fnObj 기본 함수 스타트와 리사이즈
fnObj.pageStart = function () {

    var _this = this;

    axboot
        .call({
            type: "GET", url: "/api/v1/commonCodes", data: {groupCd: "MANUAL_GROUP", useYn: "Y"},
            callback: function (res) {
                var manualGroup = [];
                res.list.forEach(function (n) {
                    manualGroup.push({
                        value: n.code, text: n.name + "(" + n.code + ")",
                        grpAuthCd: n.code, grpAuthNm: n.name,
                        data: n
                    });
                });
                this.authGroup = manualGroup;
            }
        })
        .done(function () {
            CODE = this; // this는 call을 통해 수집된 데이터들.

            _this.pageButtonView.initView();
            _this.searchView.initView();
            _this.treeView01.initView();
            _this.formView01.initView();

            ACTIONS.dispatch(ACTIONS.PAGE_SEARCH);
        });
};

fnObj.pageResize = function () {
    setTimeout(function(){
        fnObj.formView01.resize();
    }, 100);
};

fnObj.pageButtonView = axboot.viewExtend({
    initView: function () {
        var _this = this;
        $('[data-page-btn]').click(function () {
            _this.onClick(this.getAttribute("data-page-btn"));
        });
    },
    onClick: function (_act) {
        var _root = fnObj;
        switch (_act) {
            case "search":
                ACTIONS.dispatch(ACTIONS.PAGE_SEARCH);
                break;
            case "save":
                ACTIONS.dispatch(ACTIONS.PAGE_SAVE);
                break;
            case "excel":
                break;
            case "fn1":
                break;
            case "fn2":
                break;
            case "fn3":
                break;
            case "fn4":
                break;
            case "fn5":
                break;
        }
    }
});

//== view 시작
/**
 * searchView
 */
fnObj.searchView = axboot.viewExtend(axboot.searchView, {
    initView: function () {
        this.target = $(document["searchView0"]);
        this.target.attr("onsubmit", "return ACTIONS.dispatch(ACTIONS.PAGE_SEARCH);");
        this.manualGrpCd = $("#manualGrpCd");
    },
    getData: function () {
        return {
            pageNumber: 0,
            pageSize: 99999,
            manualGrpCd: this.manualGrpCd.val()
        }
    }
});

/**
 * treeView
 */
fnObj.treeView01 = axboot.viewExtend(axboot.treeView, {
    param: {},
    deletedList: [],
    newCount: 0,
    addRootNode: function () {
        var _this = this;
        var nodes = _this.target.zTree.getSelectedNodes();
        var treeNode = nodes[0];

        // root
        treeNode = _this.target.zTree.addNodes(null, {
            id: "_isnew_" + (++_this.newCount),
            pId: 0,
            name: "새 메뉴",
            __created__: true,
            manualGrpCd: _this.param.manualGrpCd
        });

        if (treeNode) {
            _this.target.zTree.editName(treeNode[0]);
        }
        fnObj.treeView01.deselectNode();
    },
    initView: function () {
        var _this = this;

        $('[data-tree-view-01-btn]').click(function () {
            var _act = this.getAttribute("data-tree-view-01-btn");
            switch (_act) {
                case "add":
                    ACTIONS.dispatch(ACTIONS.TREE_ROOTNODE_ADD);
                    break;
                case "delete":
                    //ACTIONS.dispatch(ACTIONS.ITEM_DEL);
                    break;
            }
        });

        this.target = axboot.treeBuilder($('[data-z-tree="tree-view-01"]'), {
            view: {
                dblClickExpand: false,
                addHoverDom: function (treeId, treeNode) {
                    var sObj = $("#" + treeNode.tId + "_span");
                    if (treeNode.editNameFlag || $("#addBtn_" + treeNode.tId).length > 0) return;
                    var addStr = "";
                    sObj.after(addStr);
                    var btn = $("#addBtn_" + treeNode.tId);
                    if (btn) {
                        btn.bind("click", function () {
                            _this.target.zTree.addNodes(
                                treeNode,
                                {
                                    id: "_isnew_" + (++_this.newCount),
                                    pId: treeNode.id,
                                    name: "새 메뉴",
                                    __created__: true,
                                    manualGrpCd: _this.param.manualGrpCd
                                }
                            );
                            _this.target.zTree.selectNode(treeNode.children[treeNode.children.length - 1]);
                            _this.target.editName();
                            fnObj.treeView01.deselectNode();
                            return false;
                        });
                    }
                },
                removeHoverDom: function (treeId, treeNode) {
                    $("#addBtn_" + treeNode.tId).unbind().remove();
                }
            },
            edit: {
                enable: true,
                editNameSelectAll: true
            },
            callback: {
                beforeDrag: function () {
                    //return false;
                },
                onClick: function (e, treeId, treeNode, isCancel) {
                    ACTIONS.dispatch(ACTIONS.TREEITEM_CLICK, treeNode);
                },
                onRename: function (e, treeId, treeNode, isCancel) {
                    treeNode.__modified__ = true;
                },
                onRemove: function (e, treeId, treeNode, isCancel) {
                    if (!treeNode.__created__) {
                        treeNode.__deleted__ = true;
                        _this.deletedList.push(treeNode);
                    }
                }
            }
        }, []);
    },
    setData: function (_searchData, _tree) {
        this.param = $.extend({}, _searchData);
        this.target.setData(_tree);
    },
    getData: function () {
        var _this = this;
        var tree = this.target.getData();

        var convertList = function (_tree) {
            var _newTree = [];
            _tree.forEach(function (n, nidx) {
                var item = {};
                if (n.__created__ || n.__modified__) {
                    item = {
                        __created__: n.__created__,
                        __modified__: n.__modified__,
                        manualId: n.manualId,
                        manualGrpCd: _this.param.manualGrpCd,
                        manualNm: n.name,
                        parentId: n.parentId,
                        sort: nidx,
                        progCd: n.progCd,
                        level: n.level
                    };
                } else {
                    item = {
                        manualId: n.manualId,
                        manualGrpCd: n.manualGrpCd,
                        manualNm: n.name,
                        parentId: n.parentId,
                        sort: nidx,
                        progCd: n.progCd,
                        level: n.level
                    };
                }
                if (n.children && n.children.length) {
                    item.children = convertList(n.children);
                }
                _newTree.push(item);
            });
            return _newTree;
        };
        var newTree = convertList(tree);
        return newTree;
    },
    getDeletedList: function () {
        return this.deletedList;
    },
    clearDeletedList: function () {
        this.deletedList = [];
        return true;
    },
    updateNode: function (data) {
        var treeNodes = this.target.getSelectedNodes();
        if (treeNodes[0]) {
            treeNodes[0].progCd = data.progCd;
        }
    },
    deselectNode: function () {
        ACTIONS.dispatch(ACTIONS.TREEITEM_DESELECTE);
    }
});

/**
 * formView01
 */
fnObj.formView01 = axboot.viewExtend(axboot.formView, {
    getDefaultData: function () {
        return $.extend({}, axboot.formView.defaultData, {});
    },
    initView: function () {
        var _this = this;

        this.mask = new ax5.ui.mask({
            theme: "form-mask",
            target: $('#split-panel-form'),
            content: '좌측 메뉴를 선택해주세요.'
        });
        this.mask.open();

        this.manualGroup = CODE.manualGroup;

        this.summernote = $('#summernote');
        this.summernote.summernote({
            height: ($('#summernote').height() - 50),                 // set editor height
            minHeight: null,             // set minimum height of editor
            maxHeight: null,             // set maximum height of editor
            focus: true,                  // set focus to editable area after initializing summernote,
            lang: 'ko-KR',
            airMode: false,
            toolbar: [
                ['style', ['style']],
                ['font', ['bold', 'italic', 'underline', 'clear']],
                ['fontname', ['fontname']],
                ['color', ['color']],
                ['para', ['ul', 'ol', 'paragraph']],
                ['height', ['height']],
                ['table', ['table']],
                ['insert', ['link', 'picture', 'hr']],
                ['view', ['codeview']],
                ['help', ['help']]
            ]
        });

        this.target = $("#formView01");
        this.model = new ax5.ui.binder();
        this.model.setModel(this.getDefaultData(), this.target);
        this.modelFormatter = new axboot.modelFormatter(this.model); // 모델 포메터 시작

        this.initEvent();

        $('[data-form-view-01-btn]').click(function () {
            var _root = fnObj;
            switch (this.getAttribute("data-form-view-01-btn")) {
                case "form-clear":
                    ACTIONS.dispatch(ACTIONS.FORM_CLEAR);
                    break;
            }
        });
    },
    initEvent: function () {
        var _this = this;
    },
    getData: function () {
        var data = this.modelFormatter.getClearData(this.model.get()); // 모델의 값을 포멧팅 전 값으로 치환.

        data.content = this.summernote.summernote("code");

        return data;
    },
    setData: function (data) {
        this.mask.close();
        $.extend(true, data, this.getDefaultData());
        this.model.setModel(data);
        console.log(this.summernote.summernote("code", data.content||""));
    },
    resize: function(){
        $('.note-editable.panel-body').height(($('#summernote').height() - 200));
    },
    clear: function () {
        this.mask.open();
        this.model.setModel(this.getDefaultData());
    }
});<|endoftext|>


<commit_before>var sakai = sakai || {};

sakai.tangler = function(tuid, placement, showSettings){

	var functiontodoaftersettings = false;
	var rootel = $("#" + tuid);
	var argumentsCalleeDone = false;

	var fillInUniqueId = function(){
		sdata.Ajax.request({
			url :"/sdata/f/" + placement + "/" + tuid + "/tangler?sid=" + Math.random(),
			httpMethod : "GET",
			onSuccess : function(data) {
				showForum(data,true);
			},
			onFail : function(status) {
				showForum(status,false);
			}
		});
	}

	var showForum = function(response, exists){
		if (exists){
			try {

				var split = response.split("<script");

				//extract div
				var div = split[0];

				//extract ID & gID
				var start = split[1].split("embedtopic.js?id=");
				var start2 = split[1].split("&gId=");
				var id = start[1].split("&")[0];
				var gid = start2[1].split("\"")[0];

				//execute their code
				$("#tangler_output",rootel).html(div);

				// quit if this function has already been called
				if (argumentsCalleeDone) return;

				// flag this function so we don't do the same thing twice
				argumentsCalleeDone = true;

				// topic identifier
				//var id = params['id'];
				//if( !checkParam(id, "Tangler: Embed Topic ID not set.") )return;

				// forum identifier
				//var gId = params['gId'];
				//if( !checkParam(gId, "Tangler: Embed Forum ID not set.")) return;

				var eleId = "tangler-embed-topic-" + id;
				var embedElement = $("#" + eleId, rootel)[0];

				var contextUrl = false;
				//var contextUrl = params['cUrl'];

				var width = "410px";
				var height = "480px";

				if( embedElement.style )
				{
					width = embedElement.style.width?embedElement.style.width:'410px';
					height = embedElement.style.height?embedElement.style.height:'480px';
				}
				var iframeSrc = 'http://www.tangler.com/embed/topic/' + id;
				if( contextUrl )
					iframeSrc = contextUrl + "/embed/topic/" + id;

				var iframe = document.createElement("iframe");
				iframe.src = iframeSrc;
				iframe.width = width;
				iframe.height = height;
				iframe.scolling = 'no';
				iframe.marginwidth = '0';
				iframe.marginheight = '0';
				iframe.frameBorder = '0';
				iframe.style.border = 0;
				var isIE = window.ActiveXObject?true:false;
				if( !isIE )
				{
					var a = document.createElement("a");
					a.href = 'http://localhost:8080/forum/id-' + gid + '/topic/' + id;
					a.target = "_blank";
					a.appendChild(document.createTextNode("Join this disucssion"));
					iframe.appendChild(a);
				}

				embedElement.appendChild(iframe);

			} catch (err){

				alert(err);

				$("#tangler_output", rootel).text("No valid Tangler forum found");
			}
		} else {
			$("#tangler_output", rootel).text("No valid Tangler forum found");
		}
	}

	var saveNewSettings = function(){
		var val = $("#tangler_code",rootel).val();
		if (!val || val.replace(/ /g,"%20") == ""){
			sdata.Ajax.request({
				url :"/sdata/f/" + placement + "/" + tuid + "/tangler?sid=" + Math.random(),
				httpMethod : "DELETE",
				onSuccess : function(data) {
					finishNewSettings(true);
				},
				onFail : function(status) {
					finishNewSettings(false);
				}
			});
		}
		else {
			sdata.widgets.WidgetPreference.save("/sdata/f/" + placement + "/" + tuid, "tangler", val, finishNewSettings);
		}
	}

	var finishNewSettings = function(success){
		$("#" + tuid + " #tangler_output").show();
		$("#" + tuid + " #tangler_settings").hide();
		fillInUniqueId();
	}

	if (showSettings){
		$("#" + tuid + " #tangler_output").hide();
		$("#" + tuid + " #tangler_settings").show();
	} else {
		$("#" + tuid + " #tangler_settings").hide();
		$("#" + tuid + " #tangler_output").show();
		fillInUniqueId();
	}

	$("#tangler_save", rootel).bind("click",function(e,ui){
		saveNewSettings();
	});

};

sdata.widgets.WidgetLoader.informOnLoad("tangler");<commit_msg>SAK-15773<commit_after>var sakai = sakai || {};

sakai.tangler = function(tuid, placement, showSettings){

	var functiontodoaftersettings = false;
	var rootel = $("#" + tuid);
	var argumentsCalleeDone = false;

	var fillInUniqueId = function(){
		sdata.Ajax.request({
			url :"/sdata/f/" + placement + "/" + tuid + "/tangler?sid=" + Math.random(),
			httpMethod : "GET",
			onSuccess : function(data) {
				showForum(data,true);
			},
			onFail : function(status) {
				showForum(status,false);
			}
		});
	}

	var loadSavedId = function(){
		sdata.Ajax.request({
			url :"/sdata/f/" + placement + "/" + tuid + "/tangler?sid=" + Math.random(),
			httpMethod : "GET",
			onSuccess : function(data) {
				$("#tangler_code",rootel).val(data);
			},
			onFail : function(status) {
			}
		});
	}

	var showForum = function(response, exists){
		if (exists){
			try {

				var split = response.split("<script");

				//extract div
				var div = split[0];

				//extract ID & gID
				var start = split[1].split("embedtopic.js?id=");
				var start2 = split[1].split("&gId=");
				var id = start[1].split("&")[0];
				var gid = start2[1].split("\"")[0];

				//execute their code
				$("#tangler_output",rootel).html(div);

				// quit if this function has already been called
				if (argumentsCalleeDone) return;

				// flag this function so we don't do the same thing twice
				argumentsCalleeDone = true;

				// topic identifier
				//var id = params['id'];
				//if( !checkParam(id, "Tangler: Embed Topic ID not set.") )return;

				// forum identifier
				//var gId = params['gId'];
				//if( !checkParam(gId, "Tangler: Embed Forum ID not set.")) return;

				var eleId = "tangler-embed-topic-" + id;
				var embedElement = $("#" + eleId, rootel)[0];

				var contextUrl = false;
				//var contextUrl = params['cUrl'];

				var width = "410px";
				var height = "480px";

				if( embedElement.style )
				{
					width = embedElement.style.width?embedElement.style.width:'410px';
					height = embedElement.style.height?embedElement.style.height:'480px';
				}
				var iframeSrc = 'http://www.tangler.com/embed/topic/' + id;
				if( contextUrl )
					iframeSrc = contextUrl + "/embed/topic/" + id;

				var iframe = document.createElement("iframe");
				iframe.src = iframeSrc;
				iframe.width = width;
				iframe.height = height;
				iframe.scolling = 'no';
				iframe.marginwidth = '0';
				iframe.marginheight = '0';
				iframe.frameBorder = '0';
				iframe.style.border = 0;
				var isIE = window.ActiveXObject?true:false;
				if( !isIE )
				{
					var a = document.createElement("a");
					a.href = 'http://localhost:8080/forum/id-' + gid + '/topic/' + id;
					a.target = "_blank";
					a.appendChild(document.createTextNode("Join this disucssion"));
					iframe.appendChild(a);
				}

				embedElement.appendChild(iframe);

			} catch (err){

				alert(err);

				$("#tangler_output", rootel).text("No valid Tangler forum found");
			}
		} else {
			$("#tangler_output", rootel).text("No valid Tangler forum found");
		}
	}

	var saveNewSettings = function(){
		var val = $("#tangler_code",rootel).val();
		if (!val || val.replace(/ /g,"%20") == ""){
			sdata.Ajax.request({
				url :"/sdata/f/" + placement + "/" + tuid + "/tangler?sid=" + Math.random(),
				httpMethod : "DELETE",
				onSuccess : function(data) {
					finishNewSettings(true);
				},
				onFail : function(status) {
					finishNewSettings(false);
				}
			});
		}
		else {
			sdata.widgets.WidgetPreference.save("/sdata/f/" + placement + "/" + tuid, "tangler", val, finishNewSettings);
		}
	}

	var finishNewSettings = function(success){
		sdata.container.informFinish(tuid);
	}

	if (showSettings){
		$("#" + tuid + " #tangler_output").hide();
		$("#" + tuid + " #tangler_settings").show();
		loadSavedId();
	} else {
		$("#" + tuid + " #tangler_settings").hide();
		$("#" + tuid + " #tangler_output").show();
		fillInUniqueId();
	}

	$("#tangler_save", rootel).bind("click",function(e,ui){
		saveNewSettings();
	});
	$("#tangler_cancel", rootel).bind("click",function(e,ui){
		sdata.container.informCancel(tuid);
	});

};

sdata.widgets.WidgetLoader.informOnLoad("tangler");<|endoftext|>