<commit_before>define([
    'require',
    '../lib/jquery.form/jquery.form',
    '../logging',
    '../patterns'
], function(require) {
    var log = require('../logging').getLogger('modal');

    var init = function($el, opts) {
        var $first = $el.children(':first'),
            $rest = $el.children(':not(:first)'),
            $header = $('
'),
            $body = $('
'),
            $form = $el.find('form'),
            $closebutton = $(
                '<button type="button" class="close-panel">Close</button>');

        // separate into header and body
        if ($rest.length === 0) {
            $first.wrap($body);
            $el.prepend($header);
        } else {
            $first.wrap($header);
            $rest.wrapAll($body);
        }

        // add close-panel button to header
        $('.header', $el).append($closebutton);

        // event handler to remove element
        var remove = function(ev) {
            if (ev) {
                ev.preventDefault();
            }

            // the modal will be gone, but unhooked from document
            $(document).off('.modal');
            $el.remove();
        };

        // remove on ESC
        $(document).on('keyup.remove.modal', function(ev) {
            if (ev.which == 27) remove(ev);
        });
        // remove on close-panel button click
        $el.find('.close-panel').on('click.remove.modal', remove);

        // close dialog if form is submitted
        // TODO: one might want to display errors on modal dialog
        // instead of closing it, provide that option somehow
        $form.submit(function (e) {
            remove();
        });

        // ensure element is ajaxified
        //var ajaxify = require('../patterns').ajaxify.init;
        //ajaxify($el.find('form'));

        // close forms that are successfully submitted or show error
        // if ($form) {
        //     // prepare ajax request and submit function
        //     var params = {
        //         data: { submit: "submit" },
        //         error: function(jqXHR, textStatus, errorThrown) {
        //             var msg = [jqXHR.status, textStatus,
        //                        $form.attr('action')].join(' '),
        //                 $errdiv = $el.find('.message.error');
        //             if ($errdiv.length === 0) {
        //                 $errdiv = $('
');
        //                 $errdiv.prependTo($el.find('.body'));
        //             }
        //             $el.removeClass('ajax-in-progress');
        //             $errdiv.html(msg);
        //             console.error(jqXHR, textStatus, errorThrown);
        //         },
        //         success: function(data, textStatus, jqXHR) {
        //             $el.remove();
        //         }
        //     };
        //     var submit = function(ev) {
        //         $el.addClass('ajax-in-progress');
        //         ev.preventDefault();
        //         $form.ajaxSubmit(params);
        //     };
        //     $form.find('[type=submit]').on('click', submit);
        //     $(document).on('keyup.submit.modal', function(ev) {
        //         if (ev.which == 13) submit(ev);
        //     });
        // }

        return $el;
    };

    var pattern = {
        markup_trigger: "div.modal",
        initialised_class: "modal",
        default_opts: {
            shown: false
        },
        init: init
    };

    return pattern;
});
<commit_msg>don't remove but only hide a modal<commit_after>define([
    'require',
    '../lib/jquery.form/jquery.form',
    '../logging',
    '../patterns'
], function(require) {
    var log = require('../logging').getLogger('modal');

    var init = function($el, opts) {
        var $first = $el.children(':first'),
            $rest = $el.children(':not(:first)'),
            $header = $('
'),
            $body = $('
'),
            $form = $el.find('form'),
            $closebutton = $(
                '<button type="button" class="close-panel">Close</button>');

        // separate into header and body
        if ($rest.length === 0) {
            $first.wrap($body);
            $el.prepend($header);
        } else {
            $first.wrap($header);
            $rest.wrapAll($body);
        }

        // add close-panel button to header
        $('.header', $el).append($closebutton);

        // event handler to remove element
        var remove = function(ev) {
            if (ev) {
                ev.preventDefault();
            }

            // the modal will be gone, but unhooked from document
            $(document).off('.modal');
            $el.hide();
        };

        // remove on ESC
        $(document).on('keyup.remove.modal', function(ev) {
            if (ev.which == 27) remove(ev);
        });
        // remove on close-panel button click
        $el.find('.close-panel').on('click.remove.modal', remove);

        // close dialog if form is submitted
        // TODO: one might want to display errors on modal dialog
        // instead of closing it, provide that option somehow
        $form.submit(function (e) {
            remove();
        });

        // ensure element is ajaxified
        //var ajaxify = require('../patterns').ajaxify.init;
        //ajaxify($el.find('form'));

        // close forms that are successfully submitted or show error
        // if ($form) {
        //     // prepare ajax request and submit function
        //     var params = {
        //         data: { submit: "submit" },
        //         error: function(jqXHR, textStatus, errorThrown) {
        //             var msg = [jqXHR.status, textStatus,
        //                        $form.attr('action')].join(' '),
        //                 $errdiv = $el.find('.message.error');
        //             if ($errdiv.length === 0) {
        //                 $errdiv = $('
');
        //                 $errdiv.prependTo($el.find('.body'));
        //             }
        //             $el.removeClass('ajax-in-progress');
        //             $errdiv.html(msg);
        //             console.error(jqXHR, textStatus, errorThrown);
        //         },
        //         success: function(data, textStatus, jqXHR) {
        //             $el.remove();
        //         }
        //     };
        //     var submit = function(ev) {
        //         $el.addClass('ajax-in-progress');
        //         ev.preventDefault();
        //         $form.ajaxSubmit(params);
        //     };
        //     $form.find('[type=submit]').on('click', submit);
        //     $(document).on('keyup.submit.modal', function(ev) {
        //         if (ev.which == 13) submit(ev);
        //     });
        // }

        return $el;
    };

    var pattern = {
        markup_trigger: "div.modal",
        initialised_class: "modal",
        default_opts: {
            shown: false
        },
        init: init
    };

    return pattern;
});
<|endoftext|>


<commit_before>/**
 * @author Mat Groves http://matgroves.com/ @Doormat23
 */

/**
 * A MovieClip is a simple way to display an animation depicted by a list of textures.
 * @class MovieClip
 * @extends Sprite
 * @constructor
 * @param textures {Array} an array of {Texture} objects that make up the animation
 */
PIXI.MovieClip = function(textures)
{
	PIXI.Sprite.call( this, textures[0]);

	/**
	 * The array of textures that make up the animation
	 * @property textures
	 * @type Array
	 */
	this.textures = textures;

	/**
	 * [read only] The index MovieClips current frame (this may not have to be a whole number)
	 * @property currentFrame
	 * @type Number
	 */
	this.currentFrame = 0;

	/**
	 * The speed that the MovieClip will play at. Higher is faster, lower is slower
	 * @property animationSpeed
	 * @type Number
	 */
	this.animationSpeed = 1;

    /**
     * Whether or not the movie clip repeats after playing.
     * @property loop
     * @type Boolean
     */
    this.loop = true;

    /**
     * Function to call when a MovieClip finishes playing
     * @property onComplete
     * @type Function
     */
    this.onComplete = null;

	/**
	 * [read only] indicates if the MovieClip is currently playing
	 * @property playing
	 * @type Boolean
	 */
	this.playing;
}

// constructor
PIXI.MovieClip.constructor = PIXI.MovieClip;
PIXI.MovieClip.prototype = Object.create( PIXI.Sprite.prototype );

/**
 * Stops the MovieClip
 * @method stop
 */
PIXI.MovieClip.prototype.stop = function()
{
	this.playing = false;
}

/**
 * Plays the MovieClip
 * @method play
 */
PIXI.MovieClip.prototype.play = function()
{
	this.playing = true;
}

/**
 * Stops the MovieClip and goes to a specific frame
 * @method gotoAndStop
 * @param frameNumber {Number} frame index to stop at
 */
PIXI.MovieClip.prototype.gotoAndStop = function(frameNumber)
{
	this.playing = false;
	this.currentFrame = frameNumber;
	var round = (this.currentFrame + 0.5) | 0;
	this.setTexture(this.textures[round % this.textures.length]);
}

/**
 * Goes to a specific frame and begins playing the MovieClip
 * @method gotoAndPlay
 * @param frameNumber {Number} frame index to start at
 */
PIXI.MovieClip.prototype.gotoAndPlay = function(frameNumber)
{
	this.currentFrame = frameNumber;
	this.playing = true;
}

PIXI.MovieClip.prototype.updateTransform = function()
{
	PIXI.Sprite.prototype.updateTransform.call(this);

	if(!this.playing)return;

	this.currentFrame += this.animationSpeed;
	var round = (this.currentFrame + 0.5) | 0;
    if(this.loop){
        this.setTexture(this.textures[round % this.textures.length]);
    }else{
        if (round>=this.textures.length){
            this.currentFrame=this.textures.length-1;
            this.setTexture(this.textures[this.textures.length-1]);
            this.stop();
            this.dispatchEvent( { type: 'onComplete', content: this } );
            if(this.onComplete)this.onComplete();
        }else{
            this.setTexture(this.textures[round % this.textures.length]);
        }
    }

}<commit_msg>event dispatch line was incorrect.<commit_after>/**
 * @author Mat Groves http://matgroves.com/ @Doormat23
 */

/**
 * A MovieClip is a simple way to display an animation depicted by a list of textures.
 * @class MovieClip
 * @extends Sprite
 * @constructor
 * @param textures {Array} an array of {Texture} objects that make up the animation
 */
PIXI.MovieClip = function(textures)
{
	PIXI.Sprite.call( this, textures[0]);

	/**
	 * The array of textures that make up the animation
	 * @property textures
	 * @type Array
	 */
	this.textures = textures;

	/**
	 * [read only] The index MovieClips current frame (this may not have to be a whole number)
	 * @property currentFrame
	 * @type Number
	 */
	this.currentFrame = 0;

	/**
	 * The speed that the MovieClip will play at. Higher is faster, lower is slower
	 * @property animationSpeed
	 * @type Number
	 */
	this.animationSpeed = 1;

    /**
     * Whether or not the movie clip repeats after playing.
     * @property loop
     * @type Boolean
     */
    this.loop = true;

    /**
     * Function to call when a MovieClip finishes playing
     * @property onComplete
     * @type Function
     */
    this.onComplete = null;

	/**
	 * [read only] indicates if the MovieClip is currently playing
	 * @property playing
	 * @type Boolean
	 */
	this.playing;
}

// constructor
PIXI.MovieClip.constructor = PIXI.MovieClip;
PIXI.MovieClip.prototype = Object.create( PIXI.Sprite.prototype );

/**
 * Stops the MovieClip
 * @method stop
 */
PIXI.MovieClip.prototype.stop = function()
{
	this.playing = false;
}

/**
 * Plays the MovieClip
 * @method play
 */
PIXI.MovieClip.prototype.play = function()
{
	this.playing = true;
}

/**
 * Stops the MovieClip and goes to a specific frame
 * @method gotoAndStop
 * @param frameNumber {Number} frame index to stop at
 */
PIXI.MovieClip.prototype.gotoAndStop = function(frameNumber)
{
	this.playing = false;
	this.currentFrame = frameNumber;
	var round = (this.currentFrame + 0.5) | 0;
	this.setTexture(this.textures[round % this.textures.length]);
}

/**
 * Goes to a specific frame and begins playing the MovieClip
 * @method gotoAndPlay
 * @param frameNumber {Number} frame index to start at
 */
PIXI.MovieClip.prototype.gotoAndPlay = function(frameNumber)
{
	this.currentFrame = frameNumber;
	this.playing = true;
}

PIXI.MovieClip.prototype.updateTransform = function()
{
	PIXI.Sprite.prototype.updateTransform.call(this);

	if(!this.playing)return;

	this.currentFrame += this.animationSpeed;
	var round = (this.currentFrame + 0.5) | 0;
    if(this.loop){
        this.setTexture(this.textures[round % this.textures.length]);
    }else{
        if (round>=this.textures.length){
            this.currentFrame=this.textures.length-1;
            this.setTexture(this.textures[this.textures.length-1]);
            this.stop();
            if(this.onComplete)this.onComplete();
        }else{
            this.setTexture(this.textures[round % this.textures.length]);
        }
    }

}<|endoftext|>


<commit_before>import foo from 'pkg1/mod1'
export const bar = 'bar'
export const foo_imp = foo
<commit_msg>Oh, so that was the correct syntax for importing<commit_after>import {foo} from 'pkg1/mod1'
export const bar = 'bar'
export const foo_imp = foo
<|endoftext|>


<commit_before>const { NVIM_SYNC, NVIM_SPEC, NVIM_METHOD_NAME } = require('./properties');

// Example
// @autocmd('BufEnter', { pattern: '*.js', eval: 'expand("<afile>")', sync: true })
module.exports = function(name, options = {}) {
  return function(cls, methodName) {
    // const {
    // sync,
    // ...opts,
    // } = options;

    const sync = options.sync;
    const f = cls[methodName];
    const opts = {};

    ['pattern', 'eval'].forEach(option => {
      if (typeof options[option] !== 'undefined') {
        opts[option] = options[option];
      }
    });

    Object.defineProperty(f, NVIM_METHOD_NAME, { value: `autocmd:${name}` });
    Object.defineProperty(f, NVIM_SYNC, { value: !!sync });
    Object.defineProperty(f, NVIM_SPEC, {
      value: {
        type: 'autocmd',
        name,
        sync: !!sync,
        opts,
      },
    });
    // eslint-disable-next-line no-param-reassign
    cls[methodName] = f;
    return cls;
  };
};
<commit_msg>Fix autocmd decorator, add pattern to method name<commit_after>const { NVIM_SYNC, NVIM_SPEC, NVIM_METHOD_NAME } = require('./properties');

// Example
// @autocmd('BufEnter', { pattern: '*.js', eval: 'expand("<afile>")', sync: true })
module.exports = function(name, options = {}) {
  return function(cls, methodName) {
    // const {
    // sync,
    // ...opts,
    // } = options;

    const sync = options.sync;
    const f = cls[methodName];
    const opts = {};

    ['pattern', 'eval'].forEach(option => {
      if (typeof options[option] !== 'undefined') {
        opts[option] = options[option];
      }
    });

    const nameWithPattern = `${name}${options.pattern ? `:${options.pattern}` : ''}`;
    Object.defineProperty(f, NVIM_METHOD_NAME, { value: `autocmd:${nameWithPattern}` });
    Object.defineProperty(f, NVIM_SYNC, { value: !!sync });
    Object.defineProperty(f, NVIM_SPEC, {
      value: {
        type: 'autocmd',
        name,
        sync: !!sync,
        opts,
      },
    });
    // eslint-disable-next-line no-param-reassign
    cls[methodName] = f;
    return cls;
  };
};
<|endoftext|>


<commit_before>
// sfw_calendar.js

(function _init()
{
   if ((!("SFW" in window) && setTimeout(_init,100))
       || SFW.delay_init("sfw_calendar",_init, "table"))
      return;

   if (!SFW.derive(_calendar, "calendar", "table"))
      return;

   function _calendar(base, doc, caller, data)
   {
      SFW.types["table"].call(this,base,doc,caller,data);
   }

   _calendar.prototype.process_cell_click = function(td)
   {
      var rval = null;
      var task = this.get_data_value("on_cell_click");
      if (task)
      {
         rval = {
            task:task,
            id_name:this.get_cell_click_id_name(),
            did:td.getAttribute("data-date")
         };

         function f(n) { return n.nodeType==1 && class_includes(n,"day_content"); }
         var container = SFW.find_child_matches(td,f,true);
         if (container && container.getAttribute("data-id"))
            rval.target = container;
      }

      return rval;
   };

   _calendar.prototype.process_day_click = function(t, did)
   {
      var url = this.get_data_value("on_day_click");
      if (url)
      {
         url += "=" + did;
         empty_el(this.host());
         SFW.open_interaction(SFW.stage, url, this, {caldoc:this.xmldoc(),did:did});
      }
   };

   _calendar.prototype.process_month_jump = function(month)
   {
      var url = SFW.update_location_arg("mdate", month);
      if (url)
         window.location = url;

      return false;
   };

   _calendar.prototype.get_calmove_url = function(button)
   {
      var base = this.top().getAttribute("data-url-calmove_base");
      var jump = button.getAttribute("data-jump");
      if (!base)
         SFW.alert("Missing calmove_base");
      else if (!jump)
         SFW.alert("Missing data-jump value");
      else
         return base + "=" + jump;

      return null;
   };

   _calendar.prototype.process_button_calmove = function(button, callback)
   {
      var url = get_calmove_url(button);
      if (url)
         window.location = url;
   };

   _calendar.prototype.process = function (e,t)
   {
      var did, tag, mon, top = this.top();

      if (e.type!="click")
         return true;

      if (!SFW.types["table"].prototype.process.call(this,e,t))
         return false;

      // Don't disturb the arguments array:
      var tel = t;
      while (tel && tel!=top)
      {
         if (tel.nodeType==1 && (tag=tel.tagName.toLowerCase()))
         {
            if (tag=="td" && (did=tel.getAttribute("data-date")))
               return this.process_day_click(tel, did);
            if (tag=="button" && (mon=tel.getAttribute("data-jump")))
               return this.process_month_jump(mon);
         }

         tel = tel.parentNode;
      }

      return this.call_super_event("table", "process", arguments);
   };

})();
<commit_msg>Changed get_day_click to get_el_click to match the click target element xxx on the new on_xxx_click protocol.<commit_after>
// sfw_calendar.js

(function _init()
{
   if ((!("SFW" in window) && setTimeout(_init,100))
       || SFW.delay_init("sfw_calendar",_init, "table"))
      return;

   if (!SFW.derive(_calendar, "calendar", "table"))
      return;

   function _calendar(base, doc, caller, data)
   {
      SFW.types["table"].call(this,base,doc,caller,data);
   }

   _calendar.prototype.process_cell_click = function(td)
   {
      var rval = null;
      var task = this.get_data_value("on_cell_click");
      if (task)
      {
         rval = {
            task:task,
            id_name:this.get_cell_click_id_name(),
            did:td.getAttribute("data-date")
         };

         function f(n) { return n.nodeType==1 && class_includes(n,"day_content"); }
         var container = SFW.find_child_matches(td,f,true);
         if (container && container.getAttribute("data-id"))
            rval.target = container;
      }

      return rval;
   };

   _calendar.prototype.process_day_click = function(t, did)
   {
      var url = this.get_data_value("on_day_click");
      if (url)
      {
         url += "=" + did;
         empty_el(this.host());
         SFW.open_interaction(SFW.stage, url, this, {caldoc:this.xmldoc(),did:did});
      }
   };

   _calendar.prototype.process_month_jump = function(month)
   {
      var url = SFW.update_location_arg("mdate", month);
      if (url)
         window.location = url;

      return false;
   };

   _calendar.prototype.get_calmove_url = function(button)
   {
      var base = this.top().getAttribute("data-url-calmove_base");
      var jump = button.getAttribute("data-jump");
      if (!base)
         SFW.alert("Missing calmove_base");
      else if (!jump)
         SFW.alert("Missing data-jump value");
      else
         return base + "=" + jump;

      return null;
   };

   _calendar.prototype.process_button_calmove = function(button, callback)
   {
      var url = get_calmove_url(button);
      if (url)
         window.location = url;
   };

   _calendar.prototype.process = function (e,t)
   {
      var did, tag, mon, top = this.top();

      if (e.type!="click")
         return true;

      // Preserve value of 't' for default process function:
      var tel = t;

      while (tel && tel!=top)
      {
         if (tel.nodeType==1 && (tag=tel.tagName.toLowerCase()))
         {
            if (tag=="td" && (did=tel.getAttribute("data-name")))
               return this.process_cell_click(tel, did);
            else if (tag=="button" && (mon=tel.getAttribute("data-jump")))
               return this.process_month_jump(mon);
         }

         tel = tel.parentNode;
      }

      return this.call_super_event("table", "process", arguments);
   };

   _calendar.prototype.get_el_click_info = function(el)
   {
      var did, dname, task, rval=null;
      if ((did=el.getAttribute("data-id")) && class_includes(el,"day_content")
          || (dname=el.getAttribute("data-name")) && class_includes(el,"cal_day"))
      {
         rval = { target : el,
                  task   : this.get_on_click_value("day", el.tagName.toLowerCase()),
                  idname : this.get_click_id_name("td") || this.get_click_id_name("day")
                };

         if (did)
            rval.did = did;
         else if (dname)
            rval.dname = dname;
      }
      return rval;
   };

   _calendar.prototype.process = function (e,t)
   {
      var clickinfo, tag, mon, top = this.top();

      if (e.type!="click")
         return true;

      // Preserve the arguments for last-resort call to table::process().
      var tel = t;
      while (tel && tel!=top)
      {
         if ((click_info = this.get_el_click_info(tel)))
            return this.process_click_info(click_info);
         else if ((tag=tel.tagName.toLowerCase())=="button")
         {
            if (mon=tel.getAttribute("data-jump"))
               return this.process_month_jump(mon);
         }

         tel = tel.parentNode;
      }

      return this.call_super_event("table", "process", arguments);
   };

})();
<|endoftext|>


<commit_before>// Credits: borrowed code from fcomb/redux-logger

export default function createLogger ({
  collapsed = true,
  transformer = state => state,
  mutationTransformer = mut => mut
} = {}) {
  return store => {
    let prevState = JSON.parse(JSON.stringify(store.state))

    store.subscribe((mutation, state) => {
      if (typeof console === 'undefined') {
        return
      }
      const nextState = JSON.parse(JSON.stringify(state))
      const time = new Date()
      const formattedTime = ` @ ${pad(time.getHours(), 2)}:${pad(time.getMinutes(), 2)}:${pad(time.getSeconds(), 2)}.${pad(time.getMilliseconds(), 3)}`
      const formattedMutation = mutationTransformer(mutation)
      const message = `mutation ${mutation.type}${formattedTime}`
      const startMessage = collapsed
        ? console.groupCollapsed
        : console.group

      // render
      try {
        startMessage.call(console, message)
      } catch (e) {
        console.log(message)
      }

      console.log('%c prev state', 'color: #9E9E9E; font-weight: bold', prevState)
      console.log('%c mutation', 'color: #03A9F4; font-weight: bold', formattedMutation)
      console.log('%c next state', 'color: #4CAF50; font-weight: bold', nextState)

      try {
        console.groupEnd()
      } catch (e) {
        console.log('—— log end ——')
      }

      prevState = nextState
    })
  }
}

function repeat (str, times) {
  return (new Array(times + 1)).join(str)
}

function pad (num, maxLength) {
  return repeat('0', maxLength - num.toString().length) + num
}
<commit_msg>use state transformer in logger plugin (#310)<commit_after>// Credits: borrowed code from fcomb/redux-logger

export default function createLogger ({
  collapsed = true,
  transformer = state => state,
  mutationTransformer = mut => mut
} = {}) {
  return store => {
    let prevState = JSON.parse(JSON.stringify(store.state))

    store.subscribe((mutation, state) => {
      if (typeof console === 'undefined') {
        return
      }
      const nextState = JSON.parse(JSON.stringify(state))
      const time = new Date()
      const formattedTime = ` @ ${pad(time.getHours(), 2)}:${pad(time.getMinutes(), 2)}:${pad(time.getSeconds(), 2)}.${pad(time.getMilliseconds(), 3)}`
      const formattedMutation = mutationTransformer(mutation)
      const message = `mutation ${mutation.type}${formattedTime}`
      const startMessage = collapsed
        ? console.groupCollapsed
        : console.group

      // render
      try {
        startMessage.call(console, message)
      } catch (e) {
        console.log(message)
      }

      console.log('%c prev state', 'color: #9E9E9E; font-weight: bold', transformer(prevState))
      console.log('%c mutation', 'color: #03A9F4; font-weight: bold', formattedMutation)
      console.log('%c next state', 'color: #4CAF50; font-weight: bold', transformer(nextState))

      try {
        console.groupEnd()
      } catch (e) {
        console.log('—— log end ——')
      }

      prevState = nextState
    })
  }
}

function repeat (str, times) {
  return (new Array(times + 1)).join(str)
}

function pad (num, maxLength) {
  return repeat('0', maxLength - num.toString().length) + num
}
<|endoftext|>


<commit_before>var gulp = require('gulp');
var browserify = require('browserify');
var babel = require('gulp-babel');
var source = require('vinyl-source-stream');
var livereload = require('gulp-livereload');
var uglify = require('gulp-uglify');
var streamify = require('gulp-streamify');

var files = {
  js: ['./js/*.js'],
};

var paths = {
  build: './build'
};

gulp.task('production', function () {
  browserify("js/app.js")
  .transform('babelify', {
    presets: ['es2015', 'react']
  })
  .bundle()
  .pipe(source('bundle.js'))
  .pipe(streamify(uglify()))
  .pipe(gulp.dest(paths.build))
  .pipe(livereload());
});

gulp.task('dev', function() {
  browserify("js/app.js")
  .transform('babelify', {
    presets: ['es2015', 'react']
  })
  .bundle()
  .pipe(source('bundle.js'))
  .pipe(gulp.dest(paths.build))
  .pipe(livereload());
});

// Rerun the task when a file changes
gulp.task('watch', function() {
  livereload.listen();
  gulp.watch(files.js, ['build']);
});

// The default task (called when you run `gulp` from cli)
gulp.task('default', ['watch', 'dev']);<commit_msg>Gulpfile hotfix, forgot to change task name somewhere<commit_after>var gulp = require('gulp');
var browserify = require('browserify');
var babel = require('gulp-babel');
var source = require('vinyl-source-stream');
var livereload = require('gulp-livereload');
var uglify = require('gulp-uglify');
var streamify = require('gulp-streamify');

var files = {
  js: ['./js/*.js'],
};

var paths = {
  build: './build'
};

gulp.task('production', function () {
  browserify("js/app.js")
  .transform('babelify', {
    presets: ['es2015', 'react']
  })
  .bundle()
  .pipe(source('bundle.js'))
  .pipe(streamify(uglify()))
  .pipe(gulp.dest(paths.build))
  .pipe(livereload());
});

gulp.task('dev', function() {
  browserify("js/app.js")
  .transform('babelify', {
    presets: ['es2015', 'react']
  })
  .bundle()
  .pipe(source('bundle.js'))
  .pipe(gulp.dest(paths.build))
  .pipe(livereload());
});

// Rerun the task when a file changes
gulp.task('watch', function() {
  livereload.listen();
  gulp.watch(files.js, ['dev']);
});

// The default task (called when you run `gulp` from cli)
gulp.task('default', ['watch', 'dev']);<|endoftext|>


<commit_before>module.exports = {
    bsFiles: {
        src: [
            '<%= globalConfig.public.public %>/**/*',
            '!<%= globalConfig.public.public %>/patterns/**/*'
        ]
    },
    options: {
        watchTask: true,
        port: 8000,
        ui: {
            port: 8001
        },
        server: {
            baseDir: "./<%= globalConfig.public.public %>/"
        }
    }
};
<commit_msg>Disable Browsersync notifications and ghostMode<commit_after>module.exports = {
    bsFiles: {
        src: [
            '<%= globalConfig.public.public %>/**/*',
            '!<%= globalConfig.public.public %>/patterns/**/*'
        ]
    },
    options: {
        watchTask: true,
        port: 8000,
        ui: {
            port: 8001
        },
        server: {
            baseDir: './<%= globalConfig.public.public %>/'
        },
        ghostMode: false,
        notify: false
    }
};
<|endoftext|>


<commit_before>module.exports = function(grunt) {

	grunt.initConfig({
		pkg: grunt.file.readJSON('package.json'),
		src_dir: 'src',
		template_dir: 'grunt/templates',
		build_dir: 'build',
		docs_dir: 'build_docs',
		dist_dir: 'dist',

		modules: grunt.file.expand({ cwd: 'src' }, 'mm-*'),
		shared: grunt.file.expand({ cwd: 'src' }, 'shared/**/*.html'),

		clean: {
			build: '<%= build_dir %>',
			docs: '<%= docs_dir %>',
			dist: '<%= dist_dir %>',
			src: ['src/mm-*/*.+(css|min.js)', 'src/mm-*/template.html']
		},

		copy: {
			build: {
				expand: true,
				cwd: '<%= src_dir %>',
				src: ['**/*.+(html|js|woff)', '!**/example.html'],
				dest: '<%= build_dir %>'
			},
			dist: {
				expand: true,
				cwd: '<%= build_dir %>',
				src: ['**/*.html', '!mm-*/index.html'],
				dest: '<%= dist_dir %>'
			}
		},

		sass: {
			options: {
				includePaths: ['bower_components/bourbon/app/assets/stylesheets/', '<%= src_dir %>/shared/sass/']
			},

			dev: {
				files: [{
					expand: true,
					cwd: '<%= src_dir %>',
					src: ['**/*.scss'],
					dest: '<%= build_dir %>',
					ext: '.css'
				}]
			},

			docs: {
				files: {
					'<%= docs_dir %>/docs.css':'docs/docs.scss'
				}
			},

			dist: {
				options: {
					outputStyle: 'compressed'
				},
				files: [{
					expand: true,
					cwd: '<%= src_dir %>',
					src: ['**/*.scss'],
					dest: '<%= build_dir %>',
					ext: '.css'
				}]
			}
		},

		uglify: {
			dist: {
				files: [{
					expand: true,
					cwd: '<%= build_dir %>',
					src: ['mm-*/*.js', 'shared/js/*.js'],
					dest: '<%= build_dir %>'
				}]
			}
		},

		cssUrlEmbed: {
			fonts: {
				files: {
					'<%= build_dir %>/shared/fonts/fonts.css' : '<%= build_dir %>/shared/fonts/fonts.css'
				}
			}
		},

		hogan_static: {
			index: {
				options: {
					data: {
						modules: '<%= modules %>'
					}
				},
				files: [{
					src: '<%= template_dir %>/index_template.html',
					dest: '<%= build_dir %>/index.html'
				}]
			},
			colors: {
				options: {
					// delimiters:'<< >>',
					data: {
						colors: {}
					}
				},
				files: {
					'<%= src_dir %>/lib/Colors.js': '<%= template_dir %>/lib_color.js'
				}
			},
			lib: {
				options:{
					data: {
						modules: '<%= modules %>',
						shared: '<%= shared %>',
					}
				},
				files: [{
					src: '<%= template_dir %>/lib_template.html',
					dest: '<%= build_dir %>/<%= pkg.name %>.html'
				}]
			},
			fonts:{
				options:{
					data:{
						module:'shared-fonts',
						//style:grunt.file.read("build/shared/fonts/fonts.css")
					}
				},
				files:{
					'<%= build_dir %>/shared/fonts/shared-fonts.html': "<%= template_dir %>/style_module_template.html"
				}
			}
		},

		vulcanize: {
			options: {
				inlineScripts:true,
				inlineCss:true,
				stripExcludes:false
			},
			shared: {
				files: [{
					expand: true,
					cwd: '<%= build_dir %>',
					src: ['shared/**/*.html'],
					dest: '<%= build_dir %>'
				}]
			},
			modules: {
				options:{
					excludes: {
						imports: ['.*\.html']
					}
				},
				files: [{
					expand: true,
					cwd: '<%= build_dir %>',
					src: ['mm-*/mm-*.html'],
					dest: '<%= build_dir %>'
				}]
			},
			dist:{
				options:{
					excludes: {
						imports: ['polymer.html']
					}
				},
				files: {
					'<%= build_dir %>/<%= pkg.name %>.html' : '<%= build_dir %>/<%= pkg.name %>.html'
				}
			}
		},

		htmlmin: {
			dist: {
				options: {
					customAttrAssign: /\$=/,
					minifyJS: true,
					removeComments: true,
					collapseWhitespace: true
				},
				files: {
					'<%= build_dir %>/<%= pkg.name %>.html' : '<%= build_dir %>/<%= pkg.name %>.html'
				}
			}
		},

		replace: {
            bower: {
                src: ['<%= build_dir %>/**/*.html'],
                overwrite: true,
                replacements: [{
                    from: 'bower_components',
                    to: '..'
                }]
            }
        },

		banner: grunt.file.read("BANNER.txt"),

		usebanner: {
			jscss: {
				options: {
					banner: "/**\n<%= banner %>\n*/"
				},
				files: {
					src: [ 'src/**/*.js', 'src/**/*.scss' ]
				}
			},
			html: {
				options: {
					banner: "<!--\n<%= banner %>\n-->"
				},
				files: {
					src: [ 'src/mm-*/mm-*.html' ]
				}
			},
			dist: {
				options: {
					banner: "<!--\n<%= banner %>\n-->"
				},
				files: {
					src: [ '<%= build_dir %>/strand.html' ]
				}
			},
		},

		shell: {
			stageRelease: {
				command: 'git add <%= dist_dir %>/*'
			}
		},

		githubChanges: {
			release: {
				options: {
					owner: 'MediaMath',
					repository: 'strand',
					branch: 'develop',
					noMerges: true,
					tagName: 'v<%= pkg.version %>'
				}
			}
		},

		bump: {
			options: {
				files: [ 'package.json', 'bower.json' ],
				commitFiles: [ 'package.json', 'bower.json', 'CHANGELOG.md', 'dist/*' ],
				updateConfigs: ['pkg'],
				push: false,
				pushTo: 'upstream',
				createTag: true
			}
		}

	});

	//Generate template style includes for new polymer 1.1 ext-styling
	grunt.registerTask('style:imports', function() {
		var tasks = [];
		var build = grunt.config('build_dir') + "/";
		var styles = grunt.file.expand({
			cwd: grunt.config('build_dir')
		}, 'mm-**/*.css');

		var styleData = {};
		styles.forEach(function(file) {
			var key = file.split(".css").join("").split("/")[0];
			if (grunt.file.exists(build + file)) {
				var css = grunt.file.read(build + file);
				// styleData[key] = css;
				grunt.config.set("hogan_static.styles_" + key, {
					options:{
						data:{
							module:key,
							style:css
						}
					},
					files:[{
						src:'<%= template_dir %>/style_module_template.html',
						dest:'<%=build_dir%>/'+key+'/style.html'
					}]
				});
				tasks.push("hogan_static:styles_" + key);
			} else {
				grunt.log.writeln("Not Found:"+build+file);
			}
		});

		//set config for the static fonts lib as well
		var fnts = grunt.config.get('build_dir') + '/shared/fonts/fonts.css';
		grunt.config.set("fonts.options.data.style", grunt.file.read(fnts));

		grunt.task.run(tasks);

	});

	//Create HTML imports for JS library
	grunt.registerTask('jslib:imports', function() {
		var files = grunt.file.expand({cwd: grunt.config('src_dir') + '/shared/js/' }, '*.js');

		files.forEach(function(file) {
			var fileName = file.substr(0, file.lastIndexOf('.')) || file;
			grunt.file.write(grunt.config('build_dir') + '/shared/js/' + fileName.toLowerCase() + '.html', '<script src=\"' + file + '\"></script>');
		});

		grunt.log.ok();
	});

	grunt.registerTask('color', function() {
		var path = grunt.config('src_dir') + '/shared/sass/_color.scss';
		var color = grunt.file.read(path);
		color = color.replace(/\$color-(\w\d\d*): (#[\w\d]*);/g, function(a, key, value) {
			return "\t\"" + key + "\":\"" + value + "\",";
		});
		grunt.config.set('hogan_static.colors.options.data.colors', color);
		grunt.task.run(['hogan_static:colors']);
	});

	grunt.registerTask('build:dist', function(arg){
		grunt.task.run([
			'clean:build',
			'copy:build',
			'sass:dist',
			'cssUrlEmbed',
			'hogan_static:fonts',
			'style:imports',
			// 'hogan_static:lib', //un-comment to build entire library
			'vulcanize:dist',
			'htmlmin:dist',
			'usebanner:dist'
		]);
	});

	grunt.registerTask('build:dev', function() {
		grunt.task.run([
			'clean:build',
			'copy:build',
			'sass:dev',
			'hogan_static:fonts',
			'style:imports',
			'hogan_static:index'
			// 'hogan_static:lib'
		]);
	});

	grunt.registerTask('default', ['build:dev']);

	grunt.registerTask('release', function(version){
		version = version || "patch";
		grunt.task.run( "bump-only:" + version, "clean:dist", "build:dist", "replace:bower", "copy:dist", "shell:stageRelease", "githubChanges", "bump-commit");
	});
};
<commit_msg>fixed font build<commit_after>module.exports = function(grunt) {

	grunt.initConfig({
		pkg: grunt.file.readJSON('package.json'),
		src_dir: 'src',
		template_dir: 'grunt/templates',
		build_dir: 'build',
		docs_dir: 'build_docs',
		dist_dir: 'dist',

		modules: grunt.file.expand({ cwd: 'src' }, 'mm-*'),
		shared: grunt.file.expand({ cwd: 'src' }, 'shared/**/*.html'),

		clean: {
			build: '<%= build_dir %>',
			docs: '<%= docs_dir %>',
			dist: '<%= dist_dir %>',
			src: ['src/mm-*/*.+(css|min.js)', 'src/mm-*/template.html']
		},

		copy: {
			build: {
				expand: true,
				cwd: '<%= src_dir %>',
				src: ['**/*.+(html|js|woff)', '!**/example.html'],
				dest: '<%= build_dir %>'
			},
			dist: {
				expand: true,
				cwd: '<%= build_dir %>',
				src: ['**/*.html', '!mm-*/index.html'],
				dest: '<%= dist_dir %>'
			}
		},

		sass: {
			options: {
				includePaths: ['bower_components/bourbon/app/assets/stylesheets/', '<%= src_dir %>/shared/sass/']
			},

			dev: {
				files: [{
					expand: true,
					cwd: '<%= src_dir %>',
					src: ['**/*.scss'],
					dest: '<%= build_dir %>',
					ext: '.css'
				}]
			},

			docs: {
				files: {
					'<%= docs_dir %>/docs.css':'docs/docs.scss'
				}
			},

			dist: {
				options: {
					outputStyle: 'compressed'
				},
				files: [{
					expand: true,
					cwd: '<%= src_dir %>',
					src: ['**/*.scss'],
					dest: '<%= build_dir %>',
					ext: '.css'
				}]
			}
		},

		uglify: {
			dist: {
				files: [{
					expand: true,
					cwd: '<%= build_dir %>',
					src: ['mm-*/*.js', 'shared/js/*.js'],
					dest: '<%= build_dir %>'
				}]
			}
		},

		cssUrlEmbed: {
			fonts: {
				files: {
					'<%= build_dir %>/shared/fonts/fonts.css' : '<%= build_dir %>/shared/fonts/fonts.css'
				}
			}
		},

		hogan_static: {
			index: {
				options: {
					data: {
						modules: '<%= modules %>'
					}
				},
				files: [{
					src: '<%= template_dir %>/index_template.html',
					dest: '<%= build_dir %>/index.html'
				}]
			},
			colors: {
				options: {
					// delimiters:'<< >>',
					data: {
						colors: {}
					}
				},
				files: {
					'<%= src_dir %>/lib/Colors.js': '<%= template_dir %>/lib_color.js'
				}
			},
			lib: {
				options:{
					data: {
						modules: '<%= modules %>',
						shared: '<%= shared %>',
					}
				},
				files: [{
					src: '<%= template_dir %>/lib_template.html',
					dest: '<%= build_dir %>/<%= pkg.name %>.html'
				}]
			},
			fonts:{
				options:{
					data:{
						module:'shared-fonts',
						//style:grunt.file.read("build/shared/fonts/fonts.css")
					}
				},
				files:{
					'<%= build_dir %>/shared/fonts/shared-fonts.html': "<%= template_dir %>/style_module_template.html"
				}
			}
		},

		vulcanize: {
			options: {
				inlineScripts:true,
				inlineCss:true,
				stripExcludes:false
			},
			shared: {
				files: [{
					expand: true,
					cwd: '<%= build_dir %>',
					src: ['shared/**/*.html'],
					dest: '<%= build_dir %>'
				}]
			},
			modules: {
				options:{
					excludes: {
						imports: ['.*\.html']
					}
				},
				files: [{
					expand: true,
					cwd: '<%= build_dir %>',
					src: ['mm-*/mm-*.html'],
					dest: '<%= build_dir %>'
				}]
			},
			dist:{
				options:{
					excludes: {
						imports: ['polymer.html']
					}
				},
				files: {
					'<%= build_dir %>/<%= pkg.name %>.html' : '<%= build_dir %>/<%= pkg.name %>.html'
				}
			}
		},

		htmlmin: {
			dist: {
				options: {
					customAttrAssign: /\$=/,
					minifyJS: true,
					removeComments: true,
					collapseWhitespace: true
				},
				files: {
					'<%= build_dir %>/<%= pkg.name %>.html' : '<%= build_dir %>/<%= pkg.name %>.html'
				}
			}
		},

		replace: {
            bower: {
                src: ['<%= build_dir %>/**/*.html'],
                overwrite: true,
                replacements: [{
                    from: 'bower_components',
                    to: '..'
                }]
            }
        },

		banner: grunt.file.read("BANNER.txt"),

		usebanner: {
			jscss: {
				options: {
					banner: "/**\n<%= banner %>\n*/"
				},
				files: {
					src: [ 'src/**/*.js', 'src/**/*.scss' ]
				}
			},
			html: {
				options: {
					banner: "<!--\n<%= banner %>\n-->"
				},
				files: {
					src: [ 'src/mm-*/mm-*.html' ]
				}
			},
			dist: {
				options: {
					banner: "<!--\n<%= banner %>\n-->"
				},
				files: {
					src: [ '<%= build_dir %>/strand.html' ]
				}
			},
		},

		shell: {
			stageRelease: {
				command: 'git add <%= dist_dir %>/*'
			}
		},

		githubChanges: {
			release: {
				options: {
					owner: 'MediaMath',
					repository: 'strand',
					branch: 'develop',
					noMerges: true,
					tagName: 'v<%= pkg.version %>'
				}
			}
		},

		bump: {
			options: {
				files: [ 'package.json', 'bower.json' ],
				commitFiles: [ 'package.json', 'bower.json', 'CHANGELOG.md', 'dist/*' ],
				updateConfigs: ['pkg'],
				push: false,
				pushTo: 'upstream',
				createTag: true
			}
		}

	});

	//Generate template style includes for new polymer 1.1 ext-styling
	grunt.registerTask('style:imports', function() {
		var tasks = [];
		var build = grunt.config('build_dir') + "/";
		var styles = grunt.file.expand({
			cwd: grunt.config('build_dir')
		}, 'mm-**/*.css');

		var styleData = {};
		styles.forEach(function(file) {
			var key = file.split(".css").join("").split("/")[0];
			if (grunt.file.exists(build + file)) {
				var css = grunt.file.read(build + file);
				// styleData[key] = css;
				grunt.config.set("hogan_static.styles_" + key, {
					options:{
						data:{
							module:key,
							style:css
						}
					},
					files:[{
						src:'<%= template_dir %>/style_module_template.html',
						dest:'<%=build_dir%>/'+key+'/style.html'
					}]
				});
				tasks.push("hogan_static:styles_" + key);
			} else {
				grunt.log.writeln("Not Found:"+build+file);
			}
		});

		//set config for the static fonts lib as well
		var fnts = grunt.config.get('build_dir') + '/shared/fonts/fonts.css';
		grunt.config.set("hogan_static.fonts.options.data.style", grunt.file.read(fnts));

		//run batched
		grunt.task.run(tasks);

	});

	//Create HTML imports for JS library
	grunt.registerTask('jslib:imports', function() {
		var files = grunt.file.expand({cwd: grunt.config('src_dir') + '/shared/js/' }, '*.js');

		files.forEach(function(file) {
			var fileName = file.substr(0, file.lastIndexOf('.')) || file;
			grunt.file.write(grunt.config('build_dir') + '/shared/js/' + fileName.toLowerCase() + '.html', '<script src=\"' + file + '\"></script>');
		});

		grunt.log.ok();
	});

	grunt.registerTask('color', function() {
		var path = grunt.config('src_dir') + '/shared/sass/_color.scss';
		var color = grunt.file.read(path);
		color = color.replace(/\$color-(\w\d\d*): (#[\w\d]*);/g, function(a, key, value) {
			return "\t\"" + key + "\":\"" + value + "\",";
		});
		grunt.config.set('hogan_static.colors.options.data.colors', color);
		grunt.task.run(['hogan_static:colors']);
	});

	grunt.registerTask('build:dist', function(arg){
		grunt.task.run([
			'clean:build',
			'copy:build',
			'sass:dist',
			'cssUrlEmbed',
			'style:imports',
			'hogan_static:fonts',
			// 'hogan_static:lib', //un-comment to build entire library
			'vulcanize:dist',
			'htmlmin:dist',
			'usebanner:dist'
		]);
	});

	grunt.registerTask('build:dev', function() {
		grunt.task.run([
			'clean:build',
			'copy:build',
			'sass:dev',
			'style:imports',
			'hogan_static:fonts',
			'hogan_static:index'
			// 'hogan_static:lib'
		]);
	});

	grunt.registerTask('default', ['build:dev']);

	grunt.registerTask('release', function(version){
		version = version || "patch";
		grunt.task.run( "bump-only:" + version, "clean:dist", "build:dist", "replace:bower", "copy:dist", "shell:stageRelease", "githubChanges", "bump-commit");
	});
};
<|endoftext|>


<commit_before>import { loadState, saveState } from 'utility/localStorage'
import rootReducer from 'reducers'

import { applyMiddleware, createStore } from 'redux'
import throttle from 'lodash/throttle'
import createLogger from 'redux-logger'
import thunk from 'redux-thunk'

export default function configureStore () {
  const middlewares = [thunk, createLogger()]

  const initialState = loadState()

  const { version } = initialState
  delete initialState['version']

  let store
  if (version && version >= '0.2.0') {
    store = createStore(rootReducer, initialState, applyMiddleware(...middlewares))
  } else {
    store = createStore(rootReducer, applyMiddleware(...middlewares))
  }

  store.subscribe(throttle(() => {
    const state = store.getState()

    saveState({
      currentShader: state.currentShader,
      shaders: state.shaders,
      viewports: state.viewports,
      version: '0.2.0'
    })
  }, 1000))

  return store
}
<commit_msg>fixes initialState for undefined case<commit_after>import { loadState, saveState } from 'utility/localStorage'
import rootReducer from 'reducers'

import { applyMiddleware, createStore } from 'redux'
import throttle from 'lodash/throttle'
import createLogger from 'redux-logger'
import thunk from 'redux-thunk'

export default function configureStore () {
  const middlewares = [thunk, createLogger()]

  const initialState = loadState()

  let version
  if (initialState && initialState.version) {
    version = initialState.version
    delete initialState['version']
  }

  let store
  if (version && version >= '0.2.0') {
    store = createStore(rootReducer, initialState, applyMiddleware(...middlewares))
  } else {
    store = createStore(rootReducer, applyMiddleware(...middlewares))
  }

  store.subscribe(throttle(() => {
    const state = store.getState()

    saveState({
      currentShader: state.currentShader,
      shaders: state.shaders,
      viewports: state.viewports,
      version: '0.2.0'
    })
  }, 1000))

  return store
}
<|endoftext|>


<commit_before>/*
 * Copyright 2013 Jive Software
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

var jive = require('../../api');
var q = require('q');
var client = require('./../tile/client');

exports.save = function( webhook ) {
    return jive.context.persistence.save( "webhook", webhook['url'], webhook );
};

exports.register = function( jiveCommunity, events, object, webhookCallback ) {
    var deferred = q.defer();

    jive.community.findByCommunity(jiveCommunity).then( function(community) {
        if ( community ) {

            var webhookRequest = {
                "events": events,
                "object": object,
                "callback": webhookCallback
            };

            var access_token = community['oauth']['access_token'];
            var jiveUrl = community['jiveUrl'];
            var webhooksEndpoint = jiveUrl + '/api/core/v3/webhooks';

            var headers = {
                'Authorization' : 'Bearer ' + access_token
            };

            jive.util.buildRequest(webhooksEndpoint, "POST", webhookRequest, headers).then(
                function(result) {
                    deferred.resolve( result );
                },
                function(error) {
                    deferred.reject( error );
                }
            );
        } else {
            deferred.reject( { "error" : "No such jive community"} );
        }
    });

    return deferred.promise;
};
<commit_msg>refactor<commit_after>/*
 * Copyright 2013 Jive Software
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

var jive = require('../../api');
var q = require('q');

exports.save = function( webhook ) {
    return jive.context.persistence.save( "webhook", webhook['url'], webhook );
};

exports.register = function( jiveCommunity, events, object, webhookCallback ) {
    var deferred = q.defer();

    jive.community.findByCommunity(jiveCommunity).then( function(community) {
        if ( community ) {

            var webhookRequest = {
                "events": events,
                "object": object,
                "callback": webhookCallback
            };

            var access_token = community['oauth']['access_token'];
            var jiveUrl = community['jiveUrl'];
            var webhooksEndpoint = jiveUrl + '/api/core/v3/webhooks';

            var headers = {
                'Authorization' : 'Bearer ' + access_token
            };

            jive.util.buildRequest(webhooksEndpoint, "POST", webhookRequest, headers).then(
                function(result) {
                    deferred.resolve( result );
                },
                function(error) {
                    deferred.reject( error );
                }
            );
        } else {
            deferred.reject( { "error" : "No such jive community"} );
        }
    });

    return deferred.promise;
};
<|endoftext|>


<commit_before>/**
 * ownCloud - Music app
 *
 * This file is licensed under the Affero General Public License version 3 or
 * later. See the COPYING file.
 *
 * @author Morris Jobke <hey@morrisjobke.de>
 * @author Pauli Järvinen <pauli.jarvinen@gmail.com>
 * @copyright Morris Jobke 2013, 2014
 * @copyright Pauli Järvinen 2017 - 2019
 */

angular.module('Music').controller('MainController', [
'$rootScope', '$scope', '$timeout', '$window', '$document', 'ArtistFactory',
'playlistService', 'libraryService', 'inViewService', 'gettextCatalog', 'Restangular',
function ($rootScope, $scope, $timeout, $window, $document, ArtistFactory,
		playlistService, libraryService, inViewService, gettextCatalog, Restangular) {

	// retrieve language from backend - is set in ng-app HTML element
	gettextCatalog.currentLanguage = $rootScope.lang;

	// Add dark-theme class to the #app element if Nextcloud dark theme detected.
	// Css can then diffentiate the style of the contained elments where necessary.
	if (OC_Music_Utils.darkThemeActive()) {
		$('#app').addClass('dark-theme');
	}

	$rootScope.playing = false;
	$rootScope.playingView = null;
	$scope.currentTrack = null;
	playlistService.subscribe('trackChanged', function(e, listEntry){
		$scope.currentTrack = listEntry.track;
		$scope.currentTrackIndex = playlistService.getCurrentIndex();
	});

	playlistService.subscribe('play', function(e, playingView) {
		// assume that the play started from current view if no other view given
		$rootScope.playingView = playingView || $rootScope.currentView;
	});

	playlistService.subscribe('playlistEnded', function() {
		$rootScope.playingView = null;
		$scope.currentTrack = null;
		$scope.currentTrackIndex = -1;
	});

	$scope.trackCountText = function(playlist) {
		var trackCount = playlist ? playlist.tracks.length : libraryService.getTrackCount();
		return gettextCatalog.getPlural(trackCount, '1 track', '{{ count }} tracks', { count: trackCount });
	};

	$scope.albumCountText = function() {
		var albumCount = libraryService.getAlbumCount();
		return gettextCatalog.getPlural(albumCount, '1 album', '{{ count }} albums', { count: albumCount });
	};

	$scope.folderCountText = function() {
		if (libraryService.foldersLoaded()) {
			var folderCount = libraryService.getAllFolders().length;
			return gettextCatalog.getPlural(folderCount, '1 folder', '{{ count }} folders', { count: folderCount });
		} else {
			return '';
		}
	};

	$scope.update = function() {
		$scope.updateAvailable = false;
		$rootScope.loadingCollection = true;

		// load the music collection
		ArtistFactory.getArtists().then(function(artists) {
			libraryService.setCollection(artists);
			libraryService.setFolders(null); // invalidate any out-dated folders
			$scope.artists = libraryService.getAllArtists();

			// Emit the event asynchronously so that the DOM tree has already been
			// manipulated and rendered by the browser when obeservers get the event.
			$timeout(function() {
				$rootScope.$emit('artistsLoaded');
			});

			// Load playlist once the collection has been loaded
			Restangular.all('playlists').getList().then(function(playlists) {
				libraryService.setPlaylists(playlists);
				$scope.playlists = libraryService.getAllPlaylists();
				$rootScope.$emit('playlistsLoaded');
			});

			// The "no content"/"click to scan"/"scanning" banner uses "collapsed" layout
			// if there are any tracks already visible
			if (libraryService.getTrackCount() > 0) {
				$('.emptycontent').addClass('collapsed');
			} else {
				$('.emptycontent').removeClass('collapsed');
			}

			$rootScope.loadingCollection = false;
		},
		function(response) { // error handling
			$rootScope.loadingCollection = false;

			var reason = null;
			switch (response.status) {
			case 500:
				reason = gettextCatalog.getString('Internal server error');
				break;
			case 504:
				reason = gettextCatalog.getString('Timeout');
				break;
			default:
				reason = response.status;
				break;
			}
			OC.Notification.showTemporary(
					gettextCatalog.getString('Failed to load the collection: ') + reason);
		});

	};

	// initial loading of artists
	$scope.update();

	var FILES_TO_SCAN_PER_STEP = 10;
	var filesToScan = null;
	var filesToScanIterator = 0;
	var previouslyScannedCount = 0;

	$scope.updateFilesToScan = function() {
		Restangular.one('scanstate').get().then(function(state) {
			previouslyScannedCount = state.scannedCount;
			filesToScan = state.unscannedFiles;
			filesToScanIterator = 0;
			$scope.toScan = (filesToScan.length > 0);
			$scope.scanningScanned = previouslyScannedCount;
			$scope.scanningTotal = previouslyScannedCount + filesToScan.length;
			$scope.noMusicAvailable = ($scope.scanningTotal === 0);
		});
	};

	function processNextScanStep() {
		var sliceEnd = filesToScanIterator + FILES_TO_SCAN_PER_STEP;
		var filesForStep = filesToScan.slice(filesToScanIterator, sliceEnd);
		var params = {
				files: filesForStep.join(','),
				finalize: sliceEnd >= filesToScan.length
		};
		Restangular.all('scan').post(params).then(function(result) {
			// Ignore the results if scanning has been cancelled while we
			// were waiting for the result.
			if ($scope.scanning) {
				filesToScanIterator = sliceEnd;

				if (result.filesScanned || result.coversUpdated) {
					$scope.updateAvailable = true;
				}

				$scope.scanningScanned = previouslyScannedCount + filesToScanIterator;

				if (filesToScanIterator < filesToScan.length) {
					processNextScanStep();
				} else {
					$scope.scanning = false;
				}

				// Update the newly scanned tracks to UI automatically when
				// a) the first batch is ready
				// b) the scanning process is completed.
				// Otherwise the UI state is updated only when the user hits the 'update' button
				if ($scope.updateAvailable && $scope.artists && ($scope.artists.length === 0 || !$scope.scanning)) {
					$scope.update();
				}
			}
		});
	}

	$scope.startScanning = function() {
		$scope.toScan = false;
		$scope.scanning = true;
		processNextScanStep();
	};

	$scope.stopScanning = function() {
		$scope.scanning = false;
	};

	$scope.loadFoldersAndThen = function(callback) {
		if (libraryService.foldersLoaded()) {
			$timeout(callback);
		} else {
			Restangular.one('folders').get().then(function (folders) {
				libraryService.setFolders(folders);
				callback();
			});
		}
	};

	$scope.showSidebar = function(trackId) {
		$rootScope.$emit('showDetails', trackId);
		$('#app-content').addClass('with-app-sidebar');
		$timeout(function() {
			var trackElem = document.getElementById('track-' + trackId);
			if (!isElementInViewPort(trackElem)) {
				$rootScope.$emit('scrollToTrack', trackId, 0);
			}
		}, 300);
	};

	$scope.hideSidebar = function() {
		$rootScope.$emit('hideDetails');
		$('#app-content').removeClass('with-app-sidebar');
		$('#app-content').css('margin-right', '');
	};

	function scrollOffset() {
		var controls = document.getElementById('controls');
		var header = document.getElementById('header');
		var offset = controls ? controls.offsetHeight : 0;
		if (OC_Music_Utils.newLayoutStructure() && header) {
			offset += header.offsetHeight;
		}
		return offset;
	}

	$scope.scrollToItem = function(itemId, animationTime /* optional */) {
		var container = OC_Music_Utils.newLayoutStructure() ? $document : $('#app-content');
		var element = $('#' + itemId);
		if (container && element) {
			if (animationTime === undefined) {
				animationTime = 500;
			}
			container.scrollToElement(element, scrollOffset(), animationTime);
		}
	};

	// Test if element is at least partially within the view-port
	function isElementInViewPort(el) {
		return inViewService.isElementInViewPort(el, -scrollOffset());
	}

	function setMasterLayout(classes) {
		var missingClasses = _.difference(['tablet', 'mobile', 'portrait'], classes);
		var appContent = $('#app-content');

		_.each(classes, function(cls) {
			appContent.addClass(cls);
		});
		_.each(missingClasses, function(cls) {
			appContent.removeClass(cls);
		});
	}

	$rootScope.$on('resize', function(event, appView) {
		var appViewWidth = appView.outerWidth();

		// Adjust controls bar width to not overlap with the scroll bar.
		// Subtrack one pixel from the width because outerWidth() seems to
		// return rounded integer value which may sometimes be slightly larger
		// than the actual width of the #app-view.
		var controlsWidth = appViewWidth - 1;
		$('#controls').css('width', controlsWidth);
		$('#controls').css('min-width', controlsWidth);

		// the "no content"/"click to scan"/"scanning" banner has the same width as controls
		$('.emptycontent').css('width', controlsWidth);
		$('.emptycontent').css('min-width', controlsWidth);

		// Set the app-content class according to window and view width. This has
		// impact on the overall layout of the app. See mobile.css and tablet.css.
		if ($window.innerWidth <= 570 || appViewWidth <= 500) {
			setMasterLayout(['mobile', 'portrait']);
		}
		else if ($window.innerWidth <= 768) {
			setMasterLayout(['mobile']);
		}
		else if (appViewWidth <= 690) {
			setMasterLayout(['tablet', 'portrait']);
		}
		else if (appViewWidth <= 1024) {
			setMasterLayout(['tablet']);
		}
		else {
			setMasterLayout([]);
		}
	});

	if (OC_Music_Utils.newLayoutStructure()) {
		$('#controls').addClass('taller-header');
	}

	// Work-around for NC14+: The sidebar width has been limited to 500px (normally 27%),
	// but it's not possible to make corresponding "max margin" definition for #app-content
	// in css. Hence, the margin width is limited here.
	var appContent = $('#app-content');
	appContent.resize(function() {
		if (appContent.hasClass('with-app-sidebar')) {
			var sidebarWidth = $('#app-sidebar').outerWidth();
			var viewWidth = $('#header').outerWidth();

			if (sidebarWidth < 0.27 * viewWidth) {
				appContent.css('margin-right', sidebarWidth);
			} else {
				appContent.css('margin-right', '');
			}
		}
		else {
			appContent.css('margin-right', '');
		}
	});

	$scope.scanning = false;
	$scope.scanningScanned = 0;
	$scope.scanningTotal = 0;

	// initial lookup if new files are available
	$scope.updateFilesToScan();
}]);
<commit_msg>Fix error being logged to browser console when an unassigned alphabet navigation link is clicked<commit_after>/**
 * ownCloud - Music app
 *
 * This file is licensed under the Affero General Public License version 3 or
 * later. See the COPYING file.
 *
 * @author Morris Jobke <hey@morrisjobke.de>
 * @author Pauli Järvinen <pauli.jarvinen@gmail.com>
 * @copyright Morris Jobke 2013, 2014
 * @copyright Pauli Järvinen 2017 - 2019
 */

angular.module('Music').controller('MainController', [
'$rootScope', '$scope', '$timeout', '$window', '$document', 'ArtistFactory',
'playlistService', 'libraryService', 'inViewService', 'gettextCatalog', 'Restangular',
function ($rootScope, $scope, $timeout, $window, $document, ArtistFactory,
		playlistService, libraryService, inViewService, gettextCatalog, Restangular) {

	// retrieve language from backend - is set in ng-app HTML element
	gettextCatalog.currentLanguage = $rootScope.lang;

	// Add dark-theme class to the #app element if Nextcloud dark theme detected.
	// Css can then diffentiate the style of the contained elments where necessary.
	if (OC_Music_Utils.darkThemeActive()) {
		$('#app').addClass('dark-theme');
	}

	$rootScope.playing = false;
	$rootScope.playingView = null;
	$scope.currentTrack = null;
	playlistService.subscribe('trackChanged', function(e, listEntry){
		$scope.currentTrack = listEntry.track;
		$scope.currentTrackIndex = playlistService.getCurrentIndex();
	});

	playlistService.subscribe('play', function(e, playingView) {
		// assume that the play started from current view if no other view given
		$rootScope.playingView = playingView || $rootScope.currentView;
	});

	playlistService.subscribe('playlistEnded', function() {
		$rootScope.playingView = null;
		$scope.currentTrack = null;
		$scope.currentTrackIndex = -1;
	});

	$scope.trackCountText = function(playlist) {
		var trackCount = playlist ? playlist.tracks.length : libraryService.getTrackCount();
		return gettextCatalog.getPlural(trackCount, '1 track', '{{ count }} tracks', { count: trackCount });
	};

	$scope.albumCountText = function() {
		var albumCount = libraryService.getAlbumCount();
		return gettextCatalog.getPlural(albumCount, '1 album', '{{ count }} albums', { count: albumCount });
	};

	$scope.folderCountText = function() {
		if (libraryService.foldersLoaded()) {
			var folderCount = libraryService.getAllFolders().length;
			return gettextCatalog.getPlural(folderCount, '1 folder', '{{ count }} folders', { count: folderCount });
		} else {
			return '';
		}
	};

	$scope.update = function() {
		$scope.updateAvailable = false;
		$rootScope.loadingCollection = true;

		// load the music collection
		ArtistFactory.getArtists().then(function(artists) {
			libraryService.setCollection(artists);
			libraryService.setFolders(null); // invalidate any out-dated folders
			$scope.artists = libraryService.getAllArtists();

			// Emit the event asynchronously so that the DOM tree has already been
			// manipulated and rendered by the browser when obeservers get the event.
			$timeout(function() {
				$rootScope.$emit('artistsLoaded');
			});

			// Load playlist once the collection has been loaded
			Restangular.all('playlists').getList().then(function(playlists) {
				libraryService.setPlaylists(playlists);
				$scope.playlists = libraryService.getAllPlaylists();
				$rootScope.$emit('playlistsLoaded');
			});

			// The "no content"/"click to scan"/"scanning" banner uses "collapsed" layout
			// if there are any tracks already visible
			if (libraryService.getTrackCount() > 0) {
				$('.emptycontent').addClass('collapsed');
			} else {
				$('.emptycontent').removeClass('collapsed');
			}

			$rootScope.loadingCollection = false;
		},
		function(response) { // error handling
			$rootScope.loadingCollection = false;

			var reason = null;
			switch (response.status) {
			case 500:
				reason = gettextCatalog.getString('Internal server error');
				break;
			case 504:
				reason = gettextCatalog.getString('Timeout');
				break;
			default:
				reason = response.status;
				break;
			}
			OC.Notification.showTemporary(
					gettextCatalog.getString('Failed to load the collection: ') + reason);
		});

	};

	// initial loading of artists
	$scope.update();

	var FILES_TO_SCAN_PER_STEP = 10;
	var filesToScan = null;
	var filesToScanIterator = 0;
	var previouslyScannedCount = 0;

	$scope.updateFilesToScan = function() {
		Restangular.one('scanstate').get().then(function(state) {
			previouslyScannedCount = state.scannedCount;
			filesToScan = state.unscannedFiles;
			filesToScanIterator = 0;
			$scope.toScan = (filesToScan.length > 0);
			$scope.scanningScanned = previouslyScannedCount;
			$scope.scanningTotal = previouslyScannedCount + filesToScan.length;
			$scope.noMusicAvailable = ($scope.scanningTotal === 0);
		});
	};

	function processNextScanStep() {
		var sliceEnd = filesToScanIterator + FILES_TO_SCAN_PER_STEP;
		var filesForStep = filesToScan.slice(filesToScanIterator, sliceEnd);
		var params = {
				files: filesForStep.join(','),
				finalize: sliceEnd >= filesToScan.length
		};
		Restangular.all('scan').post(params).then(function(result) {
			// Ignore the results if scanning has been cancelled while we
			// were waiting for the result.
			if ($scope.scanning) {
				filesToScanIterator = sliceEnd;

				if (result.filesScanned || result.coversUpdated) {
					$scope.updateAvailable = true;
				}

				$scope.scanningScanned = previouslyScannedCount + filesToScanIterator;

				if (filesToScanIterator < filesToScan.length) {
					processNextScanStep();
				} else {
					$scope.scanning = false;
				}

				// Update the newly scanned tracks to UI automatically when
				// a) the first batch is ready
				// b) the scanning process is completed.
				// Otherwise the UI state is updated only when the user hits the 'update' button
				if ($scope.updateAvailable && $scope.artists && ($scope.artists.length === 0 || !$scope.scanning)) {
					$scope.update();
				}
			}
		});
	}

	$scope.startScanning = function() {
		$scope.toScan = false;
		$scope.scanning = true;
		processNextScanStep();
	};

	$scope.stopScanning = function() {
		$scope.scanning = false;
	};

	$scope.loadFoldersAndThen = function(callback) {
		if (libraryService.foldersLoaded()) {
			$timeout(callback);
		} else {
			Restangular.one('folders').get().then(function (folders) {
				libraryService.setFolders(folders);
				callback();
			});
		}
	};

	$scope.showSidebar = function(trackId) {
		$rootScope.$emit('showDetails', trackId);
		$('#app-content').addClass('with-app-sidebar');
		$timeout(function() {
			var trackElem = document.getElementById('track-' + trackId);
			if (!isElementInViewPort(trackElem)) {
				$rootScope.$emit('scrollToTrack', trackId, 0);
			}
		}, 300);
	};

	$scope.hideSidebar = function() {
		$rootScope.$emit('hideDetails');
		$('#app-content').removeClass('with-app-sidebar');
		$('#app-content').css('margin-right', '');
	};

	function scrollOffset() {
		var controls = document.getElementById('controls');
		var header = document.getElementById('header');
		var offset = controls ? controls.offsetHeight : 0;
		if (OC_Music_Utils.newLayoutStructure() && header) {
			offset += header.offsetHeight;
		}
		return offset;
	}

	$scope.scrollToItem = function(itemId, animationTime /* optional */) {
		if (itemId) {
			var container = OC_Music_Utils.newLayoutStructure() ? $document : $('#app-content');
			var element = $('#' + itemId);
			if (container && element) {
				if (animationTime === undefined) {
					animationTime = 500;
				}
				container.scrollToElement(element, scrollOffset(), animationTime);
			}
		}
	};

	// Test if element is at least partially within the view-port
	function isElementInViewPort(el) {
		return inViewService.isElementInViewPort(el, -scrollOffset());
	}

	function setMasterLayout(classes) {
		var missingClasses = _.difference(['tablet', 'mobile', 'portrait'], classes);
		var appContent = $('#app-content');

		_.each(classes, function(cls) {
			appContent.addClass(cls);
		});
		_.each(missingClasses, function(cls) {
			appContent.removeClass(cls);
		});
	}

	$rootScope.$on('resize', function(event, appView) {
		var appViewWidth = appView.outerWidth();

		// Adjust controls bar width to not overlap with the scroll bar.
		// Subtrack one pixel from the width because outerWidth() seems to
		// return rounded integer value which may sometimes be slightly larger
		// than the actual width of the #app-view.
		var controlsWidth = appViewWidth - 1;
		$('#controls').css('width', controlsWidth);
		$('#controls').css('min-width', controlsWidth);

		// the "no content"/"click to scan"/"scanning" banner has the same width as controls
		$('.emptycontent').css('width', controlsWidth);
		$('.emptycontent').css('min-width', controlsWidth);

		// Set the app-content class according to window and view width. This has
		// impact on the overall layout of the app. See mobile.css and tablet.css.
		if ($window.innerWidth <= 570 || appViewWidth <= 500) {
			setMasterLayout(['mobile', 'portrait']);
		}
		else if ($window.innerWidth <= 768) {
			setMasterLayout(['mobile']);
		}
		else if (appViewWidth <= 690) {
			setMasterLayout(['tablet', 'portrait']);
		}
		else if (appViewWidth <= 1024) {
			setMasterLayout(['tablet']);
		}
		else {
			setMasterLayout([]);
		}
	});

	if (OC_Music_Utils.newLayoutStructure()) {
		$('#controls').addClass('taller-header');
	}

	// Work-around for NC14+: The sidebar width has been limited to 500px (normally 27%),
	// but it's not possible to make corresponding "max margin" definition for #app-content
	// in css. Hence, the margin width is limited here.
	var appContent = $('#app-content');
	appContent.resize(function() {
		if (appContent.hasClass('with-app-sidebar')) {
			var sidebarWidth = $('#app-sidebar').outerWidth();
			var viewWidth = $('#header').outerWidth();

			if (sidebarWidth < 0.27 * viewWidth) {
				appContent.css('margin-right', sidebarWidth);
			} else {
				appContent.css('margin-right', '');
			}
		}
		else {
			appContent.css('margin-right', '');
		}
	});

	$scope.scanning = false;
	$scope.scanningScanned = 0;
	$scope.scanningTotal = 0;

	// initial lookup if new files are available
	$scope.updateFilesToScan();
}]);
<|endoftext|>


<commit_before>/*jslint unparam: true, browser: true, indent: 2 */

;(function ($, window, document, undefined) {
  'use strict';

  Foundation.libs.tooltips = {
    name: 'tooltips',

    version : '4.0.0.alpha',

    settings : {
      bodyHeight : 0,
      selector : '.has-tip',
      additionalInheritableClasses : [],
      tooltipClass : '.tooltip',
      tipTemplate : function (selector, content) {
        return '' + content + '';
      }
    },

    cache : {},

    init : function (scope, method, options) {
      var self = this;
      this.scope = scope || this.scope;

      if (typeof method === 'object') {
        $.extend(true, this.settings, method);
      }

      if (typeof method != 'string') {
        if (Modernizr.touch) {
          $(this.scope)
            .on('click.fndtn.tooltip touchstart.fndtn.tooltip touchend.fndtn.tooltip', '[data-tooltip]', function (e) {
              e.preventDefault();
              $(self.settings.tooltipClass).hide();
              self.showOrCreateTip($(this));
            })
            .on('click.fndtn.tooltip touchstart.fndtn.tooltip touchend.fndtn.tooltip', this.settings.tooltipClass, function (e) {
              e.preventDefault();
              $(this).fadeOut(150);
            });
        } else {
          $(this.scope)
            .on('mouseenter.fndtn.tooltip mouseleave.fndtn.tooltip', '[data-tooltip]', function (e) {
              var $this = $(this);

              if (e.type === 'mouseover' || e.type === 'mouseenter') {
                self.showOrCreateTip($this);
              } else if (e.type === 'mouseout' || e.type === 'mouseleave') {
                self.hide($this);
              }
            });
        }

        // $(this.scope).data('fndtn-tooltips', true);
      } else {
        return this[method].call(this, options);
      }

    },

    showOrCreateTip : function ($target) {
      var $tip = this.getTip($target);

      if ($tip && $tip.length > 0) {
        return this.show($target);
      }

      return this.create($target);
    },

    getTip : function ($target) {
      var selector = this.selector($target),
          tip = null;

      if (selector) {
        tip = $('span[data-selector=' + selector + ']' + this.settings.tooltipClass);
      }

      return (typeof tip === 'object') ? tip : false;
    },

    selector : function ($target) {
      var id = $target.attr('id'),
          dataSelector = $target.attr('data-tooltip') || $target.attr('data-selector');

      if ((id && id.length < 1 || !id) && typeof dataSelector != 'string') {
        dataSelector = 'tooltip' + Math.random().toString(36).substring(7);
        $target.attr('data-selector', dataSelector);
      }

      return (id && id.length > 0) ? id : dataSelector;
    },

    create : function ($target) {
      var $tip = $(this.settings.tipTemplate(this.selector($target), $('
').html($target.attr('title')).html())),
          classes = this.inheritable_classes($target);

      $tip.addClass(classes).appendTo('body');
      if (Modernizr.touch) {
        $tip.append('tap to close ');
      }
      $target.removeAttr('title');
      this.show($target);
    },

    reposition : function (target, tip, classes) {
      var width, nub, nubHeight, nubWidth, column, objPos;

      tip.css('visibility', 'hidden').show();

      width = target.data('width');
      nub = tip.children('.nub');
      nubHeight = nub.outerHeight();
      nubWidth = nub.outerWidth();

      objPos = function (obj, top, right, bottom, left, width) {
        return obj.css({
          'top' : (top) ? top : 'auto',
          'bottom' : (bottom) ? bottom : 'auto',
          'left' : (left) ? left : 'auto',
          'right' : (right) ? right : 'auto',
          'width' : (width) ? width : 'auto'
        }).end();
      };

      objPos(tip, (target.offset().top + target.outerHeight() + 10), 'auto', 'auto', target.offset().left, width);

      if ($(window).width() < 767) {
        objPos(tip, (target.offset().top + target.outerHeight() + 10), 'auto', 'auto', 12.5, $(this.scope).width());
        tip.addClass('tip-override');
        objPos(nub, -nubHeight, 'auto', 'auto', target.offset().left);
      } else {
        objPos(tip, (target.offset().top + target.outerHeight() + 10), 'auto', 'auto', target.offset().left, width);
        tip.removeClass('tip-override');
        if (classes && classes.indexOf('tip-top') > -1) {
          objPos(tip, (target.offset().top - tip.outerHeight()), 'auto', 'auto', target.offset().left, width)
            .removeClass('tip-override');
          // objPos(nub, 'auto', 'auto', -nubHeight, 'auto');
        } else if (classes && classes.indexOf('tip-left') > -1) {
          objPos(tip, (target.offset().top + (target.outerHeight() / 2) - nubHeight*1.5), 'auto', 'auto', (target.offset().left - tip.outerWidth()), width)
            .removeClass('tip-override');
          // objPos(nub, (tip.outerHeight() / 2) - (nubHeight / 2), -(nubHeight / 2));
        } else if (classes && classes.indexOf('tip-right') > -1) {
          objPos(tip, (target.offset().top + (target.outerHeight() / 2) - nubHeight*1.5), 'auto', 'auto', (target.offset().left + target.outerWidth() + 10), width)
            .removeClass('tip-override');
          // objPos(nub, (tip.outerHeight() / 2) - (nubHeight / 2), 'auto', 'auto', -(nubHeight / 2));
        }
      }

      tip.css('visibility', 'visible').hide();
    },

    inheritable_classes : function (target) {
      var inheritables = ['tip-top', 'tip-left', 'tip-bottom', 'tip-right', 'noradius'].concat(this.settings.additionalInheritableClasses),
          classes = target.attr('class'),
          filtered = classes ? $.map(classes.split(' '), function (el, i) {
            if ($.inArray(el, inheritables) !== -1) {
              return el;
            }
          }).join(' ') : '';

      return $.trim(filtered);
    },

    show : function ($target) {
      var $tip = this.getTip($target);

      this.reposition($target, $tip, $target.attr('class'));
      $tip.fadeIn(150);
    },

    hide : function ($target) {
      var $tip = this.getTip($target);

      $tip.fadeOut(150);
    },

    // deprecate reload
    reload : function () {
      var $self = $(this);

      return ($self.data('fndtn-tooltips')) ? $self.foundationTooltips('destroy').foundationTooltips('init') : $self.foundationTooltips('init');
    },

    off : function () {
      $(this.scope).off('.fndtn.tooltip');
      $(this.scope).data('fndtn-tooltips', false);
      $(this.settings.tooltipClass).each(function (i) {
        $('[data-tooltip]').get(i).attr('title', $(this).text());
      }).remove();
    }
  };
}(Foundation.zj, this, this.document));
<commit_msg>Fix tooltip on IE9 where native tooltip shows in addition to custom.<commit_after>/*jslint unparam: true, browser: true, indent: 2 */

;(function ($, window, document, undefined) {
  'use strict';

  Foundation.libs.tooltips = {
    name: 'tooltips',

    version : '4.0.0.alpha',

    settings : {
      bodyHeight : 0,
      selector : '.has-tip',
      additionalInheritableClasses : [],
      tooltipClass : '.tooltip',
      tipTemplate : function (selector, content) {
        return '' + content + '';
      }
    },

    cache : {},

    init : function (scope, method, options) {
      var self = this;
      this.scope = scope || this.scope;

      if (typeof method === 'object') {
        $.extend(true, this.settings, method);
      }

      if (typeof method != 'string') {
        if (Modernizr.touch) {
          $(this.scope)
            .on('click.fndtn.tooltip touchstart.fndtn.tooltip touchend.fndtn.tooltip',
              '[data-tooltip]', function (e) {
              e.preventDefault();
              $(self.settings.tooltipClass).hide();
              self.showOrCreateTip($(this));
            })
            .on('click.fndtn.tooltip touchstart.fndtn.tooltip touchend.fndtn.tooltip',
              this.settings.tooltipClass, function (e) {
              e.preventDefault();
              $(this).fadeOut(150);
            });
        } else {
          $(this.scope)
            .on('mouseenter.fndtn.tooltip mouseleave.fndtn.tooltip',
              '[data-tooltip]', function (e) {
              var $this = $(this);

              if (e.type === 'mouseover' || e.type === 'mouseenter') {
                self.showOrCreateTip($this);
              } else if (e.type === 'mouseout' || e.type === 'mouseleave') {
                self.hide($this);
              }
            });
        }

        // $(this.scope).data('fndtn-tooltips', true);
      } else {
        return this[method].call(this, options);
      }

    },

    showOrCreateTip : function ($target) {
      var $tip = this.getTip($target);

      if ($tip && $tip.length > 0) {
        return this.show($target);
      }

      return this.create($target);
    },

    getTip : function ($target) {
      var selector = this.selector($target),
          tip = null;

      if (selector) {
        tip = $('span[data-selector=' + selector + ']' + this.settings.tooltipClass);
      }

      return (typeof tip === 'object') ? tip : false;
    },

    selector : function ($target) {
      var id = $target.attr('id'),
          dataSelector = $target.attr('data-tooltip') || $target.attr('data-selector');

      if ((id && id.length < 1 || !id) && typeof dataSelector != 'string') {
        dataSelector = 'tooltip' + Math.random().toString(36).substring(7);
        $target.attr('data-selector', dataSelector);
      }

      return (id && id.length > 0) ? id : dataSelector;
    },

    create : function ($target) {
      var $tip = $(this.settings.tipTemplate(this.selector($target), $('
').html($target.attr('title')).html())),
          classes = this.inheritable_classes($target);

      $tip.addClass(classes).appendTo('body');
      if (Modernizr.touch) {
        $tip.append('tap to close ');
      }
      $target.attr('title', '');
      this.show($target);
    },

    reposition : function (target, tip, classes) {
      var width, nub, nubHeight, nubWidth, column, objPos;

      tip.css('visibility', 'hidden').show();

      width = target.data('width');
      nub = tip.children('.nub');
      nubHeight = nub.outerHeight();
      nubWidth = nub.outerWidth();

      objPos = function (obj, top, right, bottom, left, width) {
        return obj.css({
          'top' : (top) ? top : 'auto',
          'bottom' : (bottom) ? bottom : 'auto',
          'left' : (left) ? left : 'auto',
          'right' : (right) ? right : 'auto',
          'width' : (width) ? width : 'auto'
        }).end();
      };

      objPos(tip, (target.offset().top + target.outerHeight() + 10), 'auto', 'auto', target.offset().left, width);

      if ($(window).width() < 767) {
        objPos(tip, (target.offset().top + target.outerHeight() + 10), 'auto', 'auto', 12.5, $(this.scope).width());
        tip.addClass('tip-override');
        objPos(nub, -nubHeight, 'auto', 'auto', target.offset().left);
      } else {
        objPos(tip, (target.offset().top + target.outerHeight() + 10), 'auto', 'auto', target.offset().left, width);
        tip.removeClass('tip-override');
        if (classes && classes.indexOf('tip-top') > -1) {
          objPos(tip, (target.offset().top - tip.outerHeight()), 'auto', 'auto', target.offset().left, width)
            .removeClass('tip-override');
          // objPos(nub, 'auto', 'auto', -nubHeight, 'auto');
        } else if (classes && classes.indexOf('tip-left') > -1) {
          objPos(tip, (target.offset().top + (target.outerHeight() / 2) - nubHeight*1.5), 'auto', 'auto', (target.offset().left - tip.outerWidth()), width)
            .removeClass('tip-override');
          // objPos(nub, (tip.outerHeight() / 2) - (nubHeight / 2), -(nubHeight / 2));
        } else if (classes && classes.indexOf('tip-right') > -1) {
          objPos(tip, (target.offset().top + (target.outerHeight() / 2) - nubHeight*1.5), 'auto', 'auto', (target.offset().left + target.outerWidth() + 10), width)
            .removeClass('tip-override');
          // objPos(nub, (tip.outerHeight() / 2) - (nubHeight / 2), 'auto', 'auto', -(nubHeight / 2));
        }
      }

      tip.css('visibility', 'visible').hide();
    },

    inheritable_classes : function (target) {
      var inheritables = ['tip-top', 'tip-left', 'tip-bottom', 'tip-right', 'noradius'].concat(this.settings.additionalInheritableClasses),
          classes = target.attr('class'),
          filtered = classes ? $.map(classes.split(' '), function (el, i) {
            if ($.inArray(el, inheritables) !== -1) {
              return el;
            }
          }).join(' ') : '';

      return $.trim(filtered);
    },

    show : function ($target) {
      var $tip = this.getTip($target);

      this.reposition($target, $tip, $target.attr('class'));
      $tip.fadeIn(150);
    },

    hide : function ($target) {
      var $tip = this.getTip($target);

      $tip.fadeOut(150);
    },

    // deprecate reload
    reload : function () {
      var $self = $(this);

      return ($self.data('fndtn-tooltips')) ? $self.foundationTooltips('destroy').foundationTooltips('init') : $self.foundationTooltips('init');
    },

    off : function () {
      $(this.scope).off('.fndtn.tooltip');
      $(this.scope).data('fndtn-tooltips', false);
      $(this.settings.tooltipClass).each(function (i) {
        $('[data-tooltip]').get(i).attr('title', $(this).text());
      }).remove();
    }
  };
}(Foundation.zj, this, this.document));
<|endoftext|>


<commit_before>/*jslint unparam: true, browser: true, indent: 2 */

;(function ($, window, document, undefined) {
  'use strict';

  Foundation.libs.tooltips = {
    name : 'tooltips',

    version : '4.2.2',

    settings : {
      // selector : '.has-tip',
      additional_inheritable_classes : [],
      tooltip_class : '.tooltip',
      append_to: 'body',
      disable_for_touch: false,
      tip_template : function (selector, content) {
        return '' + content + '';
      }
    },

    cache : {},

    init : function (scope, method, options) {
      Foundation.inherit(this, 'data_options');
      var self = this;

      if (typeof method === 'object') {
        $.extend(true, this.settings, method);
      } else if (typeof options !== 'undefined') {
        $.extend(true, this.settings, options);
      }

      if (typeof method !== 'string') {
        if (Modernizr.touch) {
          $(this.scope)
            .on('click.fndtn.tooltip touchstart.fndtn.tooltip touchend.fndtn.tooltip',
              '[data-tooltip]', function (e) {
              var settings = $.extend({}, self.settings, self.data_options($(this)));
              if (!settings.disable_for_touch) {
                e.preventDefault();
                $(settings.tooltip_class).hide();
                self.showOrCreateTip($(this));
              }
            })
            .on('click.fndtn.tooltip touchstart.fndtn.tooltip touchend.fndtn.tooltip',
              this.settings.tooltip_class, function (e) {
              e.preventDefault();
              $(this).fadeOut(150);
            });
        } else {
          $(this.scope)
            .on('mouseenter.fndtn.tooltip mouseleave.fndtn.tooltip',
              '[data-tooltip]', function (e) {
              var $this = $(this);

              if (/enter|over/i.test(e.type)) {
                self.showOrCreateTip($this);
              } else if (e.type === 'mouseout' || e.type === 'mouseleave') {
                self.hide($this);
              }
            });
        }

        // $(this.scope).data('fndtn-tooltips', true);
      } else {
        return this[method].call(this, options);
      }

    },

    showOrCreateTip : function ($target) {
      var $tip = this.getTip($target);

      if ($tip && $tip.length > 0) {
        return this.show($target);
      }

      return this.create($target);
    },

    getTip : function ($target) {
      var selector = this.selector($target),
          tip = null;

      if (selector) {
        tip = $('span[data-selector="' + selector + '"]' + this.settings.tooltip_class);
      }

      return (typeof tip === 'object') ? tip : false;
    },

    selector : function ($target) {
      var id = $target.attr('id'),
          dataSelector = $target.attr('data-tooltip') || $target.attr('data-selector');

      if ((id && id.length < 1 || !id) && typeof dataSelector != 'string') {
        dataSelector = 'tooltip' + Math.random().toString(36).substring(7);
        $target.attr('data-selector', dataSelector);
      }

      return (id && id.length > 0) ? id : dataSelector;
    },

    create : function ($target) {
      var $tip = $(this.settings.tip_template(this.selector($target), $('

').html($target.attr('title')).html())),
          classes = this.inheritable_classes($target);

      $tip.addClass(classes).appendTo(this.settings.append_to);
      if (Modernizr.touch) {
        $tip.append('tap to close ');
      }
      $target.removeAttr('title').attr('title','');
      this.show($target);
    },

    reposition : function (target, tip, classes) {
      var width, nub, nubHeight, nubWidth, column, objPos;

      tip.css('visibility', 'hidden').show();

      width = target.data('width');
      nub = tip.children('.nub');
      nubHeight = nub.outerHeight();
      nubWidth = nub.outerHeight();

      objPos = function (obj, top, right, bottom, left, width) {
        return obj.css({
          'top' : (top) ? top : 'auto',
          'bottom' : (bottom) ? bottom : 'auto',
          'left' : (left) ? left : 'auto',
          'right' : (right) ? right : 'auto',
          'width' : (width) ? width : 'auto'
        }).end();
      };

      objPos(tip, (target.offset().top + target.outerHeight() + 10), 'auto', 'auto', target.offset().left, width);

      if ($(window).width() < 767) {
        objPos(tip, (target.offset().top + target.outerHeight() + 10), 'auto', 'auto', 12.5, $(this.scope).width());
        tip.addClass('tip-override');
        objPos(nub, -nubHeight, 'auto', 'auto', target.offset().left);
      } else {
        var left = target.offset().left;
        if (Foundation.rtl) {
          left = target.offset().left + target.offset().width - tip.outerWidth();
        }
        objPos(tip, (target.offset().top + target.outerHeight() + 10), 'auto', 'auto', left, width);
        tip.removeClass('tip-override');
        if (classes && classes.indexOf('tip-top') > -1) {
          objPos(tip, (target.offset().top - tip.outerHeight()), 'auto', 'auto', left, width)
            .removeClass('tip-override');
        } else if (classes && classes.indexOf('tip-left') > -1) {
          objPos(tip, (target.offset().top + (target.outerHeight() / 2) - nubHeight*2.5), 'auto', 'auto', (target.offset().left - tip.outerWidth() - nubHeight), width)
            .removeClass('tip-override');
        } else if (classes && classes.indexOf('tip-right') > -1) {
          objPos(tip, (target.offset().top + (target.outerHeight() / 2) - nubHeight*2.5), 'auto', 'auto', (target.offset().left + target.outerWidth() + nubHeight), width)
            .removeClass('tip-override');
        }
      }

      tip.css('visibility', 'visible').hide();
    },

    inheritable_classes : function (target) {
      var inheritables = ['tip-top', 'tip-left', 'tip-bottom', 'tip-right', 'noradius'].concat(this.settings.additional_inheritable_classes),
          classes = target.attr('class'),
          filtered = classes ? $.map(classes.split(' '), function (el, i) {
            if ($.inArray(el, inheritables) !== -1) {
              return el;
            }
          }).join(' ') : '';

      return $.trim(filtered);
    },

    show : function ($target) {
      var $tip = this.getTip($target);

      this.reposition($target, $tip, $target.attr('class'));
      $tip.fadeIn(150);
    },

    hide : function ($target) {
      var $tip = this.getTip($target);

      $tip.fadeOut(150);
    },

    // deprecate reload
    reload : function () {
      var $self = $(this);

      return ($self.data('fndtn-tooltips')) ? $self.foundationTooltips('destroy').foundationTooltips('init') : $self.foundationTooltips('init');
    },

    off : function () {
      $(this.scope).off('.fndtn.tooltip');
      $(this.settings.tooltip_class).each(function (i) {
        $('[data-tooltip]').get(i).attr('title', $(this).text());
      }).remove();
    },

    reflow : function () {}
  };
}(jQuery, this, this.document));<commit_msg>added option to personalize the tooltip text "tap to close", so now we can translate to other languages.<commit_after>/*jslint unparam: true, browser: true, indent: 2 */

;(function ($, window, document, undefined) {
  'use strict';

  Foundation.libs.tooltips = {
    name : 'tooltips',

    version : '4.2.2',

    settings : {
      // selector : '.has-tip',
      additional_inheritable_classes : [],
      tooltip_class : '.tooltip',
      append_to: 'body',
      disable_for_touch: false,
      tip_template : function (selector, content) {
        return '' + content + '';
      }
    },

    cache : {},

    init : function (scope, method, options) {
      Foundation.inherit(this, 'data_options');
      var self = this;

      if (typeof method === 'object') {
        $.extend(true, this.settings, method);
      } else if (typeof options !== 'undefined') {
        $.extend(true, this.settings, options);
      }

      if (typeof method !== 'string') {
        if (Modernizr.touch) {
          $(this.scope)
            .on('click.fndtn.tooltip touchstart.fndtn.tooltip touchend.fndtn.tooltip',
              '[data-tooltip]', function (e) {
              var settings = $.extend({}, self.settings, self.data_options($(this)));
              if (!settings.disable_for_touch) {
                e.preventDefault();
                $(settings.tooltip_class).hide();
                self.showOrCreateTip($(this));
              }
            })
            .on('click.fndtn.tooltip touchstart.fndtn.tooltip touchend.fndtn.tooltip',
              this.settings.tooltip_class, function (e) {
              e.preventDefault();
              $(this).fadeOut(150);
            });
        } else {
          $(this.scope)
            .on('mouseenter.fndtn.tooltip mouseleave.fndtn.tooltip',
              '[data-tooltip]', function (e) {
              var $this = $(this);

              if (/enter|over/i.test(e.type)) {
                self.showOrCreateTip($this);
              } else if (e.type === 'mouseout' || e.type === 'mouseleave') {
                self.hide($this);
              }
            });
        }

        // $(this.scope).data('fndtn-tooltips', true);
      } else {
        return this[method].call(this, options);
      }

    },

    showOrCreateTip : function ($target) {
      var $tip = this.getTip($target);

      if ($tip && $tip.length > 0) {
        return this.show($target);
      }

      return this.create($target);
    },

    getTip : function ($target) {
      var selector = this.selector($target),
          tip = null;

      if (selector) {
        tip = $('span[data-selector="' + selector + '"]' + this.settings.tooltip_class);
      }

      return (typeof tip === 'object') ? tip : false;
    },

    selector : function ($target) {
      var id = $target.attr('id'),
          dataSelector = $target.attr('data-tooltip') || $target.attr('data-selector');

      if ((id && id.length < 1 || !id) && typeof dataSelector != 'string') {
        dataSelector = 'tooltip' + Math.random().toString(36).substring(7);
        $target.attr('data-selector', dataSelector);
      }

      return (id && id.length > 0) ? id : dataSelector;
    },

    create : function ($target) {
      var $tip = $(this.settings.tip_template(this.selector($target), $('

').html($target.attr('title')).html())),
          classes = this.inheritable_classes($target);

      $tip.addClass(classes).appendTo(this.settings.append_to);
      if (Modernizr.touch) {
        $tip.append(''+this.settings.tapToClose_text+'');
      }
      $target.removeAttr('title').attr('title','');
      this.show($target);
    },

    reposition : function (target, tip, classes) {
      var width, nub, nubHeight, nubWidth, column, objPos;

      tip.css('visibility', 'hidden').show();

      width = target.data('width');
      nub = tip.children('.nub');
      nubHeight = nub.outerHeight();
      nubWidth = nub.outerHeight();

      objPos = function (obj, top, right, bottom, left, width) {
        return obj.css({
          'top' : (top) ? top : 'auto',
          'bottom' : (bottom) ? bottom : 'auto',
          'left' : (left) ? left : 'auto',
          'right' : (right) ? right : 'auto',
          'width' : (width) ? width : 'auto'
        }).end();
      };

      objPos(tip, (target.offset().top + target.outerHeight() + 10), 'auto', 'auto', target.offset().left, width);

      if ($(window).width() < 767) {
        objPos(tip, (target.offset().top + target.outerHeight() + 10), 'auto', 'auto', 12.5, $(this.scope).width());
        tip.addClass('tip-override');
        objPos(nub, -nubHeight, 'auto', 'auto', target.offset().left);
      } else {
        var left = target.offset().left;
        if (Foundation.rtl) {
          left = target.offset().left + target.offset().width - tip.outerWidth();
        }
        objPos(tip, (target.offset().top + target.outerHeight() + 10), 'auto', 'auto', left, width);
        tip.removeClass('tip-override');
        if (classes && classes.indexOf('tip-top') > -1) {
          objPos(tip, (target.offset().top - tip.outerHeight()), 'auto', 'auto', left, width)
            .removeClass('tip-override');
        } else if (classes && classes.indexOf('tip-left') > -1) {
          objPos(tip, (target.offset().top + (target.outerHeight() / 2) - nubHeight*2.5), 'auto', 'auto', (target.offset().left - tip.outerWidth() - nubHeight), width)
            .removeClass('tip-override');
        } else if (classes && classes.indexOf('tip-right') > -1) {
          objPos(tip, (target.offset().top + (target.outerHeight() / 2) - nubHeight*2.5), 'auto', 'auto', (target.offset().left + target.outerWidth() + nubHeight), width)
            .removeClass('tip-override');
        }
      }

      tip.css('visibility', 'visible').hide();
    },

    inheritable_classes : function (target) {
      var inheritables = ['tip-top', 'tip-left', 'tip-bottom', 'tip-right', 'noradius'].concat(this.settings.additional_inheritable_classes),
          classes = target.attr('class'),
          filtered = classes ? $.map(classes.split(' '), function (el, i) {
            if ($.inArray(el, inheritables) !== -1) {
              return el;
            }
          }).join(' ') : '';

      return $.trim(filtered);
    },

    show : function ($target) {
      var $tip = this.getTip($target);

      this.reposition($target, $tip, $target.attr('class'));
      $tip.fadeIn(150);
    },

    hide : function ($target) {
      var $tip = this.getTip($target);

      $tip.fadeOut(150);
    },

    // deprecate reload
    reload : function () {
      var $self = $(this);

      return ($self.data('fndtn-tooltips')) ? $self.foundationTooltips('destroy').foundationTooltips('init') : $self.foundationTooltips('init');
    },

    off : function () {
      $(this.scope).off('.fndtn.tooltip');
      $(this.settings.tooltip_class).each(function (i) {
        $('[data-tooltip]').get(i).attr('title', $(this).text());
      }).remove();
    },

    reflow : function () {}
  };
}(jQuery, this, this.document));
<|endoftext|>