<commit_before>//////////////////
// Link Helpers //
//////////////////

/**
 * @summary Return a post's link if it has one, else return its post page URL
 * @param {Object} post
 */
Posts.getLink = function (post, isAbsolute) {
  return !!post.url ? Telescope.utils.getOutgoingUrl(post.url) : this.getPageUrl(post, isAbsolute);
};
Posts.helpers({getLink: function (isAbsolute) {return Posts.getLink(this, isAbsolute);}});

/**
 * @summary Depending on the settings, return either a post's URL link (if it has one) or its page URL.
 * @param {Object} post
 */
Posts.getShareableLink = function (post) {
  return Telescope.settings.get("outsideLinksPointTo", "link") === "link" ? Posts.getLink(post) : Posts.getPageUrl(post, true);
};
Posts.helpers({getShareableLink: function () {return Posts.getShareableLink(this);}});

/**
 * @summary Whether a post's link should open in a new tab or not
 * @param {Object} post
 */
Posts.getLinkTarget = function (post) {
  return !!post.url ? "_blank" : "";
};
Posts.helpers({getLinkTarget: function () {return Posts.getLinkTarget(this);}});

/**
 * @summary Get URL of a post page.
 * @param {Object} post
 */
Posts.getPageUrl = function(post, isAbsolute){
  var isAbsolute = typeof isAbsolute === "undefined" ? false : isAbsolute; // default to false
  var prefix = isAbsolute ? Telescope.utils.getSiteUrl().slice(0,-1) : "";
  return prefix + FlowRouter.path("posts.single", post);
};
Posts.helpers({getPageUrl: function (isAbsolute) {return Posts.getPageUrl(this, isAbsolute);}});

/**
 * @summary Get post edit page URL.
 * @param {String} id
 */
Posts.getEditUrl = function(post, isAbsolute){
  var isAbsolute = typeof isAbsolute === "undefined" ? false : isAbsolute; // default to false
  var prefix = isAbsolute ? Telescope.utils.getSiteUrl().slice(0,-1) : "";
  return prefix + FlowRouter.path("posts.edit", post);
};
Posts.helpers({getEditUrl: function (isAbsolute) {return Posts.getEditUrl(this, isAbsolute);}});

///////////////////
// Other Helpers //
///////////////////

/**
 * @summary Get a post author's name
 * @param {Object} post
 */
Posts.getAuthorName = function (post) {
  var user = Meteor.users.findOne(post.userId);
  if (user) {
    return user.getDisplayName();
  } else {
    return post.author;
  }
};
Posts.helpers({getAuthorName: function () {return Posts.getAuthorName(this);}});

/**
 * @summary Get default status for new posts.
 * @param {Object} user
 */
Posts.getDefaultStatus = function (user) {
  var hasAdminRights = typeof user === 'undefined' ? false : Users.is.admin(user);
  if (hasAdminRights || !Telescope.settings.get('requirePostsApproval', false)) {
    // if user is admin, or else post approval is not required
    return Posts.config.STATUS_APPROVED;
  } else {
    return Posts.config.STATUS_PENDING;
  }
};

/**
 * @summary Check if a post is approved
 * @param {Object} post
 */
Posts.isApproved = function (post) {
  return post.status === Posts.config.STATUS_APPROVED;
};
Posts.helpers({isApproved: function () {return Posts.isApproved(this);}});

/**
 * @summary Check to see if post URL is unique.
 * We need the current user so we know who to upvote the existing post as.
 * @param {String} url
 */
Posts.checkForSameUrl = function (url) {

  // check that there are no previous posts with the same link in the past 6 months
  var sixMonthsAgo = moment().subtract(6, 'months').toDate();
  var postWithSameLink = Posts.findOne({url: url, postedAt: {$gte: sixMonthsAgo}});

  if (typeof postWithSameLink !== 'undefined') {
    throw new Meteor.Error('603', __('this_link_has_already_been_posted'), postWithSameLink._id);
  }
};

/**
 * @summary When on a post page, return the current post
 */
Posts.current = function () {
  return Posts.findOne(FlowRouter.getParam("_id"));
};

/**
 * @summary Check to see if a post is a link to a video
 * @param {Object} post
 */
Posts.isVideo = function (post) {
  return post.media && post.media.type === "video";
};
Posts.helpers({isVideo: function () {return Posts.isVideo(this);}});

Posts.getNotificationProperties = function (post) {
  var postAuthor = Meteor.users.findOne(post.userId);
  var properties = {
    postAuthorName : Posts.getAuthorName(post),
    postTitle : Telescope.utils.cleanUp(post.title),
    profileUrl: Users.getProfileUrl(postAuthor, true),
    postUrl: Posts.getPageUrl(post, true),
    thumbnailUrl: post.thumbnailUrl,
    linkUrl: !!post.url ? Telescope.utils.getOutgoingUrl(post.url) : Posts.getPageUrl(post, true)
  };

  if(post.url)
    properties.url = post.url;

  if(post.htmlBody)
    properties.htmlBody = post.htmlBody;

  return properties;
};

Posts.getThumbnailUrl = (post) => {
  const thumbnailUrl = post.thumbnailUrl;
  if (!!thumbnailUrl) {
    const prefix = Telescope.utils.getSiteUrl().slice(0,-1);
    // the thumbnail may be hosted on another website
    return thumbnailUrl.indexOf('://') > -1 ? thumbnailUrl : prefix + thumbnailUrl;
  }
};
Posts.helpers({ getThumbnailUrl() { return Posts.getThumbnailUrl(this); } });<commit_msg>handle thumbnails from embedly, an external website or hosted on the app<commit_after>//////////////////
// Link Helpers //
//////////////////

/**
 * @summary Return a post's link if it has one, else return its post page URL
 * @param {Object} post
 */
Posts.getLink = function (post, isAbsolute) {
  return !!post.url ? Telescope.utils.getOutgoingUrl(post.url) : this.getPageUrl(post, isAbsolute);
};
Posts.helpers({getLink: function (isAbsolute) {return Posts.getLink(this, isAbsolute);}});

/**
 * @summary Depending on the settings, return either a post's URL link (if it has one) or its page URL.
 * @param {Object} post
 */
Posts.getShareableLink = function (post) {
  return Telescope.settings.get("outsideLinksPointTo", "link") === "link" ? Posts.getLink(post) : Posts.getPageUrl(post, true);
};
Posts.helpers({getShareableLink: function () {return Posts.getShareableLink(this);}});

/**
 * @summary Whether a post's link should open in a new tab or not
 * @param {Object} post
 */
Posts.getLinkTarget = function (post) {
  return !!post.url ? "_blank" : "";
};
Posts.helpers({getLinkTarget: function () {return Posts.getLinkTarget(this);}});

/**
 * @summary Get URL of a post page.
 * @param {Object} post
 */
Posts.getPageUrl = function(post, isAbsolute){
  var isAbsolute = typeof isAbsolute === "undefined" ? false : isAbsolute; // default to false
  var prefix = isAbsolute ? Telescope.utils.getSiteUrl().slice(0,-1) : "";
  return prefix + FlowRouter.path("posts.single", post);
};
Posts.helpers({getPageUrl: function (isAbsolute) {return Posts.getPageUrl(this, isAbsolute);}});

/**
 * @summary Get post edit page URL.
 * @param {String} id
 */
Posts.getEditUrl = function(post, isAbsolute){
  var isAbsolute = typeof isAbsolute === "undefined" ? false : isAbsolute; // default to false
  var prefix = isAbsolute ? Telescope.utils.getSiteUrl().slice(0,-1) : "";
  return prefix + FlowRouter.path("posts.edit", post);
};
Posts.helpers({getEditUrl: function (isAbsolute) {return Posts.getEditUrl(this, isAbsolute);}});

///////////////////
// Other Helpers //
///////////////////

/**
 * @summary Get a post author's name
 * @param {Object} post
 */
Posts.getAuthorName = function (post) {
  var user = Meteor.users.findOne(post.userId);
  if (user) {
    return user.getDisplayName();
  } else {
    return post.author;
  }
};
Posts.helpers({getAuthorName: function () {return Posts.getAuthorName(this);}});

/**
 * @summary Get default status for new posts.
 * @param {Object} user
 */
Posts.getDefaultStatus = function (user) {
  var hasAdminRights = typeof user === 'undefined' ? false : Users.is.admin(user);
  if (hasAdminRights || !Telescope.settings.get('requirePostsApproval', false)) {
    // if user is admin, or else post approval is not required
    return Posts.config.STATUS_APPROVED;
  } else {
    return Posts.config.STATUS_PENDING;
  }
};

/**
 * @summary Check if a post is approved
 * @param {Object} post
 */
Posts.isApproved = function (post) {
  return post.status === Posts.config.STATUS_APPROVED;
};
Posts.helpers({isApproved: function () {return Posts.isApproved(this);}});

/**
 * @summary Check to see if post URL is unique.
 * We need the current user so we know who to upvote the existing post as.
 * @param {String} url
 */
Posts.checkForSameUrl = function (url) {

  // check that there are no previous posts with the same link in the past 6 months
  var sixMonthsAgo = moment().subtract(6, 'months').toDate();
  var postWithSameLink = Posts.findOne({url: url, postedAt: {$gte: sixMonthsAgo}});

  if (typeof postWithSameLink !== 'undefined') {
    throw new Meteor.Error('603', __('this_link_has_already_been_posted'), postWithSameLink._id);
  }
};

/**
 * @summary When on a post page, return the current post
 */
Posts.current = function () {
  return Posts.findOne(FlowRouter.getParam("_id"));
};

/**
 * @summary Check to see if a post is a link to a video
 * @param {Object} post
 */
Posts.isVideo = function (post) {
  return post.media && post.media.type === "video";
};
Posts.helpers({isVideo: function () {return Posts.isVideo(this);}});

Posts.getNotificationProperties = function (post) {
  var postAuthor = Meteor.users.findOne(post.userId);
  var properties = {
    postAuthorName : Posts.getAuthorName(post),
    postTitle : Telescope.utils.cleanUp(post.title),
    profileUrl: Users.getProfileUrl(postAuthor, true),
    postUrl: Posts.getPageUrl(post, true),
    thumbnailUrl: post.thumbnailUrl,
    linkUrl: !!post.url ? Telescope.utils.getOutgoingUrl(post.url) : Posts.getPageUrl(post, true)
  };

  if(post.url)
    properties.url = post.url;

  if(post.htmlBody)
    properties.htmlBody = post.htmlBody;

  return properties;
};

/**
 * @summary Get the complete thumbnail url whether it is hosted on Embedly or on an external website, or locally in the app.
 * @param {Object} post
 */
Posts.getThumbnailUrl = (post) => {
  const thumbnailUrl = post.thumbnailUrl;
  if (!!thumbnailUrl) {
    return thumbnailUrl.indexOf('//') > -1 ? Telescope.utils.addHttp(thumbnailUrl) : Telescope.utils.getSiteUrl().slice(0,-1) + thumbnailUrl;
  }
};
Posts.helpers({ getThumbnailUrl() { return Posts.getThumbnailUrl(this); } });<|endoftext|>


<commit_before>function encrypt(text, pass) {
  //console.log('pass:' + pass + ' encrypt IN:' + text);
  var key = Sha256.hash(pass);
  var encrypted = Aes.Ctr.encrypt(text, key, 256);
  //console.log('encrypt OUT:' + encrypted);
  return encrypted;
}

function decrypt (text, pass) {
  //console.log('pass:' + pass + ' decrypt IN:' + text);
  var key = Sha256.hash(pass);
  var decrypted = Aes.Ctr.decrypt(text, key, 256);
  //console.log('decrypt OUT:' + decrypted);
  return decrypted;
}

function backToTop() {
  $("html, body").animate({ scrollTop: 0 }, "slow");
}

function passwordsMatch() {
  console.log("passwordsMatch()");

  if( $('#password').val() == $('#password2').val() ) {

    $('#passGroup').removeClass("has-error");
    $('#passwordError').addClass("hidden");

    return true;
  }

  $('#passGroup').addClass("has-error");
  $('#passwordError').removeClass("hidden");

  backToTop();

  return false;
}

function onMessageChange() {
    console.log("onMessageChange()");
    var m = $('#message');

    $("#count").text( m.val().length  );

    m.autosize({ append: '\n'});
    m.trigger('autosize.resize');
}

function messageUpdated() {
  $('#message').select();
  onMessageChange();
}

function clearMessage() {
  $('#message').val('');
  onMessageChange();
}

function pageEncrypt() {
  console.log("pageEncrypt()");
  if ( passwordsMatch() ) {
    $('#message').val( encrypt( $('#message').val(), $('#password').val() ) );
    messageUpdated();
  }
}

function pageDecrypt() {
  console.log("pageDecrypt()");
  if( passwordsMatch() ) {
    $('#message').val( decrypt( $('#message').val(), $('#password').val() ) );
    messageUpdated();
  }
}

$( function() {

  $("#message").change( onMessageChange );
  $("#message").keyup( onMessageChange );

  $('#encrypt').click( pageEncrypt );
  $('#decrypt').click( pageDecrypt );

  $('#backToTop').click( backToTop );
  $('#reset').click( clearMessage );

  onMessageChange();

  $('#splashscreen').delay( 1000 ).fadeOut('slow');

  dbChooseOptions = {
    success: function(files) {
      // name, link, bytes, icon, thumbnailLink
      $('#message').load( files[0].link, function () {
        onMessageChange();
      });
    },
    cancel: function() {

    },
    linkType: "direct", // or "direct"
    multiselect: false, // or true
    extensions: ['.md', '.txt', '.markdown', '.rsa'],
  };

  $('#dbChooseFile').click( function () {
    if( Dropbox.isBrowserSupported() )
      Dropbox.choose( dbChooseOptions );
  });

  console.log('Page loaded');
});
<commit_msg>Update app.js<commit_after>function encrypt(text, pass) {
  //console.log('pass:' + pass + ' encrypt IN:' + text);
  var key = Sha256.hash(pass);
  var encrypted = Aes.Ctr.encrypt(text, key, 256);
  //console.log('encrypt OUT:' + encrypted);
  return encrypted;
}

function decrypt (text, pass) {
  //console.log('pass:' + pass + ' decrypt IN:' + text);
  var key = Sha256.hash(pass);
  var decrypted = Aes.Ctr.decrypt(text, key, 256);
  //console.log('decrypt OUT:' + decrypted);
  return decrypted;
}

function backToTop() {
  $("html, body").animate({ scrollTop: 0 }, "slow");
}

function passwordsMatch() {
  console.log("passwordsMatch()");

  if( $('#password').val() == $('#password2').val() ) {

    $('#passGroup').removeClass("has-error");
    $('#passwordError').addClass("hidden");

    return true;
  }

  $('#passGroup').addClass("has-error");
  $('#passwordError').removeClass("hidden");

  backToTop();

  return false;
}

function onMessageChange() {
    console.log("onMessageChange()");
    var m = $('#message');

    $("#count").text( m.val().length  );

    m.autosize({ append: '\n'});
    m.trigger('autosize.resize');
}

function messageUpdated() {
  $('#message').select();
  onMessageChange();
}

function clearMessage() {
  $('#message').val('');
  onMessageChange();
}

function pageEncrypt() {
  console.log("pageEncrypt()");
  if ( passwordsMatch() ) {
    $('#message').val( encrypt( $('#message').val(), $('#password').val() ) );
    messageUpdated();
  }
}

function pageDecrypt() {
  console.log("pageDecrypt()");
  if( passwordsMatch() ) {
    $('#message').val( decrypt( $('#message').val(), $('#password').val() ) );
    messageUpdated();
  }
}

$( function() {

  $("#message").change( onMessageChange );
  $("#message").keyup( onMessageChange );

  $('#encrypt').click( pageEncrypt );
  $('#decrypt').click( pageDecrypt );

  $('#backToTop').click( backToTop );
  $('#reset').click( clearMessage );

  onMessageChange();

  $('#splashscreen').delay( 1000 ).fadeOut('slow');

  var client = new Dropbox.Client({ key: "5ecldearnclcmxv" });

  $('#dbChooseFile').click( function () {
    client.authenticate(function(error, client) {
      if (error) {
        alert( error );
        return;
      }

      var fn = prompt("File path");
      if(fn) {
        client.readFile(fn, function(error, data) {
          if (error) {
            return alert(error);
          }
          $('#message').val( data );
          onMessageChange();
        });
      }
    });
  });

/*

  dbChooseOptions = {
    success: function(files) {
      // name, link, bytes, icon, thumbnailLink
      $('#message').load( files[0].link, function () {
        onMessageChange();
      });
    },
    cancel: function() {

    },
    linkType: "direct", // or "direct"
    multiselect: false, // or true
    extensions: ['.md', '.txt', '.markdown', '.rsa'],
  };

  $('#dbChooseFile').click( function () {
    if( Dropbox.isBrowserSupported() )
      Dropbox.choose( dbChooseOptions );
  });
*/

  console.log('Page loaded');
});
<|endoftext|>


<commit_before>$.fn.random = function() {
  return this.eq(Math.floor(Math.random() * this.length));
}

Array.prototype.max = function() {
  return Math.max.apply(null, this);
};

$(document).ready(function() {
    "use strict";

    var $ = window.jQuery;
    window.sliMpd = $.extend(true, window.sliMpd, {
        modules : {},

        drawFaviconTimeout : 0,

        xwax : false,

        /**
		 * adds get-paramter to url, respecting existing and not-existing params
		 * TODO: currently not compatible with urlstring that contains a #hash
		 * @param {string} urlstring
		 * @param {string} paramName
		 * @param {string} paramValue
		 */
		setGetParameter : function(urlstring, paramName, paramValue) {
		    if (urlstring.indexOf(paramName + "=") >= 0) {
		        var prefix = urlstring.substring(0, urlstring.indexOf(paramName));
		        var suffix = urlstring.substring(urlstring.indexOf(paramName));
		        suffix = suffix.substring(suffix.indexOf("=") + 1);
		        suffix = (suffix.indexOf("&") >= 0) ? suffix.substring(suffix.indexOf("&")) : "";
		        urlstring = prefix + paramName + "=" + paramValue + suffix;
		    } else {
			    urlstring += (urlstring.indexOf("?") < 0)
			        ? "?" + paramName + "=" + paramValue
			    	: "&" + paramName + "=" + paramValue;
		    }
		    return urlstring;
		},

		drawFavicon : function() {
			clearTimeout(window.sliMpd.drawFaviconTimeout);
			window.sliMpd.currentPlayer.drawFavicon();
			window.sliMpd.drawFaviconTimeout = setTimeout(window.sliMpd.drawFavicon, 2000);
		},

		fireRequestAndNotify : function(url) {
			$.get(url).done(function(response) {
				window.sliMpd.checkNotify(response);
			});
		},

		checkNotify : function(endcodedResponse) {
			try {
	        	var notifyConf = JSON.parse(endcodedResponse);
	        	if (typeof notifyConf.notify !== 'undefined') {
	        		this.notify(notifyConf);
	        	}
		    } catch(e) {
		    	//console.log(e + ' no json response in SliMpd::checkNotify()');
			}
		},

		notify : function(notifyConf) {
    		$.notify({
				// options
				message: notifyConf.message
			},{
				// settings
				type: (notifyConf.type || 'info'),
				z_index: 10000,
				offset: {
					x: '10',
					y: '110'
				},
				placement: {
					from: "bottom",
					align: "right"
				},
			});
		},

		notifyError : function(errorUrl) {
    		this.notify({
				message : "
OOOPS!
 something went wrong...
" + errorUrl + "",
				type : "danger"
			});
		}
    });

    window.sliMpd.navbar = new window.sliMpd.modules.NavbarView({
    	el : 'nav.main-nav'
    });
    window.sliMpd.navbar.render();

    window.sliMpd.xwax = new window.sliMpd.modules.XwaxView({
		el : '.player-xwax',
		showWaveform : true
    });
    window.sliMpd.xwax.render();

	window.sliMpd.modal = new window.sliMpd.modules.ModalView({
    	el : '#global-modal .modal-content'
    });

    window.sliMpd.localPlayer = new window.sliMpd.modules.LocalPlayer({
    	el : '.permaplayer.player-local'
    });
    window.sliMpd.mpdPlayer = new window.sliMpd.modules.MpdPlayer({
    	el : '.permaplayer.player-mpd'
    });

    window.sliMpd.currentPlayer = ($.cookie("playerMode") === 'mpd')
		? window.sliMpd.mpdPlayer
    	: window.sliMpd.localPlayer;

    window.sliMpd.router = new window.sliMpd.modules.Router();

    window.Backbone.history.start({
    	pushState : true
    });

	window.sliMpd.drawFavicon();

	/* toggle between mpd-control and local player (jPlayer) */
	$('.playerModeToggle a').on('click', function(e) {
		e.preventDefault();
		if(window.sliMpd.currentPlayer.mode === 'mpd') {
			$(this).addClass('active-local').removeClass('active-mpd').html($(this).attr('data-label-local'));
			window.sliMpd.currentPlayer = window.sliMpd.localPlayer;
			window.sliMpd.mpdPlayer.pollWorker.postMessage({
				cmd: 'setMiliseconds',
				value: window.sliMpd.mpdPlayer.intervalInactive
			});
			$('body')
				.removeClass(window.sliMpd.conf.color.mpd.bodyclass)
				.addClass(window.sliMpd.conf.color.local.bodyclass);
		} else {
			$(this).addClass('active-mpd').removeClass('active-local').html($(this).attr('data-label-mpd'));
			// pause local player when switching to mpd
			window.sliMpd.currentPlayer.process({'action':'pause'});
			window.sliMpd.currentPlayer = window.sliMpd.mpdPlayer;
			window.sliMpd.mpdPlayer.pollWorker.postMessage({
				cmd: 'setMiliseconds',
				value: window.sliMpd.mpdPlayer.intervalActive
			});
			window.sliMpd.currentPlayer.refreshInterval();
			$('body')
				.removeClass(window.sliMpd.conf.color.local.bodyclass)
				.addClass(window.sliMpd.conf.color.mpd.bodyclass);
		}
		$.cookie("playerMode", window.sliMpd.currentPlayer.mode, { expires : 365, path: '/' });
		$('.player-local,.player-mpd').toggle();
		window.sliMpd.drawFavicon();
		window.sliMpd.currentPlayer.drawWaveform();
	});

	/* toggle playersize */
	$('.playerSizeToggle a').on('click', function(e) {
		e.preventDefault();
		$('body').toggleClass('slimplayer');
		$(this).find('i').toggleClass('fa-chevron-down').toggleClass('fa-chevron-up');
		window.sliMpd.currentPlayer.drawWaveform();
	});

	/* toggle between display tags and display filepath */
	$('.fileModeToggle a').on('click', function(e) {
		e.preventDefault();
		$('body').toggleClass('ffn');
		$(this).find('i').toggleClass('fa-toggle-off').toggleClass('fa-toggle-on');
	});

	// delegate calls to data-toggle="lightbox"
	$(document).delegate('*[data-toggle="lightbox"]', 'click', function(event) {
		event.preventDefault();
		return $(this).ekkoLightbox({
			always_show_close: true,
			gallery_parent_selector: 'body'
		});
	});

	$(document).on('keydown', null, 'ctrl+space', function(){
		// FIXME: this does not work with open autocomplete-widget. obviously ac overrides key bindings
		$('#mainsearch').focus().select();
		return false;
	});

	$('.navbar-upper').affix({
  		offset: {bottom: 200}
	});

	NProgress.configure({
		showSpinner: false,
		parent: '#nprog-container',
		speed: 100,
		trickleRate: 0.02,
		trickleSpeed: 800
	});

	// TODO: is it correct to place this here (excluded from all bootstrap-views)?
	$(function(){
		// Only enable if the document has a long scroll bar
		// Note the window height + offset
		if ( ($(window).height() + 100) < $(document).height() ) {
		    $('#top-link-block').removeClass('hidden').affix({
		        // how far to scroll down before link "slides" into view
		        offset: {top:100}
		    });
		}
	});
	$('#top-link-block a').on('click', function(e) {
		e.preventDefault();
		$('html,body').animate({scrollTop:0},'fast');
		return false;
	});

	/*
	 * force confirmation when user leaves sliMpd in case local audio is playing
	 */
	window.onbeforeunload=function(){
		if(window.sliMpd.currentPlayer.mode === 'local' && window.sliMpd.currentPlayer.nowPlayingState === 'play') {
			return 'local audio is currently playing';
		}
	}

	/*
	 * add lazy resize listener
	 */
	$(window).bind('resizeEnd', function() {
		window.sliMpd.currentPlayer.drawWaveform();
		window.sliMpd.currentPlayer.drawTimeGrid();
	});
	$(window).resize(function() {
		if(this.resizeTO) clearTimeout(this.resizeTO);
		this.resizeTO = setTimeout(function() {
			$(this).trigger('resizeEnd');
		}, 500);
	});
});

<commit_msg>fix functionality of to-top-link after navigating around<commit_after>$.fn.random = function() {
  return this.eq(Math.floor(Math.random() * this.length));
}

Array.prototype.max = function() {
  return Math.max.apply(null, this);
};

$(document).ready(function() {
    "use strict";

    var $ = window.jQuery;
    window.sliMpd = $.extend(true, window.sliMpd, {
        modules : {},

        drawFaviconTimeout : 0,

        xwax : false,

        /**
		 * adds get-paramter to url, respecting existing and not-existing params
		 * TODO: currently not compatible with urlstring that contains a #hash
		 * @param {string} urlstring
		 * @param {string} paramName
		 * @param {string} paramValue
		 */
		setGetParameter : function(urlstring, paramName, paramValue) {
		    if (urlstring.indexOf(paramName + "=") >= 0) {
		        var prefix = urlstring.substring(0, urlstring.indexOf(paramName));
		        var suffix = urlstring.substring(urlstring.indexOf(paramName));
		        suffix = suffix.substring(suffix.indexOf("=") + 1);
		        suffix = (suffix.indexOf("&") >= 0) ? suffix.substring(suffix.indexOf("&")) : "";
		        urlstring = prefix + paramName + "=" + paramValue + suffix;
		    } else {
			    urlstring += (urlstring.indexOf("?") < 0)
			        ? "?" + paramName + "=" + paramValue
			    	: "&" + paramName + "=" + paramValue;
		    }
		    return urlstring;
		},

		drawFavicon : function() {
			clearTimeout(window.sliMpd.drawFaviconTimeout);
			window.sliMpd.currentPlayer.drawFavicon();
			window.sliMpd.drawFaviconTimeout = setTimeout(window.sliMpd.drawFavicon, 2000);
		},

		fireRequestAndNotify : function(url) {
			$.get(url).done(function(response) {
				window.sliMpd.checkNotify(response);
			});
		},

		checkNotify : function(endcodedResponse) {
			try {
	        	var notifyConf = JSON.parse(endcodedResponse);
	        	if (typeof notifyConf.notify !== 'undefined') {
	        		this.notify(notifyConf);
	        	}
		    } catch(e) {
		    	//console.log(e + ' no json response in SliMpd::checkNotify()');
			}
		},

		notify : function(notifyConf) {
    		$.notify({
				// options
				message: notifyConf.message
			},{
				// settings
				type: (notifyConf.type || 'info'),
				z_index: 10000,
				offset: {
					x: '10',
					y: '110'
				},
				placement: {
					from: "bottom",
					align: "right"
				},
			});
		},

		notifyError : function(errorUrl) {
    		this.notify({
				message : "
OOOPS!
 something went wrong...
" + errorUrl + "",
				type : "danger"
			});
		}
    });

    window.sliMpd.navbar = new window.sliMpd.modules.NavbarView({
    	el : 'nav.main-nav'
    });
    window.sliMpd.navbar.render();

    window.sliMpd.xwax = new window.sliMpd.modules.XwaxView({
		el : '.player-xwax',
		showWaveform : true
    });
    window.sliMpd.xwax.render();

	window.sliMpd.modal = new window.sliMpd.modules.ModalView({
    	el : '#global-modal .modal-content'
    });

    window.sliMpd.localPlayer = new window.sliMpd.modules.LocalPlayer({
    	el : '.permaplayer.player-local'
    });
    window.sliMpd.mpdPlayer = new window.sliMpd.modules.MpdPlayer({
    	el : '.permaplayer.player-mpd'
    });

    window.sliMpd.currentPlayer = ($.cookie("playerMode") === 'mpd')
		? window.sliMpd.mpdPlayer
    	: window.sliMpd.localPlayer;

    window.sliMpd.router = new window.sliMpd.modules.Router();

    window.Backbone.history.start({
    	pushState : true
    });

	window.sliMpd.drawFavicon();

	/* toggle between mpd-control and local player (jPlayer) */
	$('.playerModeToggle a').on('click', function(e) {
		e.preventDefault();
		if(window.sliMpd.currentPlayer.mode === 'mpd') {
			$(this).addClass('active-local').removeClass('active-mpd').html($(this).attr('data-label-local'));
			window.sliMpd.currentPlayer = window.sliMpd.localPlayer;
			window.sliMpd.mpdPlayer.pollWorker.postMessage({
				cmd: 'setMiliseconds',
				value: window.sliMpd.mpdPlayer.intervalInactive
			});
			$('body')
				.removeClass(window.sliMpd.conf.color.mpd.bodyclass)
				.addClass(window.sliMpd.conf.color.local.bodyclass);
		} else {
			$(this).addClass('active-mpd').removeClass('active-local').html($(this).attr('data-label-mpd'));
			// pause local player when switching to mpd
			window.sliMpd.currentPlayer.process({'action':'pause'});
			window.sliMpd.currentPlayer = window.sliMpd.mpdPlayer;
			window.sliMpd.mpdPlayer.pollWorker.postMessage({
				cmd: 'setMiliseconds',
				value: window.sliMpd.mpdPlayer.intervalActive
			});
			window.sliMpd.currentPlayer.refreshInterval();
			$('body')
				.removeClass(window.sliMpd.conf.color.local.bodyclass)
				.addClass(window.sliMpd.conf.color.mpd.bodyclass);
		}
		$.cookie("playerMode", window.sliMpd.currentPlayer.mode, { expires : 365, path: '/' });
		$('.player-local,.player-mpd').toggle();
		window.sliMpd.drawFavicon();
		window.sliMpd.currentPlayer.drawWaveform();
	});

	/* toggle playersize */
	$('.playerSizeToggle a').on('click', function(e) {
		e.preventDefault();
		$('body').toggleClass('slimplayer');
		$(this).find('i').toggleClass('fa-chevron-down').toggleClass('fa-chevron-up');
		window.sliMpd.currentPlayer.drawWaveform();
	});

	/* toggle between display tags and display filepath */
	$('.fileModeToggle a').on('click', function(e) {
		e.preventDefault();
		$('body').toggleClass('ffn');
		$(this).find('i').toggleClass('fa-toggle-off').toggleClass('fa-toggle-on');
	});

	// delegate calls to data-toggle="lightbox"
	$(document).delegate('*[data-toggle="lightbox"]', 'click', function(event) {
		event.preventDefault();
		return $(this).ekkoLightbox({
			always_show_close: true,
			gallery_parent_selector: 'body'
		});
	});

	$(document).on('keydown', null, 'ctrl+space', function(){
		// FIXME: this does not work with open autocomplete-widget. obviously ac overrides key bindings
		$('#mainsearch').focus().select();
		return false;
	});

	$('.navbar-upper').affix({
  		offset: {bottom: 200}
	});

	NProgress.configure({
		showSpinner: false,
		parent: '#nprog-container',
		speed: 100,
		trickleRate: 0.02,
		trickleSpeed: 800
	});

	// TODO: is it correct to place this here (excluded from all bootstrap-views)?
	$(function(){
	    $('#top-link-block').removeClass('hidden').affix({
	        // how far to scroll down before link "slides" into view
	        offset: {top:100}
	    });
	});
	$('#top-link-block a').on('click', function(e) {
		e.preventDefault();
		$('html,body').animate({scrollTop:0},'fast');
		return false;
	});

	/*
	 * force confirmation when user leaves sliMpd in case local audio is playing
	 * as the browser is not displaying the text there is no nedd to fetch string from language file
	 */
	window.onbeforeunload=function(){
		if(window.sliMpd.currentPlayer.mode === 'local' && window.sliMpd.currentPlayer.nowPlayingState === 'play') {
			return 'local audio is currently playing';
		}
	}

	/*
	 * add lazy resize listener
	 */
	$(window).bind('resizeEnd', function() {
		window.sliMpd.currentPlayer.drawWaveform();
		window.sliMpd.currentPlayer.drawTimeGrid();
	});
	$(window).resize(function() {
		if(this.resizeTO) clearTimeout(this.resizeTO);
		this.resizeTO = setTimeout(function() {
			$(this).trigger('resizeEnd');
		}, 500);
	});
});

<|endoftext|>


<commit_before>/**
 * @namespace
 * @name validity.xml
 */
var validity = (function(validity) {
	"use strict";
	var xml = {};

	//	Public Methods

	/**
	 * @function
	 * @public
	 * @name parseResponse
	 */
	xml.parseResponse = function(xmlDom) {
		var response = {"url": undefined, "doctype": undefined, "errorCount": undefined, "messages": undefined, "source": {"encoding": undefined, "type": "text/html"}},
			errors = [],
			warnings = [],
			messages = [],
			errorNodes,
			warningNodes;

		response.url = _getFirstTagName(xmlDom, 'uri').textContent;
		response.doctype = _getFirstTagName(xmlDom, 'doctype').textContent;
		response.source.encoding = _getFirstTagName(xmlDom, 'charset').textContent;
		response.errorCount = _getFirstTagName(xmlDom, 'errorcount').textContent;

		errorNodes = _getFirstTagName(xmlDom, 'errorlist').getElementsByTagName('error');
		warningNodes = _getFirstTagName(xmlDom, 'warninglist').getElementsByTagName('warning');

		//	Loop through errors
		for (var i = 0; i < errorNodes.length; i++) {
			//	Create object for error
			errors[i] = {};

			errors[i].lastLine = parseInt(_getFirstTagName(errorNodes[i], 'line').textContent, 10);
			errors[i].lastColumn = parseInt(_getFirstTagName(errorNodes[i], 'col').textContent, 10);
			errors[i].message = _getFirstTagName(errorNodes[i], 'message').textContent;
			errors[i].messageid = _getFirstTagName(errorNodes[i], 'messageid').textContent;
			errors[i].explanation = _getFirstTagName(errorNodes[i], 'explanation').textContent;
			errors[i].type = 'error';
		}

		//	Loop through warnings
		for (var j = 0; j < warningNodes.length; j++) {
			//	Create object for warning
			warnings[j] = {};

			warnings[j].lastLine = parseInt(_getFirstTagName(warningNodes[j], 'line').textContent, 10);
			warnings[j].lastColumn = parseInt(_getFirstTagName(warningNodes[j], 'col').textContent, 10);
			warnings[j].message = _getFirstTagName(warningNodes[j], 'message').textContent;
			warnings[j].messageid = '';
			warnings[j].explanation = '';
			warnings[j].type = 'warn';
		}

		//	Concatenate errors and warnings onto messages array
		messages = messages.concat(errors, warnings);

		//	Sort messages by line
		messages.sort(function(a, b) {
			if (a.lastLine > b.lastLine) {
				return 1;
			}
			else if (a.lastLine < b.lastLine) {
				return -1;
			}
			//	Same line, look at column
			else if (a.lastColumn > b.lastColumn) {
				return 1;
			}
			else if (a.lastColumn < b.lastColumn) {
				return -1;
			}
			else {
				return 0;
			}
		});

		response.messages = messages;

		return response;
	};

	//	Private Functions

	/**
	 * @private
	 * @function
	 * @name _getFirstTagName
	 */
	function _getFirstTagName(dom, tagName) {
		var result = dom.getElementsByTagName(tagName)[0];
		return result || '';
	}

	validity.xml = xml;
	return validity;
})(validity || {});
<commit_msg>Implemented suppression of obsolete interface validator message.<commit_after>/**
 * @namespace
 * @name validity.xml
 */
var validity = (function(validity) {
	"use strict";
	var xml = {},
		suppressed = ['obsolete-interface'];

	//	Public Methods

	/**
	 * @function
	 * @public
	 * @name parseResponse
	 */
	xml.parseResponse = function(xmlDom) {
		var response = {"url": undefined, "doctype": undefined, "errorCount": undefined, "messages": undefined, "source": {"encoding": undefined, "type": "text/html"}},
			errors = [],
			warnings = [],
			messages = [],
			errorNodes,
			warningNodes;

		response.url = _getFirstTagName(xmlDom, 'uri').textContent;
		response.doctype = _getFirstTagName(xmlDom, 'doctype').textContent;
		response.source.encoding = _getFirstTagName(xmlDom, 'charset').textContent;
		response.errorCount = _getFirstTagName(xmlDom, 'errorcount').textContent;

		errorNodes = _getFirstTagName(xmlDom, 'errorlist').getElementsByTagName('error');
		warningNodes = _getFirstTagName(xmlDom, 'warninglist').getElementsByTagName('warning');

		//	Loop through errors
		for (var i = 0; i < errorNodes.length; i++) {
			//	Create object for error
			errors[i] = {};

			errors[i].lastLine = parseInt(_getFirstTagName(errorNodes[i], 'line').textContent, 10);
			errors[i].lastColumn = parseInt(_getFirstTagName(errorNodes[i], 'col').textContent, 10);
			errors[i].message = _getFirstTagName(errorNodes[i], 'message').textContent;
			errors[i].messageid = _getFirstTagName(errorNodes[i], 'messageid').textContent;
			errors[i].explanation = _getFirstTagName(errorNodes[i], 'explanation').textContent;
			errors[i].type = 'error';
		}

		//	Loop through warnings
		for (var j = 0; j < warningNodes.length; j++) {
			//	Create object for warning
			warnings[j] = {};

			warnings[j].lastLine = parseInt(_getFirstTagName(warningNodes[j], 'line').textContent, 10);
			warnings[j].lastColumn = parseInt(_getFirstTagName(warningNodes[j], 'col').textContent, 10);
			warnings[j].message = _getFirstTagName(warningNodes[j], 'message').textContent;
			warnings[j].messageid = _getFirstTagName(warningNodes[j], 'messageid').textContent;
			warnings[j].explanation = '';
			warnings[j].type = 'warn';
		}

		//	Concatenate errors and warnings onto messages array
		messages = messages.concat(errors, warnings);

		//	Sort messages by line
		messages.sort(function(a, b) {
			if (a.lastLine > b.lastLine) {
				return 1;
			}
			else if (a.lastLine < b.lastLine) {
				return -1;
			}
			//	Same line, look at column
			else if (a.lastColumn > b.lastColumn) {
				return 1;
			}
			else if (a.lastColumn < b.lastColumn) {
				return -1;
			}
			else {
				return 0;
			}
		});

		// Filter out suppressed messages.
		messages = messages.filter(function(message, index, array) {
			var id = message.messageid;

			return !suppressed.some(function(v, i, a) {
				return id === v;
			});
		});

		response.messages = messages;

		return response;
	};

	//	Private Functions

	/**
	 * @private
	 * @function
	 * @name _getFirstTagName
	 */
	function _getFirstTagName(dom, tagName) {
		var result = dom.getElementsByTagName(tagName)[0];
		return result || '';
	}

	validity.xml = xml;
	return validity;
})(validity || {});
<|endoftext|>


<commit_before>define(['module', 'vie', 'logger', 'tracker', 'userParams', 'data/episode/UserData', 'service/SocialSemanticService', 'extender',
        'data/AppData', 'underscore',
        'view/AppView', 'view/LoginFormView', 'voc',
        'text!../schemata/ss.sss.json',
        'jquery-cookie', 'bootstrap'],
function(module, VIE, Logger, tracker, userParams, UserData, SocialSemanticService, extender,
        AppData, _, AppView, LoginFormView, Voc, schema){
    VIE.Util.useRealUri = true;
    Logger.useDefaults();
    var AppLog = Logger.get('App');
    var AddLog = Logger.get('Add');
    Logger.get('Data').setLevel(Logger.OFF);
    Logger.get('UserData').setLevel(Logger.OFF);
    Logger.get('OrganizeData').setLevel(Logger.OFF);
    Logger.get('CircleData').setLevel(Logger.OFF);
    Logger.get('VersionData').setLevel(Logger.OFF);
    Logger.get('EpisodeData').setLevel(Logger.OFF);
    Logger.get('TimelineData').setLevel(Logger.OFF);
    Logger.get('UserEventData').setLevel(Logger.OFF);
    Logger.get('TimelineView').setLevel(Logger.OFF);
    Logger.get('OrganizeView').setLevel(Logger.OFF);
    Logger.get('WidgetView').setLevel(Logger.OFF);
    Logger.get('DetailView').setLevel(Logger.OFF);
    Logger.get('EpisodeManagerView').setLevel(Logger.OFF);
    Logger.get('EpisodeView').setLevel(Logger.OFF);
    Logger.get('EntityView').setLevel(Logger.OFF);
    Logger.get('OrgaEntityView').setLevel(Logger.OFF);
    Logger.get('UserEventView').setLevel(Logger.OFF);
    Logger.get('UserView').setLevel(Logger.OFF);
    Logger.get('MessageView').setLevel(Logger.OFF);
    Logger.get('ActivityView').setLevel(Logger.OFF);
    Logger.get('EntityRecommendationView').setLevel(Logger.OFF);
    Logger.get('App').setLevel(Logger.OFF);
    Logger.get('AppData').setLevel(Logger.OFF);
    Logger.get('Add').setLevel(Logger.OFF);
    Logger.get('SocialSemanticService').setLevel(Logger.OFF);
    Logger.get('SSSModel').setLevel(Logger.OFF);
    Logger.get('Mockup').setLevel(Logger.OFF);
    Logger.get('ToolbarView').setLevel(Logger.OFF);
    Logger.get('ActivityStreamToolbarView').setLevel(Logger.OFF);
    Logger.get('SearchToolbarView').setLevel(Logger.OFF);
    Logger.get('BitToolbarView').setLevel(Logger.OFF);
    Logger.get('EntityData').setLevel(Logger.OFF);
    Logger.get('OrgaEntityData').setLevel(Logger.OFF);
    Logger.get('UserAuth').setLevel(Logger.OFF);
    Logger.get('EpisodeToolbarView').setLevel(Logger.OFF);
    Logger.get('EntitiesHelper').setLevel(Logger.OFF);
    Logger.get('CategoryData').setLevel(Logger.OFF);
    Logger.get('SystemMessages').setLevel(Logger.OFF);
    Logger.get('InputValidation').setLevel(Logger.OFF);
    Logger.get('MessageData').setLevel(Logger.OFF);
    Logger.get('ActivityData').setLevel(Logger.OFF);

    if ( !userParams.isAuthenticated) {
        var loginView = new LoginFormView({
            'el' : 'body .container-fluid'
        });
        loginView.render();
        return null;
    }

    var v = new VIE();

    AppLog.debug('vie', v);

    var namespace = "http://eval.bp/" ;

    var sss = new SocialSemanticService(_.extend({
        'namespaces': {
            'sss': namespace
        },
        'hostREST' : module.config().sssHostREST
    }, userParams));
    v.use(sss, 'sss');
    //v.namespaces.base(namespace);

    extender.syncByVIE(v);
    extender.addOnUrisReady(v);
    //extender.autoResolveReferences(v);

    AppData.init(v);

    VIE.Util.loadSchemaOrg(v, JSON.parse(schema));
    $(document).ready(function(){
        var user = new v.Entity;
        user.set(user.idAttribute, userParams.user);
        user.set('@type', Voc.USER);
        v.entities.addOrUpdate(user);
        user.fetch();

        var view = new AppView({
            'model' : user,
            'el' : 'body .container-fluid',
            'vie' :  v
        });

        view.render();

    });

    return null;

});
<commit_msg>LL-282 Forot to register view logger.<commit_after>define(['module', 'vie', 'logger', 'tracker', 'userParams', 'data/episode/UserData', 'service/SocialSemanticService', 'extender',
        'data/AppData', 'underscore',
        'view/AppView', 'view/LoginFormView', 'voc',
        'text!../schemata/ss.sss.json',
        'jquery-cookie', 'bootstrap'],
function(module, VIE, Logger, tracker, userParams, UserData, SocialSemanticService, extender,
        AppData, _, AppView, LoginFormView, Voc, schema){
    VIE.Util.useRealUri = true;
    Logger.useDefaults();
    var AppLog = Logger.get('App');
    var AddLog = Logger.get('Add');
    Logger.get('Data').setLevel(Logger.OFF);
    Logger.get('UserData').setLevel(Logger.OFF);
    Logger.get('OrganizeData').setLevel(Logger.OFF);
    Logger.get('CircleData').setLevel(Logger.OFF);
    Logger.get('VersionData').setLevel(Logger.OFF);
    Logger.get('EpisodeData').setLevel(Logger.OFF);
    Logger.get('TimelineData').setLevel(Logger.OFF);
    Logger.get('UserEventData').setLevel(Logger.OFF);
    Logger.get('TimelineView').setLevel(Logger.OFF);
    Logger.get('OrganizeView').setLevel(Logger.OFF);
    Logger.get('WidgetView').setLevel(Logger.OFF);
    Logger.get('DetailView').setLevel(Logger.OFF);
    Logger.get('EpisodeManagerView').setLevel(Logger.OFF);
    Logger.get('EpisodeView').setLevel(Logger.OFF);
    Logger.get('EntityView').setLevel(Logger.OFF);
    Logger.get('OrgaEntityView').setLevel(Logger.OFF);
    Logger.get('UserEventView').setLevel(Logger.OFF);
    Logger.get('UserView').setLevel(Logger.OFF);
    Logger.get('MessageView').setLevel(Logger.OFF);
    Logger.get('ActivityView').setLevel(Logger.OFF);
    Logger.get('EntityRecommendationView').setLevel(Logger.OFF);
    Logger.get('App').setLevel(Logger.OFF);
    Logger.get('AppData').setLevel(Logger.OFF);
    Logger.get('Add').setLevel(Logger.OFF);
    Logger.get('SocialSemanticService').setLevel(Logger.OFF);
    Logger.get('SSSModel').setLevel(Logger.OFF);
    Logger.get('Mockup').setLevel(Logger.OFF);
    Logger.get('ToolbarView').setLevel(Logger.OFF);
    Logger.get('ActivityStreamToolbarView').setLevel(Logger.OFF);
    Logger.get('SearchToolbarView').setLevel(Logger.OFF);
    Logger.get('BitToolbarView').setLevel(Logger.OFF);
    Logger.get('EntityData').setLevel(Logger.OFF);
    Logger.get('OrgaEntityData').setLevel(Logger.OFF);
    Logger.get('UserAuth').setLevel(Logger.OFF);
    Logger.get('EpisodeToolbarView').setLevel(Logger.OFF);
    Logger.get('EntitiesHelper').setLevel(Logger.OFF);
    Logger.get('CategoryData').setLevel(Logger.OFF);
    Logger.get('SystemMessages').setLevel(Logger.OFF);
    Logger.get('InputValidation').setLevel(Logger.OFF);
    Logger.get('MessageData').setLevel(Logger.OFF);
    Logger.get('ActivityData').setLevel(Logger.OFF);
    Logger.get('CircleRenameModalView').setLevel(Logger.OFF);

    if ( !userParams.isAuthenticated) {
        var loginView = new LoginFormView({
            'el' : 'body .container-fluid'
        });
        loginView.render();
        return null;
    }

    var v = new VIE();

    AppLog.debug('vie', v);

    var namespace = "http://eval.bp/" ;

    var sss = new SocialSemanticService(_.extend({
        'namespaces': {
            'sss': namespace
        },
        'hostREST' : module.config().sssHostREST
    }, userParams));
    v.use(sss, 'sss');
    //v.namespaces.base(namespace);

    extender.syncByVIE(v);
    extender.addOnUrisReady(v);
    //extender.autoResolveReferences(v);

    AppData.init(v);

    VIE.Util.loadSchemaOrg(v, JSON.parse(schema));
    $(document).ready(function(){
        var user = new v.Entity;
        user.set(user.idAttribute, userParams.user);
        user.set('@type', Voc.USER);
        v.entities.addOrUpdate(user);
        user.fetch();

        var view = new AppView({
            'model' : user,
            'el' : 'body .container-fluid',
            'vie' :  v
        });

        view.render();

    });

    return null;

});
<|endoftext|>


<commit_before>'use strict';

var fs = require("fs");
var path = require("path");
var join = path.join;
var crypto = require("crypto");
var spawn = require("child_process").spawn;
var wrench = require("wrench");
var archiver = require("archiver");
var rm = require('rimraf');
var Promise = require('es6-promise').Promise;

function ChromeExtension(attrs) {
  if ((this instanceof ChromeExtension) !== true) {
    return new ChromeExtension(attrs);
  }

  /*
   Defaults
   */
  this.appId = null;

  this.manifest = '';

  this.loaded = false;

  this.rootDirectory = '';

  this.publicKey = null;

  this.privateKey = null;

  this.signature = null;

  this.contents = null;

  this.codebase = null;

  /*
  Copying attributes
   */
  for (var name in attrs) {
    this[name] = attrs[name];
  }

  this.path = join("tmp", "crx-" + (Math.random() * 1e17).toString(36))
}

ChromeExtension.prototype = {

  /**
   * Destroys generated files.
   *
   * @returns {Promise}
   */
  destroy: function () {
    var path = this.path;

    return new Promise(function(resolve, reject){
      rm(path, function(err){
        if (err){
          return reject(err);
        }

        resolve();
      });
    });
  },

  pack: function (cb) {
    if (!this.loaded) {
      return this.load().then(this.pack.bind(this, cb));
    }

    this.generatePublicKey(function (err) {
      if (err) return cb(err);

      var manifest = JSON.stringify(this.manifest);

      this.writeFile("manifest.json", manifest, function (err) {
        if (err) return cb(err);

        this.loadContents(function (err) {
          if (err) return cb(err);

          this.generateSignature();

          cb.call(this, null, this.generatePackage())
        })
      })
    })
  },

  /**
   * Loads extension manifest and copies its content to a workable path.
   *
   * @returns {Promise}
   */
  load: function () {
    if (!fs.existsSync("tmp")) {
      fs.mkdirSync("tmp");
    }

    var selfie = this;

    return new Promise(function(resolve, reject){
      wrench.copyDirRecursive(selfie.rootDirectory, selfie.path, function (err) {
        if (err) {
          return reject(err);
        }

        selfie.manifest = require(join(process.cwd(), selfie.path, "manifest.json"));
        selfie.loaded = true;

        resolve(selfie);
      });
    });
  },

  writeFile: function (path, data, cb) {
    path = join(this.path, path);

    fs.writeFile(path, data, function (err, data) {
      if (err) return cb.call(this, err);

      cb.call(this)
    }.bind(this));
  },

  generatePublicKey: function (cb) {
    var rsa = spawn("openssl", ["rsa", "-pubout", "-outform", "DER"])

    rsa.stdout.on("data", function (data) {
      this.publicKey = data;
      cb && cb.call(this, null, this)
    }.bind(this));

    rsa.stdin.end(this.privateKey)
  },

  generateSignature: function () {
    return this.signature = new Buffer(
      crypto
        .createSign("sha1")
        .update(this.contents)
        .sign(this.privateKey),

      "binary"
    )
  },

  loadContents: function (cb) {
    var archive = archiver("zip");
    this.contents = "";

    var files = wrench.readdirSyncRecursive(this.path);

    files.forEach(function (current) {
      var stat = fs.statSync(join(this.path, current));

      if (stat.isFile() && current !== "key.pem") {
        archive.append(fs.createReadStream(join(this.path, current)), {name: current})
      }
    }, this);

    archive.finalize();

    // Relates to the issue: "Event 'finished' no longer valid #18"
    // https://github.com/jed/crx/issues/18
    // TODO: Buffer concat could be a problem when building a big extension.
    //       So ideally only the 'finish' callback must be used.
    archive.on('readable', function () {
      this.contents = !this.contents.length ? archive.read() : Buffer.concat([this.contents, archive.read()]);
    }.bind(this));

    archive.on('finish', function () {
      cb.call(this);
    }.bind(this));

    archive.on("error", function (err) {
      throw err;
    });
  },

  /**
   * Generates and returns a signed package from extension content.
   *
   * BC BREAK `this.package` is not stored anymore (since 1.0.0)
   *
   * @param {Buffer} signature
   * @returns {Buffer}
   */
  generatePackage: function () {
    var signature = this.signature;
    var publicKey = this.publicKey;
    var contents = this.contents;

    var keyLength = publicKey.length;
    var sigLength = signature.length;
    var zipLength = contents.length;
    var length = 16 + keyLength + sigLength + zipLength;

    var crx = new Buffer(length);

    crx.write("Cr24" + Array(13).join("\x00"), "binary");

    crx[4] = 2;
    crx.writeUInt32LE(keyLength, 8);
    crx.writeUInt32LE(sigLength, 12);

    publicKey.copy(crx, 16);
    signature.copy(crx, 16 + keyLength);
    contents.copy(crx, 16 + keyLength + sigLength);

    return crx;
  },

  /**
   * Generates an appId from the publicKey.
   *
   * BC BREAK `this.appId` is not stored anymore (since 1.0.0)
   *
   * @returns {string}
   */
  generateAppId: function () {
    return crypto
      .createHash("sha256")
      .update(this.publicKey)
      .digest("hex")
      .slice(0, 32)
      .replace(/./g, function (x) {
        return (parseInt(x, 16) + 10).toString(26);
      });
  },

  /**
   * Generates an updateXML file from the extension content.
   *
   * BC BREAK `this.updateXML` is not stored anymore (since 1.0.0)
   *
   * @returns {Buffer}
   */
  generateUpdateXML: function () {
    if (!this.codebase) {
      throw new Error("No URL provided for update.xml.");
    }

    return Buffer(
      "<?xml version='1.0' encoding='UTF-8'?>\n" +
      "<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>\n" +
      "  <app appid='" + (this.appId || this.generateAppId()) + "'>\n" +
      "    <updatecheck codebase='" + this.codebase + "' version='" + this.manifest.version + "' />\n" +
      "  </app>\n" +
      "</gupdate>"
    );
  }
};

module.exports = ChromeExtension;
<commit_msg>BC break for `generateSignature`.<commit_after>'use strict';

var fs = require("fs");
var path = require("path");
var join = path.join;
var crypto = require("crypto");
var spawn = require("child_process").spawn;
var wrench = require("wrench");
var archiver = require("archiver");
var rm = require('rimraf');
var Promise = require('es6-promise').Promise;

function ChromeExtension(attrs) {
  if ((this instanceof ChromeExtension) !== true) {
    return new ChromeExtension(attrs);
  }

  /*
   Defaults
   */
  this.appId = null;

  this.manifest = '';

  this.loaded = false;

  this.rootDirectory = '';

  this.publicKey = null;

  this.privateKey = null;

  this.contents = null;

  this.codebase = null;

  /*
  Copying attributes
   */
  for (var name in attrs) {
    this[name] = attrs[name];
  }

  this.path = join("tmp", "crx-" + (Math.random() * 1e17).toString(36))
}

ChromeExtension.prototype = {

  /**
   * Destroys generated files.
   *
   * @returns {Promise}
   */
  destroy: function () {
    var path = this.path;

    return new Promise(function(resolve, reject){
      rm(path, function(err){
        if (err){
          return reject(err);
        }

        resolve();
      });
    });
  },

  pack: function (cb) {
    if (!this.loaded) {
      return this.load().then(this.pack.bind(this, cb));
    }

    this.generatePublicKey(function (err) {
      if (err) return cb(err);

      var manifest = JSON.stringify(this.manifest);

      this.writeFile("manifest.json", manifest, function (err) {
        if (err) return cb(err);

        this.loadContents(function (err) {
          if (err) return cb(err);

          var signature = this.generateSignature();

          cb.call(this, null, this.generatePackage(signature))
        })
      })
    })
  },

  /**
   * Loads extension manifest and copies its content to a workable path.
   *
   * @returns {Promise}
   */
  load: function () {
    if (!fs.existsSync("tmp")) {
      fs.mkdirSync("tmp");
    }

    var selfie = this;

    return new Promise(function(resolve, reject){
      wrench.copyDirRecursive(selfie.rootDirectory, selfie.path, function (err) {
        if (err) {
          return reject(err);
        }

        selfie.manifest = require(join(process.cwd(), selfie.path, "manifest.json"));
        selfie.loaded = true;

        resolve(selfie);
      });
    });
  },

  writeFile: function (path, data, cb) {
    path = join(this.path, path);

    fs.writeFile(path, data, function (err, data) {
      if (err) return cb.call(this, err);

      cb.call(this)
    }.bind(this));
  },

  generatePublicKey: function (cb) {
    var rsa = spawn("openssl", ["rsa", "-pubout", "-outform", "DER"])

    rsa.stdout.on("data", function (data) {
      this.publicKey = data;
      cb && cb.call(this, null, this)
    }.bind(this));

    rsa.stdin.end(this.privateKey)
  },

  /**
   * Generates a SHA1 package signature.
   *
   * BC BREAK `this.signature` is not stored anymore (since 1.0.0)
   *
   * @returns {Buffer}
   */
  generateSignature: function () {
    return new Buffer(
      crypto
        .createSign("sha1")
        .update(this.contents)
        .sign(this.privateKey),
      "binary"
    )
  },

  loadContents: function (cb) {
    var archive = archiver("zip");
    this.contents = "";

    var files = wrench.readdirSyncRecursive(this.path);

    files.forEach(function (current) {
      var stat = fs.statSync(join(this.path, current));

      if (stat.isFile() && current !== "key.pem") {
        archive.append(fs.createReadStream(join(this.path, current)), {name: current})
      }
    }, this);

    archive.finalize();

    // Relates to the issue: "Event 'finished' no longer valid #18"
    // https://github.com/jed/crx/issues/18
    // TODO: Buffer concat could be a problem when building a big extension.
    //       So ideally only the 'finish' callback must be used.
    archive.on('readable', function () {
      this.contents = !this.contents.length ? archive.read() : Buffer.concat([this.contents, archive.read()]);
    }.bind(this));

    archive.on('finish', function () {
      cb.call(this);
    }.bind(this));

    archive.on("error", function (err) {
      throw err;
    });
  },

  /**
   * Generates and returns a signed package from extension content.
   *
   * BC BREAK `this.package` is not stored anymore (since 1.0.0)
   *
   * @param {Buffer} signature
   * @returns {Buffer}
   */
  generatePackage: function (signature) {
    var publicKey = this.publicKey;
    var contents = this.contents;

    var keyLength = publicKey.length;
    var sigLength = signature.length;
    var zipLength = contents.length;
    var length = 16 + keyLength + sigLength + zipLength;

    var crx = new Buffer(length);

    crx.write("Cr24" + Array(13).join("\x00"), "binary");

    crx[4] = 2;
    crx.writeUInt32LE(keyLength, 8);
    crx.writeUInt32LE(sigLength, 12);

    publicKey.copy(crx, 16);
    signature.copy(crx, 16 + keyLength);
    contents.copy(crx, 16 + keyLength + sigLength);

    return crx;
  },

  /**
   * Generates an appId from the publicKey.
   *
   * BC BREAK `this.appId` is not stored anymore (since 1.0.0)
   *
   * @returns {string}
   */
  generateAppId: function () {
    return crypto
      .createHash("sha256")
      .update(this.publicKey)
      .digest("hex")
      .slice(0, 32)
      .replace(/./g, function (x) {
        return (parseInt(x, 16) + 10).toString(26);
      });
  },

  /**
   * Generates an updateXML file from the extension content.
   *
   * BC BREAK `this.updateXML` is not stored anymore (since 1.0.0)
   *
   * @returns {Buffer}
   */
  generateUpdateXML: function () {
    if (!this.codebase) {
      throw new Error("No URL provided for update.xml.");
    }

    return Buffer(
      "<?xml version='1.0' encoding='UTF-8'?>\n" +
      "<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>\n" +
      "  <app appid='" + (this.appId || this.generateAppId()) + "'>\n" +
      "    <updatecheck codebase='" + this.codebase + "' version='" + this.manifest.version + "' />\n" +
      "  </app>\n" +
      "</gupdate>"
    );
  }
};

module.exports = ChromeExtension;
<|endoftext|>


<commit_before>/*
 * Tangram
 * Copyright 2009 Baidu Inc. All rights reserved.
 */

///import baidu.ui.createUI;

///import baidu.dom.setAttr;
///import baidu.dom.setStyles;
///import baidu.dom._styleFilter.px;
///import baidu.dom._styleFixer.opacity;

///import baidu.string.format;

///import baidu.browser.ie;
///import baidu.event.on;
///import baidu.event.un;
///import baidu.page.getScrollLeft;
///import baidu.page.getScrollTop;
///import baidu.lang.isNumber;
///import baidu.object.each;
///import baidu.object.extend;
///import baidu.array.each;

///import baidu.dom.getAttr;
///import baidu.dom.getAncestorBy;
///import baidu.dom.getStyle;
///import baidu.dom.getPosition;
///import baidu.dom.children;
///import baidu.dom.fixable;
///import baidu.browser.ie;

///import baidu.lang.instance;

///import baidu.page.getViewWidth;
///import baidu.page.getViewHeight;

//添加对flash的隐藏和显示
//在webkit中，使用iframe加div的方式遮罩wmode为window的flash会时性能下降到无法忍受的地步
//在Gecko中，使用透明的iframe无法遮住wmode为window的flash
//在其余浏览器引擎中wmode为window的flash会被遮罩，处于不可见状态
//因此，直接将wmode为window的flash隐藏，保证页面最小限度的修改

/**
 * 为控件增加遮罩。
 * @class Modal类
 */

baidu.ui.Modal = baidu.ui.createUI(function(options) {
    var me = this,
        container = (options && options.container) ? baidu.g(options.container) : null;

    !container && (container = document.body);
    if (!container.id) {
        container.id = me.getId('container');
    }

    me.containerId = container.id;
    me.styles = {
        color: '#000000',
        opacity: 0.6,
        zIndex: 1000
    };

}).extend(
    /**
     *  @lends baidu.ui.Modal.prototype
     */
{
    uiType: 'modal',
    _showing: false,

    /**
     * 获取modal的Container
     * @public
     * @return {HTMLElement} container.
     */
    getContainer: function() {
        var me = this;
        return baidu.g(me.containerId);
    },

    /**
     * 渲染遮罩层
     * @public
     * @return {NULL}
     * */
    render: function() {
        var me = this,
            modalInstance,
            fixableInstance,
            style,
            main,
            id = me.containerId,
            container = baidu.g(me.containerId);

        //当该container中已经存在modal时
        //将所需参数付给当前的modalInstance
        if (modalInstance = baidu.ui.Modal.collection[id]) {
            me.mainId = modalInstance.mainId;
            main = me.getMain();
        }else {
            //如果不存在modal,则创建新的modal
            main = me.renderMain();
            if (container !== document.body) {
                container.appendChild(main);
            }else{
                fixableInstance = baidu.dom.fixable(main, {
                    autofix: false,
                    vertival: 'top',
                    horizontal: 'left',
                    offset: {x:0, y:0}
                });
            }
            //将参数写入
            baidu.ui.Modal.collection[id] = {
                mainId: me.mainId,
                instance: [],
                flash:{},
                fixableInstance: fixableInstance
            };
        }

        me.dispatchEvent('onload');
    },

    /**
     * 显示遮罩层
     * @public
     * @param  {Object} options     显示选项,任何合法的style属性.
     * @return {NULL}
     */
    show: function(options) {
        var me = this,
            container = me.getContainer(),
            main = me.getMain(),
            containerId = me.containerId,
            modalInstanceOptions = baidu.ui.Modal.collection[containerId],
            fixableInstance = modalInstanceOptions.fixableInstance,
            length = modalInstanceOptions.instance.length,
            lastTop;

        if (me._showing)
            return;

        if (length > 0) {
            lastTop = baidu.lang.instance(modalInstanceOptions.instance[length - 1]);
            lastTop && lastTop._removeHandler();
        }
        options = options || {};
        me._show(options.styles || {});
        if(fixableInstance)
            fixableInstance.render();
        main.style.display = 'block';

        //将在此层中隐藏flash入库
        modalInstanceOptions.flash[me.guid] = me._hideFlash();

        //将自己的guid加在guid最后
        modalInstanceOptions.instance.push(me.guid);
        me._showing = true;

        me.dispatchEvent('onshow');
    },

    /**
     * 更新遮罩层，绑定window.resize & window.scroll
     * @private
     * @param {Object} styles
     * @return {NULL}
     */
    _show: function(styles) {
        var me = this;

        me._getModalStyles(styles || {});
        me._update();

        if(me.getContainer() === document.body && baidu.browser.ie && baidu.browser.ie < 7){
            me.windowHandler = me.getWindowHandle();
            baidu.on(window, 'resize', me.windowHandler);
        }
    },

    /**
     * 隐藏遮罩层
     * @public
     * @return {NULL}
     */
    hide: function() {
        var me = this;
        me._hide();
        me.dispatchEvent('onhide');
    },

    _hide: function(){
        var me = this,
            containerId = me.containerId,
            modalInstanceOptions = baidu.ui.Modal.collection[containerId],
            flash = modalInstanceOptions.flash[me.guid],
            main = me.getMain(),
            length = modalInstanceOptions.instance.length,
            lastTop;

         if (!me._showing)
             return;

         for (var i = 0; i < length; i++) {
             if (modalInstanceOptions.instance[i] == me.guid) {
                 modalInstanceOptions.instance.splice(i, 1);
                 break;
             }
         }
         length = modalInstanceOptions.instance.length;
         if (i == length) {
             me._removeHandler();
             if (length > 0) {
                 lastTop = baidu.lang.instance(modalInstanceOptions.instance[length - 1]);
                 lastTop && lastTop._show();
             }else {
                 main.style.display = 'none';
             }

             me._restoreFlash(flash);
         }else{
             //如果不是最后一个，就将该层对应的flash移动到下一层的数组中
             lastTop = baidu.lang.instance(modalInstanceOptions.instance[length - 1]);
             modalInstanceOptions.flash[lastTop.guid] = modalInstanceOptions.flash[lastTop.guid].concat(flash);
         }

         modalInstanceOptions.flash[me.guid] = [];
         me._showing = false;
    },

    /**
     * 接触window.resize和window.scroll上的事件绑定
     * @private
     * @return {NULL}
     */
    _removeHandler: function() {
        var me = this;
        if(me.getContainer() === document.body && baidu.browser.ie && baidu.browser.ie < 7){
            baidu.un(window, 'resize', me.windowHandler);
        }
    },

    /**
     * window.resize & window.scroll 事件调用的function
     * @public
     * @return {NULL}
     */
    getWindowHandle: function() {
        var me = this,
            main = me.getMain();

        return function() {
            baidu.setStyles(main, {
                width: baidu.page.getViewWidth(),
                height: baidu.page.getViewHeight()
            });

            if(me.getContainer() === document.body && baidu.browser.ie && baidu.browser.ie < 7){
                //iframe 补丁
                window.top !== window.self && setTimeout(function(){
                    me._getModalStyles({});
                    me._update();
                },16);
            }
         };
    },

    /**
     * 更新遮罩层
     * @public
     * @param  {Object} options 显示选项，同show.
     * @return {NULL}
     */
    update: function(options) {
        options = options || {};
        var me = this,
            main = me.getMain(),
            modalInstanceOptions = baidu.ui.Modal.collection[me.containerId];

        options = options || {};
        baidu.extend(me, options);

        me._getModalStyles(options.styles || {});
        me._update();
        delete(options.styles);
        baidu.extend(me, options);

        me.dispatchEvent('onupdate');
    },

    /**
     * 更新样式
     * @private
     * @return {NULL}
     */
    _update: function() {
        var me = this, main = me.getMain();
        baidu.dom.setStyles(main, me.styles);
    },

    /**
     * 获取遮罩层相对container左上角的top和left
     * @private
     * @options {object} show传入的styles
     * @return {NULL}
     */
    _getModalStyles: function(styles) {
        var me = this,
            main = me.getMain(),
            container = me.getContainer(),
            offsetParentPosition,
            parentPosition, offsetParent;

        function getStyleNum(d,style) {
            var result = parseInt(baidu.getStyle(d, style));
            result = isNaN(result) ? 0 : result;
            result = baidu.lang.isNumber(result) ? result : 0;
            return result;
        }

        if (container !== document.body) {
            styles['width'] = container.offsetWidth;
            styles['height'] = container.offsetHeight;

            if (baidu.getStyle(container, 'position') == 'static') {
                offsetParent = main.offsetParent || document.body;
                offsetParentPosition = baidu.dom.getPosition(offsetParent);
                parentPosition = baidu.dom.getPosition(container);
                styles['top'] = parentPosition.top - offsetParentPosition.top + getStyleNum(offsetParent, 'marginTop');
                styles['left'] = parentPosition.left - offsetParentPosition.left + getStyleNum(offsetParent, 'marginLeft');
            }
        }else {

            if ( baidu.browser.ie >= 7 || !baidu.browser.ie) {
                styles['width'] = '100%';
                styles['height'] = '100%';
            }else {
                styles['width'] = baidu.page.getViewWidth();
                styles['height'] = baidu.page.getViewHeight();
            }
        }

        //更新styles
        baidu.extend(me.styles, styles);
        me.styles['backgroundColor'] = me.styles['color'] || me.styles['backgroundColor'];
        delete(me.styles['color']);
    },

    /**
     * 隐藏flash
     * @private
     * @return {Null}
     */
    _hideFlash: function(){
        var me = this,
            container = me.getContainer(),
            elements = container.getElementsByTagName('object'),
            result = [];

        //只隐藏wmode = window的flash
        baidu.each(elements, function(item){
            var isWinMode = true;

            if(baidu.dom.getAncestorBy(item,function(element){
                if(baidu.getStyle(element, 'zIndex') > me.styles.zIndex){
                    return true;
                }

                return false;
            })){
                return;
            }

            baidu.each(baidu.dom.children(item), function(param){
                if(baidu.getAttr(param, 'name') == 'wmode' && baidu.getAttr(param, 'value') != 'window'){
                    isWinMode = false;
                }
            });

            if(isWinMode){
                result.push([item,baidu.getStyle(item, 'visibility')]);
                item.style.visibility = 'hidden';
            }
        });

        return result;
    },

    /**
     * 还原flash
     * @private
     * @return {Null}
     */
    _restoreFlash: function(flash){
        baidu.each(flash, function(item){
            if(item[0] != null){
                item[0].style.visibility = item[1];
            }
        });
    },

    /**
     * 销毁
     * @public
     * @return {Null}
     */
    dispose: function(){
        var me = this;

        me._hide();
        me.dispatchEvent('ondispose');
        baidu.lang.Class.prototype.dispose.call(me);
    }
});

//存储所有的modal参数
baidu.ui.Modal.collection = {};
<commit_msg>bug fix:<commit_after>/*
 * Tangram
 * Copyright 2009 Baidu Inc. All rights reserved.
 */

///import baidu.ui.createUI;

///import baidu.dom.setAttr;
///import baidu.dom.setStyles;
///import baidu.dom._styleFilter.px;
///import baidu.dom._styleFixer.opacity;

///import baidu.string.format;

///import baidu.browser.ie;
///import baidu.event.on;
///import baidu.event.un;
///import baidu.page.getScrollLeft;
///import baidu.page.getScrollTop;
///import baidu.lang.isNumber;
///import baidu.object.each;
///import baidu.object.extend;
///import baidu.array.each;

///import baidu.dom.getAttr;
///import baidu.dom.getAncestorBy;
///import baidu.dom.getStyle;
///import baidu.dom.getPosition;
///import baidu.dom.children;
///import baidu.dom.fixable;
///import baidu.browser.ie;

///import baidu.lang.instance;

///import baidu.page.getViewWidth;
///import baidu.page.getViewHeight;

//添加对flash的隐藏和显示
//在webkit中，使用iframe加div的方式遮罩wmode为window的flash会时性能下降到无法忍受的地步
//在Gecko中，使用透明的iframe无法遮住wmode为window的flash
//在其余浏览器引擎中wmode为window的flash会被遮罩，处于不可见状态
//因此，直接将wmode为window的flash隐藏，保证页面最小限度的修改

/**
 * 为控件增加遮罩。
 * @class Modal类
 */

baidu.ui.Modal = baidu.ui.createUI(function(options) {
    var me = this,
        container = (options && options.container) ? baidu.g(options.container) : null;

    !container && (container = document.body);
    if (!container.id) {
        container.id = me.getId('container');
    }

    me.containerId = container.id;
    me.styles = {
        color: '#000000',
        opacity: 0.6,
        zIndex: 1000
    };

}).extend(
    /**
     *  @lends baidu.ui.Modal.prototype
     */
{
    uiType: 'modal',
    _showing: false,

    /**
     * 获取modal的Container
     * @public
     * @return {HTMLElement} container.
     `*/
    getContainer: function() {
        var me = this;
        return baidu.g(me.containerId);
    },

    /**
     * 渲染遮罩层
     * @public
     * @return {NULL}
     * */
    render: function() {
        var me = this,
            modalInstance,
            fixableInstance,
            style,
            main,
            id = me.containerId,
            container = baidu.g(me.containerId);

        //当该container中已经存在modal时
        //将所需参数付给当前的modalInstance
        if (modalInstance = baidu.ui.Modal.collection[id]) {
            me.mainId = modalInstance.mainId;
            main = me.getMain();
        }else {
            //如果不存在modal,则创建新的modal
            main = me.renderMain();
            if (container !== document.body) {
                container.appendChild(main);
            }else{
                fixableInstance = baidu.dom.fixable(main, {
                    autofix: false,
                    vertival: 'top',
                    horizontal: 'left',
                    offset: {x:0, y:0}
                });
            }
            //将参数写入
            baidu.ui.Modal.collection[id] = {
                mainId: me.mainId,
                instance: [],
                flash:{},
                fixableInstance: fixableInstance
            };
        }

        me.dispatchEvent('onload');
    },

    /**
     * 显示遮罩层
     * @public
     * @param  {Object} options     显示选项,任何合法的style属性.
     * @return {NULL}
     */
    show: function(options) {
        var me = this,
            container = me.getContainer(),
            main = me.getMain(),
            containerId = me.containerId,
            modalInstanceOptions = baidu.ui.Modal.collection[containerId],
            fixableInstance = modalInstanceOptions.fixableInstance,
            length = modalInstanceOptions.instance.length,
            lastTop;

        if (me._showing)
            return;

        if (length > 0) {
            lastTop = baidu.lang.instance(modalInstanceOptions.instance[length - 1]);
            lastTop && lastTop._removeHandler();
        }
        options = options || {};
        me._show(options.styles || {});
        if(fixableInstance)
            fixableInstance.render();
        main.style.display = 'block';

        //将在此层中隐藏flash入库
        modalInstanceOptions.flash[me.guid] = me._hideFlash();

        //将自己的guid加在guid最后
        modalInstanceOptions.instance.push(me.guid);
        me._showing = true;

        me.dispatchEvent('onshow');
    },

    /**
     * 更新遮罩层，绑定window.resize & window.scroll
     * @private
     * @param {Object} styles
     * @return {NULL}
     */
    _show: function(styles) {
        var me = this;

        me._getModalStyles(styles || {});
        me._update();

        if(me.getContainer() === document.body && baidu.browser.ie && baidu.browser.ie <= 7){
            me.windowHandler = me.getWindowHandle();
            baidu.on(window, 'resize', me.windowHandler);
        }
    },

    /**
     * 隐藏遮罩层
     * @public
     * @return {NULL}
     */
    hide: function() {
        var me = this;
        me._hide();
        me.dispatchEvent('onhide');
    },

    _hide: function(){
        var me = this,
            containerId = me.containerId,
            modalInstanceOptions = baidu.ui.Modal.collection[containerId],
            flash = modalInstanceOptions.flash[me.guid],
            main = me.getMain(),
            length = modalInstanceOptions.instance.length,
            lastTop;

         if (!me._showing)
             return;

         for (var i = 0; i < length; i++) {
             if (modalInstanceOptions.instance[i] == me.guid) {
                 modalInstanceOptions.instance.splice(i, 1);
                 break;
             }
         }
         length = modalInstanceOptions.instance.length;
         if (i == length) {
             me._removeHandler();
             if (length > 0) {
                 lastTop = baidu.lang.instance(modalInstanceOptions.instance[length - 1]);
                 lastTop && lastTop._show();
             }else {
                 main.style.display = 'none';
             }

             me._restoreFlash(flash);
         }else{
             //如果不是最后一个，就将该层对应的flash移动到下一层的数组中
             lastTop = baidu.lang.instance(modalInstanceOptions.instance[length - 1]);
             modalInstanceOptions.flash[lastTop.guid] = modalInstanceOptions.flash[lastTop.guid].concat(flash);
         }

         modalInstanceOptions.flash[me.guid] = [];
         me._showing = false;
    },

    /**
     * 接触window.resize和window.scroll上的事件绑定
     * @private
     * @return {NULL}
     */
    _removeHandler: function() {
        var me = this;
        if(me.getContainer() === document.body && baidu.browser.ie && baidu.browser.ie <= 7){
            baidu.un(window, 'resize', me.windowHandler);
        }
    },

    /**
     * window.resize & window.scroll 事件调用的function
     * @public
     * @return {NULL}
     */
    getWindowHandle: function() {
        var me = this,
            main = me.getMain();

        return function() {
            baidu.setStyles(main, {
                width: baidu.page.getViewWidth(),
                height: baidu.page.getViewHeight()
            });

            if(me.getContainer() === document.body && baidu.browser.ie && baidu.browser.ie <= 7){
                //iframe 补丁
                window.top !== window.self && setTimeout(function(){
                    me._getModalStyles({});
                    me._update();
                },16);
            }
         };
    },

    /**
     * 更新遮罩层
     * @public
     * @param  {Object} options 显示选项，同show.
     * @return {NULL}
     */
    update: function(options) {
        options = options || {};
        var me = this,
            main = me.getMain(),
            modalInstanceOptions = baidu.ui.Modal.collection[me.containerId];

        options = options || {};
        baidu.extend(me, options);

        me._getModalStyles(options.styles || {});
        me._update();
        delete(options.styles);
        baidu.extend(me, options);

        me.dispatchEvent('onupdate');
    },

    /**
     * 更新样式
     * @private
     * @return {NULL}
     */
    _update: function() {
        var me = this, main = me.getMain();
        baidu.dom.setStyles(main, me.styles);
    },

    /**
     * 获取遮罩层相对container左上角的top和left
     * @private
     * @options {object} show传入的styles
     * @return {NULL}
     */
    _getModalStyles: function(styles) {
        var me = this,
            main = me.getMain(),
            container = me.getContainer(),
            offsetParentPosition,
            parentPosition, offsetParent;

        function getStyleNum(d,style) {
            var result = parseInt(baidu.getStyle(d, style));
            result = isNaN(result) ? 0 : result;
            result = baidu.lang.isNumber(result) ? result : 0;
            return result;
        }

        if (container !== document.body) {
            styles['width'] = container.offsetWidth;
            styles['height'] = container.offsetHeight;

            if (baidu.getStyle(container, 'position') == 'static') {
                offsetParent = main.offsetParent || document.body;
                offsetParentPosition = baidu.dom.getPosition(offsetParent);
                parentPosition = baidu.dom.getPosition(container);
                styles['top'] = parentPosition.top - offsetParentPosition.top + getStyleNum(offsetParent, 'marginTop');
                styles['left'] = parentPosition.left - offsetParentPosition.left + getStyleNum(offsetParent, 'marginLeft');
            }
        }else {

            if ( baidu.browser.ie > 7 || !baidu.browser.ie) {
                styles['width'] = '100%';
                styles['height'] = '100%';
            }else {
                styles['width'] = baidu.page.getViewWidth();
                styles['height'] = baidu.page.getViewHeight();
            }
        }

        //更新styles
        baidu.extend(me.styles, styles);
        me.styles['backgroundColor'] = me.styles['color'] || me.styles['backgroundColor'];
        delete(me.styles['color']);
    },

    /**
     * 隐藏flash
     * @private
     * @return {Null}
     */
    _hideFlash: function(){
        var me = this,
            container = me.getContainer(),
            elements = container.getElementsByTagName('object'),
            result = [];

        //只隐藏wmode = window的flash
        baidu.each(elements, function(item){
            var isWinMode = true;

            if(baidu.dom.getAncestorBy(item,function(element){
                if(baidu.getStyle(element, 'zIndex') > me.styles.zIndex){
                    return true;
                }

                return false;
            })){
                return;
            }

            baidu.each(baidu.dom.children(item), function(param){
                if(baidu.getAttr(param, 'name') == 'wmode' && baidu.getAttr(param, 'value') != 'window'){
                    isWinMode = false;
                }
            });

            if(isWinMode){
                result.push([item,baidu.getStyle(item, 'visibility')]);
                item.style.visibility = 'hidden';
            }
        });

        return result;
    },

    /**
     * 还原flash
     * @private
     * @return {Null}
     */
    _restoreFlash: function(flash){
        baidu.each(flash, function(item){
            if(item[0] != null){
                item[0].style.visibility = item[1];
            }
        });
    },

    /**
     * 销毁
     * @public
     * @return {Null}
     */
    dispose: function(){
        var me = this;

        me._hide();
        me.dispatchEvent('ondispose');
        baidu.lang.Class.prototype.dispose.call(me);
    }
});

//存储所有的modal参数
baidu.ui.Modal.collection = {};
<|endoftext|>


<commit_before>function getUrlVars()
{
    var vars = [], hash;
    var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
    for(var i = 0; i < hashes.length; i++)
    {
        hash = hashes[i].split('=');
        vars.push(hash[0]);
        vars[hash[0]] = hash[1];
    }
    return vars;
}

function encrypt(text, pass) {
  //console.log('pass:' + pass + ' encrypt IN:' + text);
  var key = Sha256.hash(pass);
  var encrypted = Aes.Ctr.encrypt(text, key, 256);
  //console.log('encrypt OUT:' + encrypted);
  return encrypted;
}

function decrypt (text, pass) {
  //console.log('pass:' + pass + ' decrypt IN:' + text);
  var key = Sha256.hash(pass);
  var decrypted = Aes.Ctr.decrypt(text, key, 256);
  //console.log('decrypt OUT:' + decrypted);
  return decrypted;
}

function backToTop() {
  $("html, body").animate({ scrollTop: 0 }, "slow");
}

function passwordsMatch() {
  console.log("passwordsMatch()");

  if( $('#password').val() == $('#password2').val() ) {

    $('#passGroup').removeClass("has-error");
    $('#passwordError').addClass("hidden");

    return true;
  }

  $('#passGroup').addClass("has-error");
  $('#passwordError').removeClass("hidden");

  backToTop();

  return false;
}

function onMessageChange() {
    console.log("onMessageChange()");
    var m = $('#message');

    $("#count").text( m.val().length  );

    m.autosize({ append: '\n'});
    m.trigger('autosize.resize');
}

function messageUpdated() {
  $('#message').select();
  onMessageChange();
}

function clearMessage() {
  $('#message').val('');
  onMessageChange();
}

function pageEncrypt() {
  console.log("pageEncrypt()");
  if ( passwordsMatch() ) {
    $('#message').val( encrypt( $('#message').val(), $('#password').val() ) );
    messageUpdated();
  }
}

function pageDecrypt() {
  console.log("pageDecrypt()");
  if( passwordsMatch() ) {
    $('#message').val( decrypt( $('#message').val(), $('#password').val() ) );
    messageUpdated();
  }
}

$( function() {

  $("#message").change( onMessageChange );
  $("#message").keyup( onMessageChange );

  $('#encrypt').click( pageEncrypt );
  $('#decrypt').click( pageDecrypt );

  $('#backToTop').click( backToTop );
  $('#reset').click( clearMessage );

  onMessageChange();

  $('#splashscreen').delay( 1000 ).fadeOut('slow');

/*
  var client = new Dropbox.Client({ key: "dzdofhi3xrasyw8" });
  client.authDriver(new Dropbox.AuthDriver.Popup({
    receiverUrl: "https://quickencrypt.io/oauth/dropbox.html"}));

  $('#dbChooseFile').click( function () {
    client.authenticate(function(error, client) {
      if (error) {
        alert( error );
        return;
      }

      var fn = prompt("File path");
      if(fn) {
        client.readFile(fn, function(error, data) {
          if (error) {
            return alert(error);
          }
          $('#message').val( data );
          onMessageChange();
        });
      }
    });
  });

*/

  dbChooseOptions = {
    success: function(files) {
      // name, link, bytes, icon, thumbnailLink
      $('#message').load( files[0].link, function () {
        onMessageChange();
      });
    },
    cancel: function() {

    },
    linkType: "direct", // or "direct"
    multiselect: false, // or true
    extensions: ['.md', '.txt', '.markdown', '.rsa'],
  };

  $('#dbChooseFile').click( function () {
    if( Dropbox.isBrowserSupported() )
      Dropbox.choose( dbChooseOptions );
  });

  console.log('Page loaded');
});
<commit_msg>Update app.js<commit_after>function getUrlVars()
{
    var vars = [], hash;
    var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
    for(var i = 0; i < hashes.length; i++)
    {
        hash = hashes[i].split('=');
        vars.push(hash[0]);
        vars[hash[0]] = hash[1];
    }
    return vars;
}

function encrypt(text, pass) {
  //console.log('pass:' + pass + ' encrypt IN:' + text);
  var key = Sha256.hash(pass);
  var encrypted = Aes.Ctr.encrypt(text, key, 256);
  //console.log('encrypt OUT:' + encrypted);
  return encrypted;
}

function decrypt (text, pass) {
  //console.log('pass:' + pass + ' decrypt IN:' + text);
  var key = Sha256.hash(pass);
  var decrypted = Aes.Ctr.decrypt(text, key, 256);
  //console.log('decrypt OUT:' + decrypted);
  return decrypted;
}

function backToTop() {
  $("html, body").animate({ scrollTop: 0 }, "slow");
}

function passwordsMatch() {
  console.log("passwordsMatch()");

  if( $('#password').val() == $('#password2').val() ) {

    $('#passGroup').removeClass("has-error");
    $('#passwordError').addClass("hidden");

    return true;
  }

  $('#passGroup').addClass("has-error");
  $('#passwordError').removeClass("hidden");

  backToTop();

  return false;
}

function onMessageChange() {
    console.log("onMessageChange()");
    var m = $('#message');

    $("#count").text( m.val().length  );

    m.autosize({ append: '\n'});
    m.trigger('autosize.resize');
}

function messageUpdated() {
  $('#message').select();
  onMessageChange();
}

function clearMessage() {
  $('#message').val('');
  onMessageChange();
}

function pageEncrypt() {
  console.log("pageEncrypt()");
  if ( passwordsMatch() ) {
    $('#message').val( encrypt( $('#message').val(), $('#password').val() ) );
    messageUpdated();
  }
}

function pageDecrypt() {
  console.log("pageDecrypt()");
  if( passwordsMatch() ) {
    $('#message').val( decrypt( $('#message').val(), $('#password').val() ) );
    messageUpdated();
  }
}

$( function() {

  $("#message").change( onMessageChange );
  $("#message").keyup( onMessageChange );

  $('#encrypt').click( pageEncrypt );
  $('#decrypt').click( pageDecrypt );

  $('#backToTop').click( backToTop );
  $('#reset').click( clearMessage );

  onMessageChange();

  $('#splashscreen').delay( 1000 ).fadeOut('slow');

/*
  var client = new Dropbox.Client({ key: "dzdofhi3xrasyw8" });
  client.authDriver(new Dropbox.AuthDriver.Popup({
    receiverUrl: "https://quickencrypt.io/oauth/dropbox.html"}));

  $('#dbChooseFile').click( function () {
    client.authenticate(function(error, client) {
      if (error) {
        alert( error );
        return;
      }

      var fn = prompt("File path");
      if(fn) {
        client.readFile(fn, function(error, data) {
          if (error) {
            return alert(error);
          }
          $('#message').val( data );
          onMessageChange();
        });
      }
    });
  });

*/

  dbChooseOptions = {
    success: function(files) {
      // name, link, bytes, icon, thumbnailLink
      $('#message').load( files[0].link, function () {
        onMessageChange();
      });
    },
    cancel: function() {

    },
    linkType: "direct", // or "direct"
    multiselect: false, // or true
    extensions: ['.md', '.txt', '.markdown', '.rsa'],
  };

  $('#dbChooseFile').click( function () {
    if( Dropbox.isBrowserSupported() )
      Dropbox.choose( dbChooseOptions );
  });

  // Dropbox.save("http://google.com", "google.txt");

  console.log('Page loaded');
});
<|endoftext|>


<commit_before>(function($) {

	$.fn.shopaholic = function(params) {
		var options = $.extend({
			data: '/data/items.json' //This line adding another parameter to the options... ```expands``` it
		}, params);
		var Super = this;
		var jsonData = {};
		var models = {
			item: function(item) {
				return '
' +
						'
' +
							'
' +
								'' +
							'
' +
							'
' + item.name + '+
' +
						'
' +
					'
';
			}
		}

		var render = {
			items: function(data){ //Renders Items
				$.each( data.items, function( key, value ) {
					$(Super).append(models.item(value));
				});
			},
			desc: function(){ //Renders Description
				options.header.append(''); //Add image
				options.header.append('
' + jsonData.name + '
'); //Add name
				options.header.append('
' + jsonData.description + '
');//Add description

				$('head').append('<title>' + jsonData.name + '</title>'); //Add name
			},
			cart: function(){

			}
		}

		$.getJSON( 'data/items.json', function( data ) {
			jsonData = data; //Saving data
			render.desc(); //Rendering description
			render.items(data); //Rendering items
		});

	};

}(jQuery));<commit_msg>Added event handler.<commit_after>(function($) {

	$.fn.shopaholic = function(params) {
		var options = $.extend({
			data: '/data/items.json' //This line adding another parameter to the options... ```expands``` it
		}, params);
		var Super = this;
		var jsonData = {};
		var models = {
			item: function(item) {
				return '
' +
						'
' +
							'
' +
								'' +
							'
' +
							'
' + item.name + '+
' +
						'
' +
					'
';
			}
		}

		var render = {
			items: function(data){ //Renders Items
				$.each( data.items, function( key, value ) {
					$(Super).append(models.item(value));
				});
				$('a.button').click(function(){ //Adds click handler
					console.log(this);
				})

			},
			desc: function(data){ //Renders Description
				options.header.append(''); //Add image
				options.header.append('
' + data.name + '
'); //Add name
				options.header.append('
' + data.description + '
');//Add description

				$('head').append('<title>' + data.name + '</title>'); //Add name
			},
			cart: function(){

			}
		}

		$.getJSON( 'data/items.json', function( data ) {
			jsonData = data; //Saving data
			render.desc(data); //Rendering description
			render.items(data); //Rendering items
		});
	};

}(jQuery));<|endoftext|>


<commit_before><commit_msg>Added basic of jQuery plugin.<commit_after>(function($) {

	$.fn.shopaholic = function(params) {
		var options = $.extend({
			data: '/data/items.json' //This line adding another parameter to the options... ```expands``` it
		}, params);
		$.getJSON( 'data/items.json', function( data ) {
			$.each( data.items, function( key, value ) {
				console.log(value)
			});
		});
	};

}(jQuery));<|endoftext|>


<commit_before>window.addEventListener('DOMContentLoaded', function() {

    'use strict';

    var searchform = $("#searchform"),
        searchbox = $("#searchbox"),
        searchsubmit = $("#searchsubmit"),
        resultsbox = $("#resultsbox"),
        wobblebar = $(".wobblebar"),
        results = [],
        finder = new Applait.Finder({type: "sdcard", minSearchLength: 2}),
        searchcompletecount = 0,
        totalfilematchcount = 0;

    var isactivity = false;

    /**
     * Now, handle activities
     */
    navigator.mozSetMessageHandler('activity', function(activityRequest) {
        var option = activityRequest.source;
        isactivity = true;

        if (option.name === "pick") {
            searchbox.focus();
            $(document).on("finderFilePicked", function (event, filepicked) {
                if (filepicked) {
                    activityRequest.postResult({
                        type: filepicked.type,
                        blob: filepicked
                    });
                } else {
                    activityRequest.postError("Unable to pick a file.");
                }
            });
        }
    });

    /**
     * Clean up artefacts to clear up memory
     */
    var cleanupsearch = function () {
        results = [];
        resultsbox.html("");
        searchcompletecount = 0;
        totalfilematchcount = 0;
    };

    /**
     * Interactions when search has started
     */
    var startprogress = function () {
        searchbox.attr('disabled', 'disabled');
        searchsubmit.removeClass('active');
        wobblebar.removeClass("hide");
    };

    /**
     * Interactions when search has ended
     */
    var stopprogress = function () {
        searchbox.removeAttr('disabled');
        searchsubmit.addClass('active');
        wobblebar.addClass("hide");
    };

    /**
     * Trigger search
     */
    var searchtrigger = function (event) {
        event.preventDefault();

        searchbox.val(searchbox.val().trim()).blur();
        finder.search(searchbox.val());
    };

    finder.events.addListener("searchCancelled", function () {
        cleanupsearch();
        stopprogress();
        searchbox.focus();
        wobblebar.addClass("hide");
    });

    finder.events.addListener("empty", function (needle) {
        cleanupsearch();
        stopprogress();
        searchbox.focus();
        resultsbox.append($("

No results found.

"));
    });

    finder.events.on("fileFound", function (file, fileinfo, storageName) {
        results.push({ file: file, fileinfo: fileinfo, storageName: storageName });
    });

    finder.events.on("searchBegin", function (needle) {
        cleanupsearch();
        startprogress();
    });

    finder.events.on("searchComplete", function (storageName, needle, filematchcount) {

        searchcompletecount++;
        totalfilematchcount += filematchcount;

        if (searchcompletecount >= finder.storages.length) {

            results.length && results.forEach(function (result, i) {
                var resultitem = $("

").attr({
                    "data-file" : result.file.name,
                    "data-type" : result.file.type,
                    "data-storage": result.storageName,
                    "data-result-index": i,
                    "class" : "resultitem panel"
                });
                resultitem.append($("
" + result.fileinfo.name + "
" + result.fileinfo.path + ""));
                resultsbox.append(resultitem);
            });

            $(".resultitem").bind("click", function (event) {
                if (isactivity) {
                    $(document).trigger("finderFilePicked", [results[$(this).attr("data-result-index")].file]);
                } else {
                    var activityname = "open";

                    if ($.inArray($(this).attr("data-type"), ["application/pdf"]) > -1) {
                        activityname = "view";
                    }

                    var activity = new MozActivity({
                        name: activityname,
                        data: {
                            type: $(this).attr("data-type"),
                            blob: results[$(this).attr("data-result-index")].file
                        }
                    });
                }
            });

            stopprogress();

            if(!totalfilematchcount) {
                resultsbox.append($("

No results found.

"));
            }

            searchcompletecount = 0;
            totalfilematchcount = 0;
        }
    });

    /**
     * Bind search trigger to search form submit
     */
    searchform.bind("submit", searchtrigger);
    $(searchsubmit.selector + ".active").bind("click", searchtrigger);

    /**
     * UI sweetness
     */
    searchbox.focus();
    $("#menu-btn").bind("click", function (event) {
        event.preventDefault();
        searchbox.blur();
        document.querySelector("x-flipbox").toggle();
    });

    $("#reset-btn").bind("click", function (event) {
        event.preventDefault();
        cleanupsearch();
        stopprogress();
        searchbox.val("");;
    });
});
<commit_msg>Fix reset button<commit_after>window.addEventListener('DOMContentLoaded', function() {

    'use strict';

    var searchform = $("#searchform"),
        searchbox = $("#searchbox"),
        searchsubmit = $("#searchsubmit"),
        resultsbox = $("#resultsbox"),
        wobblebar = $(".wobblebar"),
        results = [],
        finder = new Applait.Finder({type: "sdcard", minSearchLength: 2}),
        searchcompletecount = 0,
        totalfilematchcount = 0;

    var isactivity = false;

    /**
     * Now, handle activities
     */
    navigator.mozSetMessageHandler('activity', function(activityRequest) {
        var option = activityRequest.source;
        isactivity = true;

        if (option.name === "pick") {
            searchbox.focus();
            $(document).on("finderFilePicked", function (event, filepicked) {
                if (filepicked) {
                    activityRequest.postResult({
                        type: filepicked.type,
                        blob: filepicked
                    });
                } else {
                    activityRequest.postError("Unable to pick a file.");
                }
            });
        }
    });

    /**
     * Clean up artefacts to clear up memory
     */
    var cleanupsearch = function () {
        results = [];
        resultsbox.html("");
        searchcompletecount = 0;
        totalfilematchcount = 0;
    };

    /**
     * Interactions when search has started
     */
    var startprogress = function () {
        searchbox.attr('disabled', 'disabled');
        searchsubmit.removeClass('active');
        wobblebar.removeClass("hide");
    };

    /**
     * Interactions when search has ended
     */
    var stopprogress = function () {
        searchbox.removeAttr('disabled');
        searchsubmit.addClass('active');
        wobblebar.addClass("hide");
    };

    /**
     * Trigger search
     */
    var searchtrigger = function (event) {
        event.preventDefault();

        searchbox.val(searchbox.val().trim()).blur();
        finder.search(searchbox.val());
    };

    finder.events.addListener("searchCancelled", function () {
        cleanupsearch();
        stopprogress();
        searchbox.focus();
        wobblebar.addClass("hide");
    });

    finder.events.addListener("empty", function (needle) {
        cleanupsearch();
        stopprogress();
        searchbox.focus();
        resultsbox.append($("

No results found.

"));
    });

    finder.events.on("fileFound", function (file, fileinfo, storageName) {
        results.push({ file: file, fileinfo: fileinfo, storageName: storageName });
    });

    finder.events.on("searchBegin", function (needle) {
        cleanupsearch();
        startprogress();
    });

    finder.events.on("searchComplete", function (storageName, needle, filematchcount) {

        searchcompletecount++;
        totalfilematchcount += filematchcount;

        if (searchcompletecount >= finder.storages.length) {

            results.length && results.forEach(function (result, i) {
                var resultitem = $("

").attr({
                    "data-file" : result.file.name,
                    "data-type" : result.file.type,
                    "data-storage": result.storageName,
                    "data-result-index": i,
                    "class" : "resultitem panel"
                });
                resultitem.append($("
" + result.fileinfo.name + "
" + result.fileinfo.path + ""));
                resultsbox.append(resultitem);
            });

            $(".resultitem").bind("click", function (event) {
                if (isactivity) {
                    $(document).trigger("finderFilePicked", [results[$(this).attr("data-result-index")].file]);
                } else {
                    var activityname = "open";

                    if ($.inArray($(this).attr("data-type"), ["application/pdf"]) > -1) {
                        activityname = "view";
                    }

                    var activity = new MozActivity({
                        name: activityname,
                        data: {
                            type: $(this).attr("data-type"),
                            blob: results[$(this).attr("data-result-index")].file
                        }
                    });
                }
            });

            stopprogress();

            if(!totalfilematchcount) {
                resultsbox.append($("

No results found.

"));
            }

            searchcompletecount = 0;
            totalfilematchcount = 0;
        }
    });

    /**
     * Bind search trigger to search form submit
     */
    searchform.bind("submit", searchtrigger);
    $(searchsubmit.selector + ".active").bind("click", searchtrigger);

    /**
     * UI sweetness
     */
    searchbox.focus();
    $("#menu-btn").bind("click", function (event) {
        event.preventDefault();
        searchbox.blur();
        document.querySelector("x-flipbox").toggle();
    });

    $("#reset-btn").bind("click", function (event) {
        event.preventDefault();
        cleanupsearch();
        stopprogress();
        searchbox.val("").focus();
    });
});
<|endoftext|>