<commit_before>window.cls || (window.cls = {});

/**
  * @constructor
  * @extends ViewBase
  */

cls.WatchesView = function(id, name, container_class)
{
  /* interface */
  /* inherits from ViewBase */
  /* implements action handler interface */

  this.add_watch = function(key, uid){};

  /* constants */

  const
  MODE_DEFAULT = "default",
  MODE_EDIT = "edit";

  /* private */
  /* templates */

  this._tmpl_main = function()
  {
    return (
    [
      ['div'],
      ['div',
        ['button',
          ['span', ui_strings.S_LABEL_ADD_WATCH],
          'handler', 'watches-add',
          'class', 'container-button'
        ],
        'class', 'watches-controls padding'
      ]
    ]);
  };

  this._tmpl_new_prop = function()
  {
    return ['item', ['key', 'class', 'no-expander', 'data-prop-uid', '0']];
  };

  this._check_no_content = function()
  {
    var proto = this._watch_container &&
                this._watch_container.getElementsByClassName('prototype')[0];
    if (proto && !proto.textContent)
    {
      proto.clearAndRender(['div', ui_strings.M_VIEW_LABEL_NO_WATCHES,
                            'class', 'not-content']);
    }
  }

  /* action handler interface */

  ActionHandlerInterface.apply(this);

  this.onclick = function(event)
  {
    if (this.mode == MODE_EDIT)
    {
      if (this._add_watches_button == event.target)
      {
        return false;
      }
      if (this._editor.onclick(event))
      {
        this.mode = MODE_DEFAULT;
        this._add_watches_button.disabled = false;
        return true;
      }
      return false;
    }
    return true;
  };

  this._handlers['edit'] = function(event, target)
  {
    var ele = this._get_editable_item(event, target);
    if (ele)
    {
      this.mode = MODE_EDIT;
      this._editor.edit(event, ele);
      this._add_watches_button.disabled = true;
    }
  }.bind(this);

  this._handlers['delete'] = function(event, target)
  {
    var ele = this._get_editable_item(event, target);
    if (ele)
    {
      this._data.remove_property(ele.getAttribute('data-prop-uid'));
    }
    this._check_no_content();
  }.bind(this);

  this._handlers['delete-all'] = function(event, target)
  {
    this._data.remove_all_properties();
    this._check_no_content();
  }.bind(this);

  this._handlers['submit'] = function(event, target)
  {
    if (this.mode == MODE_EDIT)
    {
      this._editor.submit();
      this._check_no_content();
      this._add_watches_button.disabled = false;
      return false;
    }
  }.bind(this);

  this._handlers['cancel'] = function(event, target)
  {
    if (this.mode == MODE_EDIT)
    {
      this._editor.cancel();
      this._check_no_content();
      this._add_watches_button.disabled = false;
      return false;
    }
  }.bind(this);

  this._handlers['add'] = function(event, target)
  {
    if (this._watch_container)
    {
      var proto = this._watch_container.getElementsByClassName('prototype')[0];
      if (proto)
      {
        var no_content = proto.getElementsByClassName('not-content')[0];
        if (no_content)
        {
          proto.removeChild(no_content);
        }
        var key = proto.render(this._tmpl_new_prop()).firstElementChild;
        this.mode = MODE_EDIT;
        this._editor.edit(event, key);
        this._add_watches_button.disabled = true;
      }
    }
  }.bind(this);

  this._onframeselected = function(msg)
  {
    if (msg.frame_index != -1 || this._last_selected_frame_index != -1)
    {
      this._data.update_watches();
    }
    this._last_selected_frame_index = msg.frame_index;
  };

  this._get_editable_item = function(event, target)
  {
    var ele = event.target;
    while (ele && ele.nodeName.toLowerCase() != 'item' &&
          (ele = ele.parentNode) && ele != target);
    ele = ele && ele.getElementsByTagName('key')[0];
    if (ele && ele.hasAttribute('data-prop-uid'))
    {
      return ele;
    }
    return null;
  };

  /* rightclick menu */

  this._menu_common_items =
  [
    {
      label: ui_strings.S_LABEL_ADD_WATCH,
      handler: this._handlers['add']
    }
  ];

  this._menu_editable_items =
  [
    {
      label: ui_strings.S_LABEL_EDIT_WATCH,
      handler: this._handlers['edit']
    },
    {
      label: ui_strings.S_LABEL_DELETE_WATCH,
      handler: this._handlers['delete']
    },
    {
      label: ui_strings.S_LABEL_DELETE_ALL_WATCHES,
      handler: this._handlers['delete-all']
    }
  ]
  .concat(ContextMenu.separator)
  .concat(this._menu_common_items);

  this._menu =
  [
    {
      callback: function(event, target)
      {
        return (
        this._get_editable_item(event, target) ?
        this._menu_editable_items :
        this._menu_common_items);
      }.bind(this)
    }
  ];

  this._init = function(id, name, container_class)
  {
    this.init(id, name, container_class, null, null, 'watches-edit-prop');
    this._last_selected_frame_index = 0;
    this._watch_container = null;
    this._data = new cls.Watches(this);
    this._editor = new cls.JSPropertyEditor(this);
    eventHandlers.dblclick['watches-edit-prop'] = this._handlers['edit'];
    eventHandlers.click['watches-add'] = this._handlers['add'];
    ActionBroker.get_instance().register_handler(this);
    ContextMenu.get_instance().register("watches", this._menu);
    messages.addListener('frame-selected', this._onframeselected.bind(this));
  };

  /* implementation */

  this.createView = function(container)
  {
    if (!this._watch_container)
    {
      container.clearAndRender(this._tmpl_main());
      this._watch_container = container.firstElementChild;
      this._add_watches_button = container.getElementsByTagName('button')[0];
    }
    var tmpl = window.templates.inspected_js_object(this._data, false, null);
    this._watch_container.clearAndRender(tmpl);
    this._check_no_content();
  };

  this.ondestroy = function()
  {
    this._watch_container = null;
    this._add_watches_button = null;
  };

  this.add_watch = function(key, uid)
  {
    if (key)
    {
      this._data.add_property(key, uid);
    }
    else
    {
      this._data.remove_property(uid);
    }
  };

  this._init(id, name, container_class);

};
<commit_msg>Added unselectable attribute to a button.<commit_after>window.cls || (window.cls = {});

/**
  * @constructor
  * @extends ViewBase
  */

cls.WatchesView = function(id, name, container_class)
{
  /* interface */
  /* inherits from ViewBase */
  /* implements action handler interface */

  this.add_watch = function(key, uid){};

  /* constants */

  const
  MODE_DEFAULT = "default",
  MODE_EDIT = "edit";

  /* private */
  /* templates */

  this._tmpl_main = function()
  {
    return (
    [
      ['div'],
      ['div',
        ['button',
          ['span', ui_strings.S_LABEL_ADD_WATCH],
          'handler', 'watches-add',
          'class', 'container-button',
          'unselectable', 'on'
        ],
        'class', 'watches-controls padding'
      ]
    ]);
  };

  this._tmpl_new_prop = function()
  {
    return ['item', ['key', 'class', 'no-expander', 'data-prop-uid', '0']];
  };

  this._check_no_content = function()
  {
    var proto = this._watch_container &&
                this._watch_container.getElementsByClassName('prototype')[0];
    if (proto && !proto.textContent)
    {
      proto.clearAndRender(['div', ui_strings.M_VIEW_LABEL_NO_WATCHES,
                            'class', 'not-content']);
    }
  }

  /* action handler interface */

  ActionHandlerInterface.apply(this);

  this.onclick = function(event)
  {
    if (this.mode == MODE_EDIT)
    {
      if (this._add_watches_button == event.target)
      {
        return false;
      }
      if (this._editor.onclick(event))
      {
        this.mode = MODE_DEFAULT;
        this._add_watches_button.disabled = false;
        return true;
      }
      return false;
    }
    return true;
  };

  this._handlers['edit'] = function(event, target)
  {
    var ele = this._get_editable_item(event, target);
    if (ele)
    {
      this.mode = MODE_EDIT;
      this._editor.edit(event, ele);
      this._add_watches_button.disabled = true;
    }
  }.bind(this);

  this._handlers['delete'] = function(event, target)
  {
    var ele = this._get_editable_item(event, target);
    if (ele)
    {
      this._data.remove_property(ele.getAttribute('data-prop-uid'));
    }
    this._check_no_content();
  }.bind(this);

  this._handlers['delete-all'] = function(event, target)
  {
    this._data.remove_all_properties();
    this._check_no_content();
  }.bind(this);

  this._handlers['submit'] = function(event, target)
  {
    if (this.mode == MODE_EDIT)
    {
      this._editor.submit();
      this._check_no_content();
      this._add_watches_button.disabled = false;
      return false;
    }
  }.bind(this);

  this._handlers['cancel'] = function(event, target)
  {
    if (this.mode == MODE_EDIT)
    {
      this._editor.cancel();
      this._check_no_content();
      this._add_watches_button.disabled = false;
      return false;
    }
  }.bind(this);

  this._handlers['add'] = function(event, target)
  {
    if (this._watch_container)
    {
      var proto = this._watch_container.getElementsByClassName('prototype')[0];
      if (proto)
      {
        var no_content = proto.getElementsByClassName('not-content')[0];
        if (no_content)
        {
          proto.removeChild(no_content);
        }
        var key = proto.render(this._tmpl_new_prop()).firstElementChild;
        this.mode = MODE_EDIT;
        this._editor.edit(event, key);
        this._add_watches_button.disabled = true;
      }
    }
  }.bind(this);

  this._onframeselected = function(msg)
  {
    if (msg.frame_index != -1 || this._last_selected_frame_index != -1)
    {
      this._data.update_watches();
    }
    this._last_selected_frame_index = msg.frame_index;
  };

  this._get_editable_item = function(event, target)
  {
    var ele = event.target;
    while (ele && ele.nodeName.toLowerCase() != 'item' &&
          (ele = ele.parentNode) && ele != target);
    ele = ele && ele.getElementsByTagName('key')[0];
    if (ele && ele.hasAttribute('data-prop-uid'))
    {
      return ele;
    }
    return null;
  };

  /* rightclick menu */

  this._menu_common_items =
  [
    {
      label: ui_strings.S_LABEL_ADD_WATCH,
      handler: this._handlers['add']
    }
  ];

  this._menu_editable_items =
  [
    {
      label: ui_strings.S_LABEL_EDIT_WATCH,
      handler: this._handlers['edit']
    },
    {
      label: ui_strings.S_LABEL_DELETE_WATCH,
      handler: this._handlers['delete']
    },
    {
      label: ui_strings.S_LABEL_DELETE_ALL_WATCHES,
      handler: this._handlers['delete-all']
    }
  ]
  .concat(ContextMenu.separator)
  .concat(this._menu_common_items);

  this._menu =
  [
    {
      callback: function(event, target)
      {
        return (
        this._get_editable_item(event, target) ?
        this._menu_editable_items :
        this._menu_common_items);
      }.bind(this)
    }
  ];

  this._init = function(id, name, container_class)
  {
    this.init(id, name, container_class, null, null, 'watches-edit-prop');
    this._last_selected_frame_index = 0;
    this._watch_container = null;
    this._data = new cls.Watches(this);
    this._editor = new cls.JSPropertyEditor(this);
    eventHandlers.dblclick['watches-edit-prop'] = this._handlers['edit'];
    eventHandlers.click['watches-add'] = this._handlers['add'];
    ActionBroker.get_instance().register_handler(this);
    ContextMenu.get_instance().register("watches", this._menu);
    messages.addListener('frame-selected', this._onframeselected.bind(this));
  };

  /* implementation */

  this.createView = function(container)
  {
    if (!this._watch_container)
    {
      container.clearAndRender(this._tmpl_main());
      this._watch_container = container.firstElementChild;
      this._add_watches_button = container.getElementsByTagName('button')[0];
    }
    var tmpl = window.templates.inspected_js_object(this._data, false, null);
    this._watch_container.clearAndRender(tmpl);
    this._check_no_content();
  };

  this.ondestroy = function()
  {
    this._watch_container = null;
    this._add_watches_button = null;
  };

  this.add_watch = function(key, uid)
  {
    if (key)
    {
      this._data.add_property(key, uid);
    }
    else
    {
      this._data.remove_property(uid);
    }
  };

  this._init(id, name, container_class);

};
<|endoftext|>


<commit_before>window.ScrubGSAPTimeline = (tl) => {
    let mainTl = gsap.timeline();
    if (Object.prototype.toString.call(tl) === '[object Array]') {
        let i = tl.length;
        while (--i > -1) {
            mainTl.add(tl[i], 0);
        }

    } else {
        mainTl = tl;
    }
    const Scrubber = (_tl) => {

        let mouseMove = (e) => {
                box.innerHTML = parseFloat(_tl.time()).toFixed(2);
                _tl.pause();
                _tl.progress(e.clientX / (window.innerWidth));
                mouseX = e.clientX, mouseY = e.clientY;

                gsap.set(box, {
                    x: (mouseX >= (window.innerWidth - 48)) ? mouseX - 48 : mouseX,
                    y: (mouseY <= 20) ? mouseY + 20 : mouseY - 20
                })
            },
            mouseOver = (e) => {
                _tl.pause();
                _tl.play(0);
                gsap.set(box, {
                    autoAlpha: 1
                })
            },
            mouseOut = (e) => {
                _tl.play(e.clientX / (window.innerWidth) * _tl.duration());
                gsap.set(box, {
                    autoAlpha: 0
                })
            },
            box = document.createElement('div'),
            mouseX, mouseY, gGreen = '#53A018',
            cssText = "position:fixed;border-radius:4px;font-size:14px;padding:5px;user-select:none;pointer-events:none;text-align:center;color:#53A018;top:0;left:0;font-family:Helvetica, Arial, sans-serif;background-color:#262626;line-height:1 !important;z-index:99999999"
        box.style.cssText = cssText;

        document.body.appendChild(box);
        document.body.onmousemove = mouseMove;
        document.body.onmouseover = mouseOver;
        document.body.onmouseout = mouseOut;
        document.body.ondblclick = (e) => {
            if (!document.body.onmousemove) {
                gsap.to(box, {
                    duration: 0.2,
                    color: gGreen
                })
                document.body.onmousemove = mouseMove;
                document.body.onmouseover = mouseOver;
                document.body.onmouseout = mouseOut;
                return;
            }

            gsap.to(box, {
                duration: 0.2,
                color: '#A31632'
            })
            document.body.onmousemove = null;
            document.body.onmouseover = null;
            document.body.onmouseout = null;
            _tl.pause();

        }

    }

    Scrubber(mainTl);

}
<commit_msg>Update ScrubGSAPTimeline_v3.js<commit_after>window.ScrubGSAPTimeline = (tl) => {

	document.body.childNodes.forEach(target => {
		gsap.set(target, {
			pointerEvents: 'none'
		})
	})
    let mainTl = gsap.timeline();
    if (Object.prototype.toString.call(tl) === '[object Array]') {
        let i = tl.length;
        while (--i > -1) {
            mainTl.add(tl[i], 0);
        }

    } else {
        mainTl = tl;
    }
    const Scrubber = (_tl) => {

        let mouseMove = (e) => {

                box.innerHTML = parseFloat(_tl.time()).toFixed(2);
                _tl.pause();
                _tl.progress(e.clientX / (window.innerWidth));
                mouseX = e.clientX, mouseY = e.clientY;

                gsap.set(box, {
                    x: (mouseX >= (window.innerWidth - 48)) ? mouseX - 48 : mouseX,
                    y: (mouseY <= 20) ? mouseY + 20 : mouseY - 20
                })
            },
            mouseOver = (e) => {
                _tl.pause();
                _tl.play(0);
                gsap.set(box, {
                    autoAlpha: 1
                })
            },
            mouseOut = (e) => {
                _tl.play(e.clientX / (window.innerWidth) * _tl.duration());
                gsap.set(box, {
                    autoAlpha: 0
                })
            },
            box = document.createElement('div'),
            mouseX, mouseY, gGreen = '#53A018',
            cssText = "position:fixed;border-radius:4px;font-size:14px;padding:5px;user-select:none;pointer-events:none;text-align:center;color:#53A018;top:0;left:0;font-family:Helvetica, Arial, sans-serif;background-color:#262626;line-height:1 !important;z-index:99999999"
        box.style.cssText = cssText;

        document.body.appendChild(box);
        document.body.onmousemove = mouseMove;
        document.body.onmouseover = mouseOver;
        document.body.onmouseout = mouseOut;
        document.body.ondblclick = (e) => {
            if (!document.body.onmousemove) {
                gsap.to(box, {
                    duration: 0.2,
                    color: gGreen
                })
                document.body.onmousemove = mouseMove;
                document.body.onmouseover = mouseOver;
                document.body.onmouseout = mouseOut;
                return;
            }

            gsap.to(box, {
                duration: 0.2,
                color: '#A31632'
            })
            document.body.onmousemove = null;
            document.body.onmouseover = null;
            document.body.onmouseout = null;
            _tl.pause();

        }

    }

		//console.log(document.body.childNodes)

    Scrubber(mainTl);

}
<|endoftext|>


<commit_before>/*
  Copyright Jesús Pérez <jesusprubio@gmail.com>

  This code may only be used under the MIT license found at
  https://opensource.org/licenses/MIT.
*/

'use strict';

const path = require('path');

const phantom = require('phantom');

const utils = require('../../../lib/utils');
const defaultUa = require('../../../cfg/uas').http;

const dbg = utils.dbg(__filename);

module.exports.desc = 'Take a screenshoot of a website.';

module.exports.opts = {
  url: {
    types: 'url',
    desc: 'URL to explore',
    default: 'http://example.com/',
  },
  path: {
    desc: 'Path to store the output file (relative to from where Bluebox was launched)',
    default: '.',
  },
  // TODO: Support this parameter in the method.
  // timeout: {
  //   types: 'natural',
  //   desc: 'Time to wait for a response, in ms.',
  //   default: 5000,
  // },
};

module.exports.impl = (opts = {}) =>
  new Promise((resolve, reject) => {
    let oPath;

    // TODO: Output file name hardcoded for now, add an option.
    if (opts.path) {
      oPath =
        path.resolve(process.cwd(), opts.path, `shoot-${new Date().toISOString()}.png`);
    }
    const result = {};
    const uaStr = opts.ua || defaultUa;
    const outPath = oPath || `${process.cwd()}shoot-${new Date().toISOString()}.png`;

    dbg('Inspecting the web page ...');
    phantom.create(['--ignore-ssl-errors=yes'])
    .then((instance) => {
      const phInstance = instance;

      instance.createPage()
      .then((page) => {
        // eslint-disable-next-line no-param-reassign
        page.property('viewportSize', { width: 800, height: 600 });
        // eslint-disable-next-line no-param-reassign
        page.property('userAgent', uaStr);

        page.open(opts.url)
        .then(() => {
          dbg(`Page opened, shooting ..., url: "${opts.url}"`);
          page.render(outPath)
          .then(() => {
            // Phantom not needed anymore
            phInstance.exit();

            dbg('Shoot done correctly');
            result.path = outPath;
            resolve(result);
          })
          .catch((err) => {
            phInstance.exit();
            reject(new Error(`Taking the screenshoot: ${opts.url}: ${err.message}`));
          });
        })
        .catch((err) => {
          phInstance.exit();
          reject(new Error(`Opening the website: ${opts.url}: ${err.message}`));
        });
      })
      .catch((err) => {
        phInstance.exit();
        reject(new Error(`phantom (createPage): ${err.message}`));
      });
    })
    .catch(err => reject(new Error(`phantom (create): ${err.message}`)));
  });
<commit_msg>Minor TODO.<commit_after>/*
  Copyright Jesús Pérez <jesusprubio@gmail.com>

  This code may only be used under the MIT license found at
  https://opensource.org/licenses/MIT.
*/

'use strict';

const path = require('path');

const phantom = require('phantom');

const utils = require('../../../lib/utils');
const defaultUa = require('../../../cfg/uas').http;

const dbg = utils.dbg(__filename);

module.exports.desc = 'Take a screenshoot of a website.';

module.exports.opts = {
  // TODO: Integrate in the report.
  url: {
    types: 'url',
    desc: 'URL to explore',
    default: 'http://example.com/',
  },
  path: {
    desc: 'Path to store the output file (relative to from where Bluebox was launched)',
    default: '.',
  },
  // TODO: Support this parameter in the method.
  // timeout: {
  //   types: 'natural',
  //   desc: 'Time to wait for a response, in ms.',
  //   default: 5000,
  // },
};

module.exports.impl = (opts = {}) =>
  new Promise((resolve, reject) => {
    let oPath;

    // TODO: Output file name hardcoded for now, add an option.
    if (opts.path) {
      oPath =
        path.resolve(process.cwd(), opts.path, `shoot-${new Date().toISOString()}.png`);
    }
    const result = {};
    const uaStr = opts.ua || defaultUa;
    const outPath = oPath || `${process.cwd()}shoot-${new Date().toISOString()}.png`;

    dbg('Inspecting the web page ...');
    phantom.create(['--ignore-ssl-errors=yes'])
    .then((instance) => {
      const phInstance = instance;

      instance.createPage()
      .then((page) => {
        // eslint-disable-next-line no-param-reassign
        page.property('viewportSize', { width: 800, height: 600 });
        // eslint-disable-next-line no-param-reassign
        page.property('userAgent', uaStr);

        page.open(opts.url)
        .then(() => {
          dbg(`Page opened, shooting ..., url: "${opts.rhost}"`);
          page.render(outPath)
          .then(() => {
            // Phantom not needed anymore
            phInstance.exit();

            dbg('Shoot done correctly');
            result.path = outPath;
            resolve(result);
          })
          .catch((err) => {
            phInstance.exit();
            reject(new Error(`Taking the screenshoot: ${opts.rhost}: ${err.message}`));
          });
        })
        .catch((err) => {
          phInstance.exit();
          reject(new Error(`Opening the website: ${opts.rhost}: ${err.message}`));
        });
      })
      .catch((err) => {
        phInstance.exit();
        reject(new Error(`phantom (createPage): ${err.message}`));
      });
    })
    .catch(err => reject(new Error(`phantom (create): ${err.message}`)));
  });
<|endoftext|>


<commit_before><commit_msg>Fix garbage collector leak<commit_after><|endoftext|>


<commit_before>import EventEmitter from 'events';

/**
 * The class implements basic event operations - add/remove listener.
 * NOTE: The purpose of the class is to be extended in order to add
 * this functionality to other classes.
 */
export default class Listenable {
    /**
     * Creates new instance.
     * @param {EventEmitter} eventEmitter
     * @constructor
     */
    constructor(eventEmitter = new EventEmitter()) {
        this.eventEmitter = eventEmitter;

        // aliases for addListener/removeListener
        this.addEventListener = this.on = this.addListener;
        this.removeEventListener = this.off = this.removeListener;
    }

    /**
     * Adds new listener.
     * @param {String} eventName the name of the event
     * @param {Function} listener the listener.
     */
    addListener(eventName, listener) {
        this.eventEmitter.addListener(eventName, listener);
    }

    /**
     * Removes listener.
     * @param {String} eventName the name of the event that triggers the
     * listener
     * @param {Function} listener the listener.
     */
    removeListener(eventName, listener) {
        this.eventEmitter.removeListener(eventName, listener);
    }
}
<commit_msg>feat(Listenable): make addListener remove unsubscribe method<commit_after>import EventEmitter from 'events';

/**
 * The class implements basic event operations - add/remove listener.
 * NOTE: The purpose of the class is to be extended in order to add
 * this functionality to other classes.
 */
export default class Listenable {
    /**
     * Creates new instance.
     * @param {EventEmitter} eventEmitter
     * @constructor
     */
    constructor(eventEmitter = new EventEmitter()) {
        this.eventEmitter = eventEmitter;

        // aliases for addListener/removeListener
        this.addEventListener = this.on = this.addListener;
        this.removeEventListener = this.off = this.removeListener;
    }

    /**
     * Adds new listener.
     * @param {String} eventName the name of the event
     * @param {Function} listener the listener.
     * @returns {Function} - The unsubscribe function.
     */
    addListener(eventName, listener) {
        this.eventEmitter.addListener(eventName, listener);

        return () => this.removeEventListener(eventName, listener);
    }

    /**
     * Removes listener.
     * @param {String} eventName the name of the event that triggers the
     * listener
     * @param {Function} listener the listener.
     */
    removeListener(eventName, listener) {
        this.eventEmitter.removeListener(eventName, listener);
    }
}
<|endoftext|>


<commit_before>sap.ui.define([
		'jquery.sap.global',
		'sap/m/MessageToast',
		'sap/m/UploadCollectionParameter',
		'sap/ui/core/mvc/Controller',
		'sap/ui/model/json/JSONModel'
	], function(jQuery, MessageToast, UploadCollectionParameter, Controller, JSONModel) {
	"use strict";

	var PageController = Controller.extend("sap.m.sample.UploadCollection.Page", {

		onInit: function () {
			// set mock data
			var sPath = jQuery.sap.getModulePath("sap.m.sample.UploadCollection", "/uploadCollection.json")
			var oModel = new JSONModel(sPath);
			this.getView().setModel(oModel);

			var aDataCB = {
				"items" : [{
					"key" : "All",
					"text" : "sap.m.ListSeparators.All"
				}, {
					"key" : "None",
					"text" : "sap.m.ListSeparators.None"
				}],
				"selectedKey" : "All"
			};

			var oModelCB = new JSONModel();
			oModelCB.setData(aDataCB);

			var oSelect = this.getView().byId("tbSelect");
			oSelect.setModel(oModelCB);
		},

		onBeforeRendering : function () {
			// Sets the text to the label
			this.getView().byId("attachmentTitle").setText(this.getAttachmentTitleText());
		},

		formatAttribute : function (sValue) {
			jQuery.sap.require("sap.ui.core.format.FileSizeFormat");
			if (jQuery.isNumeric(sValue)) {
				return sap.ui.core.format.FileSizeFormat.getInstance({
					binaryFilesize : false,
					maxFractionDigits : 1,
					maxIntegerDigits : 3
				}).format(sValue);
			} else {
				return sValue
			}
		},

		onChange: function(oEvent) {
			var oUploadCollection = oEvent.getSource();
			// Header Token
			var oCustomerHeaderToken = new UploadCollectionParameter({
				name : "x-csrf-token",
				value : "securityTokenFromModel"
			});
			oUploadCollection.addHeaderParameter(oCustomerHeaderToken);
		},

		onFileDeleted: function(oEvent) {
			this.deleteItemById(oEvent.getParameter("documentId"));
			MessageToast.show("FileDeleted event triggered.");
		},

		deleteItemById: function(sItemToDeleteId){
			var oData = this.getView().byId("UploadCollection").getModel().getData();
			var aItems = jQuery.extend(true, {}, oData).items;
			jQuery.each(aItems, function(index) {
				if (aItems[index] && aItems[index].documentId === sItemToDeleteId) {
					aItems.splice(index, 1);
				};
			});
			this.getView().byId("UploadCollection").getModel().setData({
				"items" : aItems
			});
			this.getView().byId("attachmentTitle").setText(this.getAttachmentTitleText());
		},

		deleteMultipleItems: function(aItemsToDelete){
			var oData = this.getView().byId("UploadCollection").getModel().getData();
			var nItemsToDelete = aItemsToDelete.length;
			var aItems = jQuery.extend(true, {}, oData).items;
			var i = 0;
			jQuery.each(aItems, function(index) {
				if (aItems[index]) {
					for (i = 0; i < nItemsToDelete; i++){
						if (aItems[index].documentId === aItemsToDelete[i].getDocumentId()){
							aItems.splice(index, 1);
						}
					}
				};
			});
			this.getView().byId("UploadCollection").getModel().setData({
				"items" : aItems
			});
			this.getView().byId("attachmentTitle").setText(this.getAttachmentTitleText());
		},

		onFilenameLengthExceed : function(oEvent) {
			MessageToast.show("FilenameLengthExceed event triggered.");
		},

		onFileRenamed: function(oEvent) {
			var oData = this.getView().byId("UploadCollection").getModel().getData();
			var aItems = jQuery.extend(true, {}, oData).items;
			var sDocumentId = oEvent.getParameter("documentId");
			jQuery.each(aItems, function(index) {
				if (aItems[index] && aItems[index].documentId === sDocumentId) {
					aItems[index].fileName = oEvent.getParameter("item").getFileName();
				};
			});
			this.getView().byId("UploadCollection").getModel().setData({
				"items" : aItems
			});
			MessageToast.show("FileRenamed event triggered.");
		},

		onFileSizeExceed : function(oEvent) {
			MessageToast.show("FileSizeExceed event triggered.");
		},

		onTypeMissmatch : function(oEvent) {
			MessageToast.show("TypeMissmatch event triggered.");
		},

		onUploadComplete: function(oEvent) {
			var oData = this.getView().byId("UploadCollection").getModel().getData();
			var aItems = jQuery.extend(true, {}, oData).items;
			var oItem = {};
			var sUploadedFile = oEvent.getParameter("files")[0].fileName;
			// at the moment parameter fileName is not set in IE9
			if (!sUploadedFile) {
				var aUploadedFile = (oEvent.getParameters().getSource().getProperty("value")).split(/\" "/);
				sUploadedFile = aUploadedFile[0];
			}
			oItem = {
					"documentId" : jQuery.now().toString(), // generate Id,
					"fileName" : sUploadedFile,
					"mimeType" : "",
					"thumbnailUrl" : "",
					"url" : "",
					"attributes":[
						{
							"title" : "Uploaded By",
							"text" : "You"
						},
						{
							"title" : "Uploaded On",
							"text" : new Date(jQuery.now()).toLocaleDateString()
						},
						{
							"title" : "File Size",
							"text" : "505000"
						}
					]
			};

			if (this.getView().byId("modeSwitch").getState()){
				oItem.visibleEdit = false;
				oItem.visibleDelete = false;
			}else{
				oItem.visibleEdit = true;
				oItem.visibleDelete = true;
			}
			aItems.unshift(oItem);
			this.getView().byId("UploadCollection").getModel().setData({
				"items" : aItems
			});
			// Sets the text to the label
			this.getView().byId("attachmentTitle").setText(this.getAttachmentTitleText());
			// delay the success message for to notice onChange message
			setTimeout(function() {
				MessageToast.show("UploadComplete event triggered.");
			}, 4000);
		},

		onSelectChange:  function(oEvent) {
			var oUploadCollection= this.getView().byId("UploadCollection");
			oUploadCollection.setShowSeparators(oEvent.getParameters().selectedItem.getProperty("key"));
		},

		onBeforeUploadStarts: function(oEvent) {
			// Header Slug
			var oCustomerHeaderSlug = new sap.m.UploadCollectionParameter({
				name : "slug",
				value : oEvent.getParameter("fileName")
			});
			oEvent.getParameters().addHeaderParameter(oCustomerHeaderSlug);
			MessageToast.show("BeforeUploadStarts event triggered.");
		},

		onUploadTerminated: function(oEvent) {
			// get parameter file name
			var sFileName = oEvent.getParameter("fileName");
			// get a header parameter (in case no parameter specified, the callback function getHeaderParameter returns all request headers)
			var oRequestHeaders = oEvent.getParameters().getHeaderParameter();
		},

		onSelectAllPress: function(oEvent) {
			var oUploadCollection = this.getView().byId("UploadCollection");

			if (!oEvent.getSource().getPressed()){
				this.deselectAllItems(oUploadCollection);
				oEvent.getSource().setPressed(false);
				oEvent.getSource().setText("Select all");
			} else {
				this.deselectAllItems(oUploadCollection);
				oUploadCollection.selectAll();
				oEvent.getSource().setPressed(true);
				oEvent.getSource().setText("Deselect all");
			}
		},

		deselectAllItems: function(oUploadCollection){
			var aItems = oUploadCollection.getItems();
			for (var i = 0; i < aItems.length; i++){
				oUploadCollection.setSelectedItem(aItems[i], false);
			}
		},

		getAttachmentTitleText: function(){
			var aItems = this.getView().byId("UploadCollection").getItems();
			return "Uploaded (" + aItems.length + ")";
		},

		onSwitchUploaderChange: function(oEvent){
			var oUploadCollection = this.getView().byId("UploadCollection");
			var bState = oEvent.getParameter("state");
			if (bState){
				oUploadCollection.setUploadEnabled(true);
			} else {
				oUploadCollection.setUploadEnabled(false);
			}
		},

		onSwitchModeChange: function(oEvent){
			// Sets to MultiSelect
			if (this.getView().byId("modeSwitch").getState()){
				this.setVisibleEditAndDelete(false);
				this.enableToolbarItems(true);
				this.getView().byId("UploadCollection").setMode("MultiSelect");
			}else{
				// Sets to SingleSelectMaster
				this.setVisibleEditAndDelete(true);
				this.enableToolbarItems(false);
				this.getView().byId("UploadCollection").setMode("SingleSelectMaster");
			}
		},

		setVisibleEditAndDelete: function(status){
			var aItems = this.getView().byId("UploadCollection").getItems();
			for (var i = 0; i < aItems.length; i++){
				aItems[i].setVisibleEdit(status);
				aItems[i].setVisibleDelete(status);
			}
		},

		enableToolbarItems: function(status){
			this.getView().byId("selectAllButton").setEnabled(status);
			this.getView().byId("deleteSelectedButton").setEnabled(status);
		},

		onDeleteSelectedItems: function(){
			var aSelectedItems = this.getView().byId("UploadCollection").getSelectedItems();
			this.deleteMultipleItems(aSelectedItems);
			if (this.getView().byId("UploadCollection").getSelectedItems().length < 1){
				this.getView().byId("selectAllButton").setPressed(false);
				this.getView().byId("selectAllButton").setText("Select all");
			}
			MessageToast.show("Delete selected items button press.");
		},

		onSearch: function(oEvent){
			MessageToast.show("Search feature isn't available in this sample");
		}
	});

	return PageController;

});<commit_msg>[INTERNAL] sap.m.UploadCollection: Number of attachments at first rendering corrected in explored<commit_after>sap.ui.define([
		'jquery.sap.global',
		'sap/m/MessageToast',
		'sap/m/UploadCollectionParameter',
		'sap/ui/core/mvc/Controller',
		'sap/ui/model/json/JSONModel'
	], function(jQuery, MessageToast, UploadCollectionParameter, Controller, JSONModel) {
	"use strict";

	var PageController = Controller.extend("sap.m.sample.UploadCollection.Page", {

		onInit: function () {
			// set mock data
			var sPath = jQuery.sap.getModulePath("sap.m.sample.UploadCollection", "/uploadCollection.json")
			var oModel = new JSONModel(sPath);
			this.getView().setModel(oModel);

			var aDataCB = {
				"items" : [{
					"key" : "All",
					"text" : "sap.m.ListSeparators.All"
				}, {
					"key" : "None",
					"text" : "sap.m.ListSeparators.None"
				}],
				"selectedKey" : "All"
			};

			var oModelCB = new JSONModel();
			oModelCB.setData(aDataCB);

			var oSelect = this.getView().byId("tbSelect");
			oSelect.setModel(oModelCB);

			// Sets the text to the label
			this.getView().byId("UploadCollection").addEventDelegate({
				onBeforeRendering : function () {
					this.getView().byId("attachmentTitle").setText(this.getAttachmentTitleText())
				}.bind(this)
			});
		},

		formatAttribute : function (sValue) {
			jQuery.sap.require("sap.ui.core.format.FileSizeFormat");
			if (jQuery.isNumeric(sValue)) {
				return sap.ui.core.format.FileSizeFormat.getInstance({
					binaryFilesize : false,
					maxFractionDigits : 1,
					maxIntegerDigits : 3
				}).format(sValue);
			} else {
				return sValue
			}
		},

		onChange: function(oEvent) {
			var oUploadCollection = oEvent.getSource();
			// Header Token
			var oCustomerHeaderToken = new UploadCollectionParameter({
				name : "x-csrf-token",
				value : "securityTokenFromModel"
			});
			oUploadCollection.addHeaderParameter(oCustomerHeaderToken);
		},

		onFileDeleted: function(oEvent) {
			this.deleteItemById(oEvent.getParameter("documentId"));
			MessageToast.show("FileDeleted event triggered.");
		},

		deleteItemById: function(sItemToDeleteId){
			var oData = this.getView().byId("UploadCollection").getModel().getData();
			var aItems = jQuery.extend(true, {}, oData).items;
			jQuery.each(aItems, function(index) {
				if (aItems[index] && aItems[index].documentId === sItemToDeleteId) {
					aItems.splice(index, 1);
				};
			});
			this.getView().byId("UploadCollection").getModel().setData({
				"items" : aItems
			});
			this.getView().byId("attachmentTitle").setText(this.getAttachmentTitleText());
		},

		deleteMultipleItems: function(aItemsToDelete){
			var oData = this.getView().byId("UploadCollection").getModel().getData();
			var nItemsToDelete = aItemsToDelete.length;
			var aItems = jQuery.extend(true, {}, oData).items;
			var i = 0;
			jQuery.each(aItems, function(index) {
				if (aItems[index]) {
					for (i = 0; i < nItemsToDelete; i++){
						if (aItems[index].documentId === aItemsToDelete[i].getDocumentId()){
							aItems.splice(index, 1);
						}
					}
				};
			});
			this.getView().byId("UploadCollection").getModel().setData({
				"items" : aItems
			});
			this.getView().byId("attachmentTitle").setText(this.getAttachmentTitleText());
		},

		onFilenameLengthExceed : function(oEvent) {
			MessageToast.show("FilenameLengthExceed event triggered.");
		},

		onFileRenamed: function(oEvent) {
			var oData = this.getView().byId("UploadCollection").getModel().getData();
			var aItems = jQuery.extend(true, {}, oData).items;
			var sDocumentId = oEvent.getParameter("documentId");
			jQuery.each(aItems, function(index) {
				if (aItems[index] && aItems[index].documentId === sDocumentId) {
					aItems[index].fileName = oEvent.getParameter("item").getFileName();
				};
			});
			this.getView().byId("UploadCollection").getModel().setData({
				"items" : aItems
			});
			MessageToast.show("FileRenamed event triggered.");
		},

		onFileSizeExceed : function(oEvent) {
			MessageToast.show("FileSizeExceed event triggered.");
		},

		onTypeMissmatch : function(oEvent) {
			MessageToast.show("TypeMissmatch event triggered.");
		},

		onUploadComplete: function(oEvent) {
			var oData = this.getView().byId("UploadCollection").getModel().getData();
			var aItems = jQuery.extend(true, {}, oData).items;
			var oItem = {};
			var sUploadedFile = oEvent.getParameter("files")[0].fileName;
			// at the moment parameter fileName is not set in IE9
			if (!sUploadedFile) {
				var aUploadedFile = (oEvent.getParameters().getSource().getProperty("value")).split(/\" "/);
				sUploadedFile = aUploadedFile[0];
			}
			oItem = {
					"documentId" : jQuery.now().toString(), // generate Id,
					"fileName" : sUploadedFile,
					"mimeType" : "",
					"thumbnailUrl" : "",
					"url" : "",
					"attributes":[
						{
							"title" : "Uploaded By",
							"text" : "You"
						},
						{
							"title" : "Uploaded On",
							"text" : new Date(jQuery.now()).toLocaleDateString()
						},
						{
							"title" : "File Size",
							"text" : "505000"
						}
					]
			};

			if (this.getView().byId("modeSwitch").getState()){
				oItem.visibleEdit = false;
				oItem.visibleDelete = false;
			}else{
				oItem.visibleEdit = true;
				oItem.visibleDelete = true;
			}
			aItems.unshift(oItem);
			this.getView().byId("UploadCollection").getModel().setData({
				"items" : aItems
			});
			// Sets the text to the label
			this.getView().byId("attachmentTitle").setText(this.getAttachmentTitleText());
			// delay the success message for to notice onChange message
			setTimeout(function() {
				MessageToast.show("UploadComplete event triggered.");
			}, 4000);
		},

		onSelectChange:  function(oEvent) {
			var oUploadCollection= this.getView().byId("UploadCollection");
			oUploadCollection.setShowSeparators(oEvent.getParameters().selectedItem.getProperty("key"));
		},

		onBeforeUploadStarts: function(oEvent) {
			// Header Slug
			var oCustomerHeaderSlug = new sap.m.UploadCollectionParameter({
				name : "slug",
				value : oEvent.getParameter("fileName")
			});
			oEvent.getParameters().addHeaderParameter(oCustomerHeaderSlug);
			MessageToast.show("BeforeUploadStarts event triggered.");
		},

		onUploadTerminated: function(oEvent) {
			// get parameter file name
			var sFileName = oEvent.getParameter("fileName");
			// get a header parameter (in case no parameter specified, the callback function getHeaderParameter returns all request headers)
			var oRequestHeaders = oEvent.getParameters().getHeaderParameter();
		},

		onSelectAllPress: function(oEvent) {
			var oUploadCollection = this.getView().byId("UploadCollection");

			if (!oEvent.getSource().getPressed()){
				this.deselectAllItems(oUploadCollection);
				oEvent.getSource().setPressed(false);
				oEvent.getSource().setText("Select all");
			} else {
				this.deselectAllItems(oUploadCollection);
				oUploadCollection.selectAll();
				oEvent.getSource().setPressed(true);
				oEvent.getSource().setText("Deselect all");
			}
		},

		deselectAllItems: function(oUploadCollection){
			var aItems = oUploadCollection.getItems();
			for (var i = 0; i < aItems.length; i++){
				oUploadCollection.setSelectedItem(aItems[i], false);
			}
		},

		getAttachmentTitleText: function(){
			var aItems = this.getView().byId("UploadCollection").getItems();
			return "Uploaded (" + aItems.length + ")";
		},

		onSwitchUploaderChange: function(oEvent){
			var oUploadCollection = this.getView().byId("UploadCollection");
			var bState = oEvent.getParameter("state");
			if (bState){
				oUploadCollection.setUploadEnabled(true);
			} else {
				oUploadCollection.setUploadEnabled(false);
			}
		},

		onSwitchModeChange: function(oEvent){
			// Sets to MultiSelect
			if (this.getView().byId("modeSwitch").getState()){
				this.setVisibleEditAndDelete(false);
				this.enableToolbarItems(true);
				this.getView().byId("UploadCollection").setMode("MultiSelect");
			}else{
				// Sets to SingleSelectMaster
				this.setVisibleEditAndDelete(true);
				this.enableToolbarItems(false);
				this.getView().byId("UploadCollection").setMode("SingleSelectMaster");
			}
		},

		setVisibleEditAndDelete: function(status){
			var aItems = this.getView().byId("UploadCollection").getItems();
			for (var i = 0; i < aItems.length; i++){
				aItems[i].setVisibleEdit(status);
				aItems[i].setVisibleDelete(status);
			}
		},

		enableToolbarItems: function(status){
			this.getView().byId("selectAllButton").setEnabled(status);
			this.getView().byId("deleteSelectedButton").setEnabled(status);
		},

		onDeleteSelectedItems: function(){
			var aSelectedItems = this.getView().byId("UploadCollection").getSelectedItems();
			this.deleteMultipleItems(aSelectedItems);
			if (this.getView().byId("UploadCollection").getSelectedItems().length < 1){
				this.getView().byId("selectAllButton").setPressed(false);
				this.getView().byId("selectAllButton").setText("Select all");
			}
			MessageToast.show("Delete selected items button press.");
		},

		onSearch: function(oEvent){
			MessageToast.show("Search feature isn't available in this sample");
		}
	});

	return PageController;

});<|endoftext|>


<commit_before>define([
	"dojo/_base/array",
	"dojo/_base/declare",
	"dojo/_base/lang",
	"dojo/dom-class",
	"dojo/dom-construct",
	"dojo/dom-style",
	"./iconUtils",
	"./_ItemBase",
	"./ProgressIndicator",
], function(array, declare, lang, domClass, domConstruct, domStyle, iconUtils, ItemBase, ProgressIndicator){

/*=====
	var ItemBase = dojox.mobile._ItemBase;
=====*/

	// module:
	//		dojox/mobile/ListItem
	// summary:
	//		An item of either RoundRectList or EdgeToEdgeList.

	return declare("dojox.mobile.ListItem", ItemBase, {
		// summary:
		//		An item of either RoundRectList or EdgeToEdgeList.
		// description:
		//		ListItem represents an item of either RoundRectList or
		//		EdgeToEdgeList. There are three ways to move to a different
		//		view, moveTo, href, and url. You can choose only one of them.

		// rightText: String
		//		A right-aligned text to display on the item.
		rightText: "",

		// rightIcon: String
		//		An icon to display at the right hand side of the item. The value
		//		can be either a path for an image file or a class name of a DOM
		//		button.
		rightIcon: "",

		// rightIcon2: String
		//		An icon to display at the left of the rightIcon. The value can
		//		be either a path for an image file or a class name of a DOM
		//		button.
		rightIcon2: "",

		// deleteIcon: String
		//		A delete icon to display at the left of the item. The value can
		//		be either a path for an image file or a class name of a DOM
		//		button.
		deleteIcon: "",

		// anchorLabel: Boolean
		//		If true, the label text becomes a clickable anchor text. When
		//		the user clicks on the text, the onAnchorLabelClicked handler is
		//		called. You can override or connect to the handler and implement
		//		any action. The handler has no default action.
		anchorLabel: false,

		// noArrow: Boolean
		//		If true, the right hand side arrow is not displayed.
		noArrow: false,

		// checked: Boolean
		//		If true, a check mark is displayed at the right of the item.
		checked: false,

		// arrowClass: String
		//		An icon to display as an arrow. The value can be either a path
		//		for an image file or a class name of a DOM button.
		arrowClass: "",

		// checkClass: String
		//		An icon to display as a check mark. The value can be either a
		//		path for an image file or a class name of a DOM button.
		checkClass: "",

		// uncheckClass: String
		//		An icon to display as an uncheck mark. The value can be either a
		//		path for an image file or a class name of a DOM button.
		uncheckClass: "",

		// variableHeight: Boolean
		//		If true, the height of the item varies according to its
		//		content. In dojo 1.6 or older, the "mblVariableHeight" class was
		//		used for this purpose. In dojo 1.7, adding the mblVariableHeight
		//		class still works for backward compatibility.
		variableHeight: false,

		// rightIconTitle: String
		//		An alt text for the right icon.
		rightIconTitle: "",

		// rightIcon2Title: String
		//		An alt text for the right icon2.
		rightIcon2Title: "",

		// header: Boolean
		//		If true, this item is rendered as a category header.
		header: false,

		// tag: String
		//		A name of html tag to create as domNode.
		tag: "li",

		// busy: Boolean
		//		If true, a progress indicator spins.
		busy: false,

		// progStyle: String
		//		A css class name to add to the progress indicator.
		progStyle: "",

		/* internal properties */
		paramsToInherit: "variableHeight,transition,deleteIcon,icon,rightIcon,rightIcon2,uncheckIcon,arrowClass,checkClass,uncheckClass",
		baseClass: "mblListItem",

		_selStartMethod: "touch",
		_selEndMethod: "timer",
		_delayedSelection: true,

		_selClass: "mblListItemSelected",

		buildRendering: function(){
			this.domNode = this.srcNodeRef || domConstruct.create(this.tag);
			this.inherited(arguments);

			if(this.selected){
				domClass.add(this.domNode, this._selClass);
			}
			if(this.header){
				domClass.replace(this.domNode, "mblEdgeToEdgeCategory", this.baseClass);
			}

			this.labelNode = this.containerNode =
				domConstruct.create("div", {className:"mblListItemTextBox"});
			var ref = this.srcNodeRef;
			if(ref){
				// reparent
				for(var i = 0, len = ref.childNodes.length; i < len; i++){
					this.labelNode.appendChild(ref.firstChild);
				}
			}
			this.domNode.appendChild(this.labelNode);

			if(this.anchorLabel){
				this.labelNode.style.display = "inline"; // to narrow the text region
				this.labelNode.style.cursor = "pointer";
			}
		},

		startup: function(){
			if(this._started){ return; }

			var parent = this.getParent();
			if(this.moveTo || this.href || this.url || this.clickable || (parent && parent.select)){
				this._keydownHandle = this.connect(this.domNode, "onkeydown", "_onClick"); // for desktop browsers
			}else{
				this._handleClick = false;
			}
			this.setArrow();

			if(domClass.contains(this.domNode, "mblVariableHeight")){
				this.variableHeight = true;
			}
			if(this.variableHeight){
				domClass.add(this.domNode, "mblVariableHeight");
				setTimeout(lang.hitch(this, "layoutVariableHeight"));
			}

			if(parent.select){
				this.set("checked", this.checked);
			}

			this.inherited(arguments);
			if(!this._isOnLine){
				this._isOnLine = true;
				this.set({ // retry applying the attribute
					icon: this.icon,
					deleteIcon: this.deleteIcon,
					rightIcon: this.rightIcon,
					rightIcon2: this.rightIcon2
				});
			}
		},

		resize: function(){
			if(this.variableHeight){
				this.layoutVariableHeight();
			}
		},

		_onClick: function(e){
			// summary:
			//		Internal handler for click events.
			// tags:
			//		private
			if(e && e.type === "keydown" && e.keyCode !== 13){ return; }
			if(this.onClick(e) === false){ return; } // user's click action
			if(this.anchorLabel){
				for(var p = e.target; p.tagName !== this.tag.toUpperCase(); p = p.parentNode){
					if(p.className == "mblListItemTextBox"){
						domClass.add(p, "mblListItemTextBoxSelected");
						setTimeout(function(){
							domClass.remove(p, "mblListItemTextBoxSelected");
						}, this._duration);
						this.onAnchorLabelClicked(e);
						return;
					}
				}
			}
			var parent = this.getParent();
			if(parent.select){
				if(parent.select === "single"){
					if(!this.checked){
						this.set("checked", true);
					}
				}else if(parent.select === "multiple"){
					this.set("checked", !this.checked);
				}
			}
			this.defaultClickAction(e);
		},

		onClick: function(/*Event*/ /*===== e =====*/){
			// summary:
			//		User defined function to handle clicks
			// tags:
			//		callback
		},

		onAnchorLabelClicked: function(e){
			// summary:
			//		Stub function to connect to from your application.
		},

		layoutVariableHeight: function(){
			var h = this.anchorNode.offsetHeight;
			if(h === this.anchorNodeHeight){ return; }
			this.anchorNodeHeight = h;
			array.forEach([
					this.rightTextNode,
					this.rightIcon2Node,
					this.rightIconNode,
					this.iconNode
				], function(n){
					if(n){
						var t = Math.round((h - n.offsetHeight) / 2);
						n.style.marginTop = t + "px";
					}
				});
		},

		setArrow: function(){
			// summary:
			//		Sets the arrow icon if necessary.
			if(this.checked){ return; }
			var c = "";
			var parent = this.getParent();
			if(this.moveTo || this.href || this.url || this.clickable){
				if(!this.noArrow && !(parent && parent.selectOne)){
					c = this.arrowClass || "mblDomButtonArrow";
				}
			}
			if(c){
				this._setRightIconAttr(c);
			}
		},

		_setIcon: function(/*String*/icon, /*String*/type, /*DomNode*/ref){
			if(!this.getParent()){ return; }
			this._set(type, icon);
			this[type + "Node"] = iconUtils.setIcon(icon, this[type + "Pos"],
				this[type + "Node"], this[type + "Title"] || this.alt, this.domNode, ref, "before");
			if(this[type + "Node"]){
				var cap = type.charAt(0).toUpperCase() + type.substring(1);
				domClass.add(this[type + "Node"], "mblListItem" + cap);
			}
		},

		_setDeleteIconAttr: function(/*String*/icon){
			this._setIcon(icon, "deleteIcon", this.iconNode || this.rightIconNode || this.rightIcon2Node || this.rightTextNode || this.labelNode);
		},

		_setIconAttr: function(icon){
			this._setIcon(icon, "icon", this.rightIconNode || this.rightIcon2Node || this.rightTextNode || this.labelNode);
		},

		_setRightTextAttr: function(/*String*/text){
			if(!this.rightTextNode){
				this.rightTextNode = domConstruct.create("div", {className:"mblListItemRightText"}, this.labelNode, "before");
			}
			this.rightText = text;
			this.rightTextNode.innerHTML = this._cv ? this._cv(text) : text;
		},

		_setRightIconAttr: function(/*String*/icon){
			this._setIcon(icon, "rightIcon", this.rightIcon2Node || this.rightTextNode || this.labelNode);
		},

		_setUncheckIconAttr: function(/*String*/icon){
			this._setIcon(icon, "uncheckIcon", this.rightIcon2Node || this.rightTextNode || this.labelNode);
		},

		_setRightIcon2Attr: function(/*String*/icon){
			this._setIcon(icon, "rightIcon2", this.rightTextNode || this.labelNode);
		},

		_setCheckedAttr: function(/*Boolean*/checked){
			var parent = this.getParent();
			if(parent && parent.select === "single" && checked){
				array.forEach(parent.getChildren(), function(child){
					child !== this && child.checked && child.set("checked", false);
				}, this);
			}
			this._setRightIconAttr(this.checkClass || "mblDomButtonCheck");
			this._setUncheckIconAttr(this.uncheckClass);

			domClass.toggle(this.domNode, "mblListItemChecked", checked);
			domClass.toggle(this.domNode, "mblListItemUnchecked", !checked);
			domClass.toggle(this.domNode, "mblListItemHasUncheck", !!this.uncheckIconNode);
			this.rightIconNode.style.position = (this.uncheckIconNode && !checked) ? "absolute" : "";

			if(parent && this.checked !== checked){
				parent.onCheckStateChanged(this, checked);
			}
			this._set("checked", checked);
		},

		_setBusyAttr: function(/*Boolean*/busy){
			var prog = this._prog;
			if(busy){
				if(!this.iconNode){
					this.iconNode = domConstruct.create("div", {className:"mblListItemIcon"},
						this.rightIconNode || this.rightIcon2Node || this.rightTextNode || this.labelNode, "before");
				}
				if(!prog){
					prog = this._prog = new ProgressIndicator({size:25, center:false});
					domClass.add(prog.domNode, this.progStyle);
				}
				array.forEach(this.iconNode.childNodes, function(child){
					child.style.display = "none";
				});
				this.iconNode.appendChild(prog.domNode);
				prog.start();
			}else{
				array.forEach(this.iconNode.childNodes, function(child){
					child.style.display = "";
				});
				prog.stop();
			}
			this._set("busy", busy);
		},

		_setSelectedAttr: function(/*Boolean*/selected){
			// summary:
			//		Makes this widget in the selected or unselected state.
			this.inherited(arguments);
			domClass.toggle(this.domNode, this._selClass, selected);
		}
	});
});
<commit_msg>Fixes #14152 !strict When necessary, re-calculate the position in the images's onload handler. This is performed only when images are not loaded in time.<commit_after>define([
	"dojo/_base/array",
	"dojo/_base/declare",
	"dojo/_base/lang",
	"dojo/dom-class",
	"dojo/dom-construct",
	"dojo/dom-style",
	"./iconUtils",
	"./_ItemBase",
	"./ProgressIndicator",
], function(array, declare, lang, domClass, domConstruct, domStyle, iconUtils, ItemBase, ProgressIndicator){

/*=====
	var ItemBase = dojox.mobile._ItemBase;
=====*/

	// module:
	//		dojox/mobile/ListItem
	// summary:
	//		An item of either RoundRectList or EdgeToEdgeList.

	return declare("dojox.mobile.ListItem", ItemBase, {
		// summary:
		//		An item of either RoundRectList or EdgeToEdgeList.
		// description:
		//		ListItem represents an item of either RoundRectList or
		//		EdgeToEdgeList. There are three ways to move to a different
		//		view, moveTo, href, and url. You can choose only one of them.

		// rightText: String
		//		A right-aligned text to display on the item.
		rightText: "",

		// rightIcon: String
		//		An icon to display at the right hand side of the item. The value
		//		can be either a path for an image file or a class name of a DOM
		//		button.
		rightIcon: "",

		// rightIcon2: String
		//		An icon to display at the left of the rightIcon. The value can
		//		be either a path for an image file or a class name of a DOM
		//		button.
		rightIcon2: "",

		// deleteIcon: String
		//		A delete icon to display at the left of the item. The value can
		//		be either a path for an image file or a class name of a DOM
		//		button.
		deleteIcon: "",

		// anchorLabel: Boolean
		//		If true, the label text becomes a clickable anchor text. When
		//		the user clicks on the text, the onAnchorLabelClicked handler is
		//		called. You can override or connect to the handler and implement
		//		any action. The handler has no default action.
		anchorLabel: false,

		// noArrow: Boolean
		//		If true, the right hand side arrow is not displayed.
		noArrow: false,

		// checked: Boolean
		//		If true, a check mark is displayed at the right of the item.
		checked: false,

		// arrowClass: String
		//		An icon to display as an arrow. The value can be either a path
		//		for an image file or a class name of a DOM button.
		arrowClass: "",

		// checkClass: String
		//		An icon to display as a check mark. The value can be either a
		//		path for an image file or a class name of a DOM button.
		checkClass: "",

		// uncheckClass: String
		//		An icon to display as an uncheck mark. The value can be either a
		//		path for an image file or a class name of a DOM button.
		uncheckClass: "",

		// variableHeight: Boolean
		//		If true, the height of the item varies according to its
		//		content. In dojo 1.6 or older, the "mblVariableHeight" class was
		//		used for this purpose. In dojo 1.7, adding the mblVariableHeight
		//		class still works for backward compatibility.
		variableHeight: false,

		// rightIconTitle: String
		//		An alt text for the right icon.
		rightIconTitle: "",

		// rightIcon2Title: String
		//		An alt text for the right icon2.
		rightIcon2Title: "",

		// header: Boolean
		//		If true, this item is rendered as a category header.
		header: false,

		// tag: String
		//		A name of html tag to create as domNode.
		tag: "li",

		// busy: Boolean
		//		If true, a progress indicator spins.
		busy: false,

		// progStyle: String
		//		A css class name to add to the progress indicator.
		progStyle: "",

		/* internal properties */
		paramsToInherit: "variableHeight,transition,deleteIcon,icon,rightIcon,rightIcon2,uncheckIcon,arrowClass,checkClass,uncheckClass",
		baseClass: "mblListItem",

		_selStartMethod: "touch",
		_selEndMethod: "timer",
		_delayedSelection: true,

		_selClass: "mblListItemSelected",

		buildRendering: function(){
			this.domNode = this.srcNodeRef || domConstruct.create(this.tag);
			this.inherited(arguments);

			if(this.selected){
				domClass.add(this.domNode, this._selClass);
			}
			if(this.header){
				domClass.replace(this.domNode, "mblEdgeToEdgeCategory", this.baseClass);
			}

			this.labelNode = this.containerNode =
				domConstruct.create("div", {className:"mblListItemTextBox"});
			var ref = this.srcNodeRef;
			if(ref){
				// reparent
				for(var i = 0, len = ref.childNodes.length; i < len; i++){
					this.labelNode.appendChild(ref.firstChild);
				}
			}
			this.domNode.appendChild(this.labelNode);

			if(this.anchorLabel){
				this.labelNode.style.display = "inline"; // to narrow the text region
				this.labelNode.style.cursor = "pointer";
			}
		},

		startup: function(){
			if(this._started){ return; }

			var parent = this.getParent();
			if(this.moveTo || this.href || this.url || this.clickable || (parent && parent.select)){
				this._keydownHandle = this.connect(this.domNode, "onkeydown", "_onClick"); // for desktop browsers
			}else{
				this._handleClick = false;
			}
			this.setArrow();

			if(domClass.contains(this.domNode, "mblVariableHeight")){
				this.variableHeight = true;
			}
			if(this.variableHeight){
				domClass.add(this.domNode, "mblVariableHeight");
				setTimeout(lang.hitch(this, "layoutVariableHeight"));
			}

			if(parent.select){
				this.set("checked", this.checked);
			}

			this.inherited(arguments);
			if(!this._isOnLine){
				this._isOnLine = true;
				this.set({ // retry applying the attribute
					icon: this.icon,
					deleteIcon: this.deleteIcon,
					rightIcon: this.rightIcon,
					rightIcon2: this.rightIcon2
				});
			}
		},

		resize: function(){
			if(this.variableHeight){
				this.layoutVariableHeight();
			}
		},

		_onClick: function(e){
			// summary:
			//		Internal handler for click events.
			// tags:
			//		private
			if(e && e.type === "keydown" && e.keyCode !== 13){ return; }
			if(this.onClick(e) === false){ return; } // user's click action
			if(this.anchorLabel){
				for(var p = e.target; p.tagName !== this.tag.toUpperCase(); p = p.parentNode){
					if(p.className == "mblListItemTextBox"){
						domClass.add(p, "mblListItemTextBoxSelected");
						setTimeout(function(){
							domClass.remove(p, "mblListItemTextBoxSelected");
						}, this._duration);
						this.onAnchorLabelClicked(e);
						return;
					}
				}
			}
			var parent = this.getParent();
			if(parent.select){
				if(parent.select === "single"){
					if(!this.checked){
						this.set("checked", true);
					}
				}else if(parent.select === "multiple"){
					this.set("checked", !this.checked);
				}
			}
			this.defaultClickAction(e);
		},

		onClick: function(/*Event*/ /*===== e =====*/){
			// summary:
			//		User defined function to handle clicks
			// tags:
			//		callback
		},

		onAnchorLabelClicked: function(e){
			// summary:
			//		Stub function to connect to from your application.
		},

		layoutVariableHeight: function(){
			var h = this.domNode.offsetHeight;
			if(h === this.domNodeHeight){ return; }
			this.domNodeHeight = h;
			array.forEach([
				this.rightTextNode,
				this.rightIcon2Node,
				this.rightIconNode,
				this.uncheckIconNode,
				this.iconNode,
				this.deleteIconNode,
				this.knobIconNode
			], function(n){
				if(n){
					var domNode = this.domNode;
					var f = function(){
						var t = Math.round((domNode.offsetHeight - n.offsetHeight) / 2) -
							domStyle.get(domNode, "paddingTop");
						n.style.marginTop = t + "px";
					}
					if(n.offsetHeight === 0 && n.tagName === "IMG"){
						n.onload = f;
					}else{
						f();
					}
				}
			}, this);
		},

		setArrow: function(){
			// summary:
			//		Sets the arrow icon if necessary.
			if(this.checked){ return; }
			var c = "";
			var parent = this.getParent();
			if(this.moveTo || this.href || this.url || this.clickable){
				if(!this.noArrow && !(parent && parent.selectOne)){
					c = this.arrowClass || "mblDomButtonArrow";
				}
			}
			if(c){
				this._setRightIconAttr(c);
			}
		},

		_setIcon: function(/*String*/icon, /*String*/type, /*DomNode*/ref){
			if(!this.getParent()){ return; }
			this._set(type, icon);
			this[type + "Node"] = iconUtils.setIcon(icon, this[type + "Pos"],
				this[type + "Node"], this[type + "Title"] || this.alt, this.domNode, ref, "before");
			if(this[type + "Node"]){
				var cap = type.charAt(0).toUpperCase() + type.substring(1);
				domClass.add(this[type + "Node"], "mblListItem" + cap);
			}
		},

		_setDeleteIconAttr: function(/*String*/icon){
			this._setIcon(icon, "deleteIcon", this.iconNode || this.rightIconNode || this.rightIcon2Node || this.rightTextNode || this.labelNode);
		},

		_setIconAttr: function(icon){
			this._setIcon(icon, "icon", this.rightIconNode || this.rightIcon2Node || this.rightTextNode || this.labelNode);
		},

		_setRightTextAttr: function(/*String*/text){
			if(!this.rightTextNode){
				this.rightTextNode = domConstruct.create("div", {className:"mblListItemRightText"}, this.labelNode, "before");
			}
			this.rightText = text;
			this.rightTextNode.innerHTML = this._cv ? this._cv(text) : text;
		},

		_setRightIconAttr: function(/*String*/icon){
			this._setIcon(icon, "rightIcon", this.rightIcon2Node || this.rightTextNode || this.labelNode);
		},

		_setUncheckIconAttr: function(/*String*/icon){
			this._setIcon(icon, "uncheckIcon", this.rightIcon2Node || this.rightTextNode || this.labelNode);
		},

		_setRightIcon2Attr: function(/*String*/icon){
			this._setIcon(icon, "rightIcon2", this.rightTextNode || this.labelNode);
		},

		_setCheckedAttr: function(/*Boolean*/checked){
			var parent = this.getParent();
			if(parent && parent.select === "single" && checked){
				array.forEach(parent.getChildren(), function(child){
					child !== this && child.checked && child.set("checked", false);
				}, this);
			}
			this._setRightIconAttr(this.checkClass || "mblDomButtonCheck");
			this._setUncheckIconAttr(this.uncheckClass);

			domClass.toggle(this.domNode, "mblListItemChecked", checked);
			domClass.toggle(this.domNode, "mblListItemUnchecked", !checked);
			domClass.toggle(this.domNode, "mblListItemHasUncheck", !!this.uncheckIconNode);
			this.rightIconNode.style.position = (this.uncheckIconNode && !checked) ? "absolute" : "";

			if(parent && this.checked !== checked){
				parent.onCheckStateChanged(this, checked);
			}
			this._set("checked", checked);
		},

		_setBusyAttr: function(/*Boolean*/busy){
			var prog = this._prog;
			if(busy){
				if(!this.iconNode){
					this.iconNode = domConstruct.create("div", {className:"mblListItemIcon"},
						this.rightIconNode || this.rightIcon2Node || this.rightTextNode || this.labelNode, "before");
				}
				if(!prog){
					prog = this._prog = new ProgressIndicator({size:25, center:false});
					domClass.add(prog.domNode, this.progStyle);
				}
				array.forEach(this.iconNode.childNodes, function(child){
					child.style.display = "none";
				});
				this.iconNode.appendChild(prog.domNode);
				prog.start();
			}else{
				array.forEach(this.iconNode.childNodes, function(child){
					child.style.display = "";
				});
				prog.stop();
			}
			this._set("busy", busy);
		},

		_setSelectedAttr: function(/*Boolean*/selected){
			// summary:
			//		Makes this widget in the selected or unselected state.
			this.inherited(arguments);
			domClass.toggle(this.domNode, this._selClass, selected);
		}
	});
});
<|endoftext|>


<commit_before>var sentiment = require('sentiment');
var Twit = require('twit');
var Pubnub = require('pubnub');
var fs = require('fs');
var nconf = require('nconf');

nconf.file({ file: 'config.json' }).env();

TweetPublisher = { };

var twitter = TweetPublisher.twitter = new Twit({
	consumer_key: nconf.get('TWITTER_CONSUMER_KEY'),
	consumer_secret: nconf.get('TWITTER_CONSUMER_SECRET'),
	access_token: nconf.get('TWITTER_ACCESS_TOKEN'),
	access_token_secret: nconf.get('TWITTER_TOKEN_SECRET')
});

var pubnub = TweetPublisher.pubnub = Pubnub({
	publish_key: nconf.get('PUBNUB_PUBLISH_KEY'),
	subscribe_key: nconf.get('PUBNUB_SUBSCRIBE_KEY')
});

var stream, cachedTweet, publishInterval;

/**
 * Starts Twitter stream and publish interval
 */
TweetPublisher.start = function () {

	var response = { };

	// If the stream does not exist create it
	if (!stream) {

		// Connect to stream and filter by a geofence that is the size of the Earth
		stream = twitter.stream('statuses/filter', { locations: '-180,-90,180,90' });

		// When Tweet is received only process it if it has geo data
		stream.on('tweet', function (tweet) {
			// calculate sentiment with "sentiment" module
			tweet.sentiment = sentiment(tweet.text);

			// save the Tweet so that the very latest Tweet is available and can be published
			cachedTweet = tweet
		});

		response.message = 'Stream created and started.'
	}
	// If the stream exists start it
	else {
		stream.start();
		response.message = 'Stream already exists and started.'
	}

	// Clear publish interval just be sure they don't stack up (probably not necessary)
	if (publishInterval) {
		clearInterval(publishInterval);
	}

	// Only publish a Tweet every 100 millseconds so that the browser view is not overloaded
	// This will provide a predictable and consistent flow of real-time Tweets
	publishInterval = setInterval(function () {
		if (cachedTweet) {
			publishTweet(cachedTweet);
		}
	}, 100); // Adjust the interval to increase or decrease the rate at which Tweets sent to the clients

	return response;
}

/**
 * Stops the stream and publish interval
 **/
TweetPublisher.stop = function () {

	var response = { };

	if (stream) {
		stream.stop();
		clearInterval(publishInterval);
		response.message = 'Stream stopped.'
	}
	else {
		response.message = 'Stream does not exist.'
	}

	return response;
}

var lastPublishedTweetId;

/**
 * Publishes Tweet object through PubNub to all clients
 **/
function publishTweet (tweet) {

	if (tweet.id == lastPublishedTweetId) {
		return;
	}

	lastPublishedTweetId = tweet.id;

	pubnub.publish({
		post: false,
		channel: 'tweet_stream',
		message: tweet,
		callback: function (details) {
			// success
		}
	});
}

module.exports = TweetPublisher;<commit_msg>My Keys index.js<commit_after>var sentiment = require('sentiment');
var Twit = require('twit');
var Pubnub = require('pubnub');
var fs = require('fs');
var nconf = require('nconf');

nconf.file({ file: 'config.json' }).env();

TweetPublisher = { };

var twitter = TweetPublisher.twitter = new Twit({
	consumer_key: nconf.get('8hBtQHHYCG32jvNDTc9VZpCVj'),
	consumer_secret: nconf.get('8tE3W54IexnVFP8CqJi2M119sjy1z7ceMqhCvwOcYJeTIPe3tl'),
	access_token: nconf.get('318514505-6q105MKOSQFxoWWRV8JyzLWQBehq0Wq4y8HQLXG4'),
	access_token_secret: nconf.get('WOiyS4VoPRW7lb1R7iHk8Z3uE9Zciy3SjE2YA0PeZ4scC')
});

var pubnub = TweetPublisher.pubnub = Pubnub({
	publish_key: nconf.get('pub-c-446f3359-f8f8-46c9-8fbc-c67e1e6d43e9'),
	subscribe_key: nconf.get('sub-c-0c949b90-f546-11e6-bb94-0619f8945a4f')
});

var stream, cachedTweet, publishInterval;

/**
 * Starts Twitter stream and publish interval
 */
TweetPublisher.start = function () {

	var response = { };

	// If the stream does not exist create it
	if (!stream) {

		// Connect to stream and filter by a geofence that is the size of the Earth
		stream = twitter.stream('statuses/filter', { locations: '-180,-90,180,90' });

		// When Tweet is received only process it if it has geo data
		stream.on('tweet', function (tweet) {
			// calculate sentiment with "sentiment" module
			tweet.sentiment = sentiment(tweet.text);

			// save the Tweet so that the very latest Tweet is available and can be published
			cachedTweet = tweet
		});

		response.message = 'Stream created and started.'
	}
	// If the stream exists start it
	else {
		stream.start();
		response.message = 'Stream already exists and started.'
	}

	// Clear publish interval just be sure they don't stack up (probably not necessary)
	if (publishInterval) {
		clearInterval(publishInterval);
	}

	// Only publish a Tweet every 100 millseconds so that the browser view is not overloaded
	// This will provide a predictable and consistent flow of real-time Tweets
	publishInterval = setInterval(function () {
		if (cachedTweet) {
			publishTweet(cachedTweet);
		}
	}, 100); // Adjust the interval to increase or decrease the rate at which Tweets sent to the clients

	return response;
}

/**
 * Stops the stream and publish interval
 **/
TweetPublisher.stop = function () {

	var response = { };

	if (stream) {
		stream.stop();
		clearInterval(publishInterval);
		response.message = 'Stream stopped.'
	}
	else {
		response.message = 'Stream does not exist.'
	}

	return response;
}

var lastPublishedTweetId;

/**
 * Publishes Tweet object through PubNub to all clients
 **/
function publishTweet (tweet) {

	if (tweet.id == lastPublishedTweetId) {
		return;
	}

	lastPublishedTweetId = tweet.id;

	pubnub.publish({
		post: false,
		channel: 'tweet_stream',
		message: tweet,
		callback: function (details) {
			// success
		}
	});
}

module.exports = TweetPublisher;
<|endoftext|>


<commit_before>(function ($) {

    var toggleStyle = function (elementSelector, nightCss, dayCss) {
        var styleElement = $(elementSelector)[0];
        var current = styleElement.href;

        if (current.indexOf(nightCss) >= 0) {
            current = current.replace(nightCss, dayCss);
        } else if (current.indexOf(dayCss) >= 0) {
            current = current.replace(dayCss, nightCss);
        }

        styleElement.href = current;
        saveTheme(elementSelector, current);
    }

    var toggleBootswatch = function () {
        toggleStyle(
            "link#bootswatch-style",
            "content/bootswatch-darkly.min.css",
            "content-bootswatch-flatly.min.css"
        );
    }

    var togglePrism = function () {
        toggleStyle(
            "link#prism-style",
            "content/prism.night.css",
            "content/prism.default.css"
        );
    }

    var toggleTheme = function() {
        toggleBootswatch();
        togglePrism();
    }

    var saveTheme = function (elementSelector, value) {
        if (window.localStorage && window.localStorage.setItem) {
            window.localStorage.setItem(elementSelector, value);
        }
    }

    var getSavedTheme = function (elementSelector) {
        if (window.localStorage && window.localStorage[elementSelector]) {
            return window.localStorage[elementSelector];
        }

        return null;
    }

    var getCurrentTheme = function (elementSelector) {
        var styleElement = $(elementSelector)[0];
        return styleElement.href;
    }

    var bootswatchSelector = "link#bootswatch-style";
    var savedTheme = getSavedTheme(bootswatchSelector);

    if (savedTheme && savedTheme !== getCurrentTheme(bootswatchSelector)) {
        toggleTheme();
    }

    $("a#theme-toggle").click(function (click) {
        toggleTheme();
        click.preventDefault();
        return false;
    });

    $(".post-content img").addClass("img-fluid");

})(window.jQuery);<commit_msg>theme selector<commit_after>(function ($) {

    var toggleStyle = function (elementSelector, nightCss, dayCss) {
        var styleElement = $(elementSelector)[0];
        var current = styleElement.href;

        if (current.indexOf(nightCss) >= 0) {
            current = current.replace(nightCss, dayCss);
        } else if (current.indexOf(dayCss) >= 0) {
            current = current.replace(dayCss, nightCss);
        }

        styleElement.href = current;
        saveTheme(elementSelector, current);
    }

    var toggleBootswatch = function () {
        toggleStyle(
            "link#bootswatch-style",
            "content/bootswatch-darkly.min.css",
            "content/bootswatch-flatly.min.css"
        );
    }

    var togglePrism = function () {
        toggleStyle(
            "link#prism-style",
            "content/prism.night.css",
            "content/prism.default.css"
        );
    }

    var toggleTheme = function() {
        toggleBootswatch();
        togglePrism();
    }

    var saveTheme = function (elementSelector, value) {
        if (window.localStorage && window.localStorage.setItem) {
            window.localStorage.setItem(elementSelector, value);
        }
    }

    var getSavedTheme = function (elementSelector) {
        if (window.localStorage && window.localStorage[elementSelector]) {
            return window.localStorage[elementSelector];
        }

        return null;
    }

    var getCurrentTheme = function (elementSelector) {
        var styleElement = $(elementSelector)[0];
        return styleElement.href;
    }

    var bootswatchSelector = "link#bootswatch-style";
    var savedTheme = getSavedTheme(bootswatchSelector);

    if (savedTheme && savedTheme !== getCurrentTheme(bootswatchSelector)) {
        toggleTheme();
    }

    $("a#theme-toggle").click(function (click) {
        toggleTheme();
        click.preventDefault();
        return false;
    });

    $(".post-content img").addClass("img-fluid");

})(window.jQuery);<|endoftext|>