<commit_before>//Class for the Link properties tab that appears when link settings are clicked.

var LinkInspector = Backbone.View.extend({

  className: 'link-inspector',

  refinementtemplate: [
    'Refinement Relationship',
    '
',
    '<select class="sublink-type">',
      '<option value=and>And-Decomposition</option>',
      '<option value=or>Or-Decomposition (Means-end)</option>',
    '</select>',
    '
',
    '
'
  ].join(''),
  neededbytemplate: [
    'NeededBy Relationship',
    '
',
    '
',
    '
'
  ].join(''),
  contributiontemplate: [
    'Contribution Relationship',
    '
',
    '<select class="sublink-type">',
      '<option value=makes>Makes</option>',
      '<option value=breaks>Breaks</option>',
      '<option value=helps>Helps</option>',
      '<option value=hurts>Hurts</option>',
    '</select>',
    '
',
    '
'
  ].join(''),
  qualificationtemplate: [
    'Qualification Relationship',
    '
',
    '
',
    '
'
  ].join(''),
  errortemplate: [
    'Error',
    '
',
    '
 This is usually caused by 3 possible reasons:
',
    '

 Link is not connected to both source and target node

 You are connecting from resource to goal

 You are connecting from resource to resource
',
    '
',
    '
'
  ].join(''),
  actortemplate: [
      ' Link Type
',
      '<select class="sublink-type">',
        '<option value="is-a">is-a</option>',
        '<option value="participates-in">participates-in</option>',
      '</select>
'].join(''),

  events: {
    'change .sublink-type': 'updateCell',
  },

  //Method to create the Link Inspector using the template.
  render: function(cellView, linktype) {
    this._cellView = cellView;
    var cell = this._cellView.model;
    var type = cellView.model.attributes.labels[0].attrs.text.text

    this.relationTextA = ["And-Decomposition", "Or-Decomposition (Means-end)", "Depends"];
    this.relationTextB = ["Makes", "Breaks", "Helps", "Hurts"];
    this.relationValA = ["and", "or", "depends"];
    this.relationValB = ["makes", "breaks", "helps", "hurts"];
    // select template
    if (cell.prop("linktype")){
      this.$el.html(_.template(this.actortemplate)());
    }else{
      // Choose template based on linktype: Contribution, refinement, error, neededby, qualification
      switch(linktype){
        case 'Contribution':
          this.$el.html(_.template(this.contributiontemplate)());
          break;
        case 'Refinement':
          this.$el.html(_.template(this.refinementtemplate)());
          break;
        case 'Qualification':
          this.$el.html(_.template(this.qualificationtemplate)());
          break;
        case 'NeededBy':
          this.$el.html(_.template(this.neededbytemplate)());
          break;
        default:
          this.$el.html(_.template(this.errortemplate)());
      }

    }

    // already intialized previously
    if (cell.prop("sublink-type")){
      var val = cell.prop("sublink-type").split("|");

      // normal relation
      if (val.length == 1){
        this.$('.sublink-type').val(val[0]);
      }
    }

    cell.on('remove', function() {
      this.$el.html('');
    }, this);

  },

  //Whenever something is changed in the inspector, make the corresponding change to the link in the model.
  updateCell: function() {
    var link = this._cellView.model;
    this._cellView.model.prop("sublink-type", this.$('.sublink-type').val());
    var linktype = link.attr(".link-type");
    if (linktype == "Refinement"){
      if (this._cellView.model.prop("sublink-type") == 'or'){
        link.attr({
          '.connection': {stroke: '#000000', 'stroke-dasharray': '0 0'},
          '.marker-source': {'d': 'M 0 0'},
          '.marker-target': {stroke: '#000000', 'stroke-width': 1, "d": 'M 10 0 L 10 10 M 10 5 L 0 5' }
        });
        link.label(0 ,{position: 0.5, attrs: {text: {text: 'or'}}});

      }else if (this._cellView.model.prop("sublink-type") == 'and'){
        link.attr({
          '.connection': {stroke: '#000000', 'stroke-dasharray': '0 0'},
          '.marker-source': {'d': 'M 0 0'},
          '.marker-target': {stroke: '#000000', "d": 'M 10 0 L 0 5 L 10 10 z'}
        });
        link.label(0 ,{position: 0.5, attrs: {text: {text: 'and'}}});
      }
      else {
        console.log('Error, this should not happen');
      }
    }

    else if (linktype == "Contribution"){
      link.attr({
        '.connection': {stroke: '#000000', 'stroke-dasharray': '0 0'},
        '.marker-source': {'d': 'M 0 0'},
        '.marker-target': {stroke: '#000000', "d": 'M 12 -3 L 5 5 L 12 13 M 5 5 L 30 5'}
      });
      link.label(0 ,{position: 0.5, attrs: {text: {text: link.prop("sublink-type")}}});
    }
    else if (linktype == "NeededBy"){
      link.attr({
          '.connection': {stroke: '#000000', 'stroke-dasharray': '0 0'},
          '.marker-source': {'d': 'M 0 0'},
          '.marker-target': {stroke: '#000000', "d": 'M-4,0a4,4 0 1,0 8,0a4,4 0 1,0 -8,0'}
        });
    }
    else if (linktype == "Qualification"){
      link.attr({
        '.connection': {stroke: '#000000', 'stroke-dasharray': '5 2'},
        '.marker-source': {'d': 'M 0 0'},
        '.marker-target': {'d': 'M 0 0'}
      });
    }
    else{
      link.attr({
        '.connection': {stroke: '#000000', 'stroke-dasharray': '0 0'},
        '.marker-source': {'d': 'M 0 0'},
        '.marker-target': {stroke: '#000000', "d": 'M 12 -3 L 5 5 L 12 13 M 5 5 L 30 5'}
      });
      link.label(0 ,{position: 0.5, attrs: {text: {text: link.prop("sublink-type")}}});
    }

  },

  //Displays the additional options when delayed propagation is checked.
  checkboxHandler: function(e){
    if (e.currentTarget.checked){
      document.getElementById("hidden").removeAttribute("style");
    }
    else{
      document.getElementById("hidden").setAttribute("style", "display:none");
    }
  },

  clear: function(){
    this.$el.html('');
  }
});
<commit_msg>Updated link inspector to display dependency link<commit_after>//Class for the Link properties tab that appears when link settings are clicked.

var LinkInspector = Backbone.View.extend({

  className: 'link-inspector',

  refinementtemplate: [
    'Refinement Relationship',
    '
',
    '<select class="sublink-type">',
      '<option value=and>And-Decomposition</option>',
      '<option value=or>Or-Decomposition (Means-end)</option>',
    '</select>',
    '
',
    '
'
  ].join(''),
  neededbytemplate: [
    'NeededBy Relationship',
    '
',
    '
',
    '
'
  ].join(''),
  contributiontemplate: [
    'Contribution Relationship',
    '
',
    '<select class="sublink-type">',
      '<option value=makes>Makes</option>',
      '<option value=breaks>Breaks</option>',
      '<option value=helps>Helps</option>',
      '<option value=hurts>Hurts</option>',
    '</select>',
    '
',
    '
'
  ].join(''),
  qualificationtemplate: [
    'Qualification Relationship',
    '
',
    '
',
    '
'
  ].join(''),
  dependencytemplate: [
    'Dependency',
    '
',
    '
',
    '
'
  ].join(''),
  errortemplate: [
    'Error',
    '
',
    '
 This is usually caused by 3 possible reasons:
',
    '

 Link is not connected to both source and target node

 You are connecting from resource to goal

 You are connecting from resource to resource
',
    '
',
    '
'
  ].join(''),
  actortemplate: [
      ' Actor Association Link
',
      '<select class="sublink-type">',
        '<option value="is-a">is-a</option>',
        '<option value="participates-in">participates-in</option>',
      '</select>
'].join(''),

  events: {
    'change .sublink-type': 'updateCell',
  },

  //Method to create the Link Inspector using the template.
  render: function(cellView, linktype) {
    this._cellView = cellView;
    var cell = this._cellView.model;
    var type = cellView.model.attributes.labels[0].attrs.text.text

    this.relationTextA = ["And-Decomposition", "Or-Decomposition (Means-end)", "Depends"];
    this.relationTextB = ["Makes", "Breaks", "Helps", "Hurts"];
    this.relationValA = ["and", "or", "depends"];
    this.relationValB = ["makes", "breaks", "helps", "hurts"];

    // Choose template based on linktype: Contribution, refinement, error, neededby, qualification, actor or dependency
    console.log(linktype);
    switch(linktype){
      case 'Contribution':
        this.$el.html(_.template(this.contributiontemplate)());
        break;
      case 'Refinement':
        this.$el.html(_.template(this.refinementtemplate)());
        break;
      case 'Qualification':
        this.$el.html(_.template(this.qualificationtemplate)());
        break;
      case 'NeededBy':
        this.$el.html(_.template(this.neededbytemplate)());
        break;
      case 'Actor':
        this.$el.html(_.template(this.actortemplate)());
        break;
      case 'Dependency':
        this.$el.html(_.template(this.dependencytemplate)());
        break;

      default:
        this.$el.html(_.template(this.errortemplate)());
    }

    // already intialized previously
    if (cell.prop("sublink-type")){
      var val = cell.prop("sublink-type").split("|");

      // normal relation
      if (val.length == 1){
        this.$('.sublink-type').val(val[0]);
      }
    }

    cell.on('remove', function() {
      this.$el.html('');
    }, this);

  },

  //Whenever something is changed in the inspector, make the corresponding change to the link in the model.
  updateCell: function() {
    var link = this._cellView.model;
    this._cellView.model.prop("sublink-type", this.$('.sublink-type').val());
    var linktype = link.attr(".link-type");
    if (linktype == "Refinement"){
      if (this._cellView.model.prop("sublink-type") == 'or'){
        link.attr({
          '.connection': {stroke: '#000000', 'stroke-dasharray': '0 0'},
          '.marker-source': {'d': 'M 0 0'},
          '.marker-target': {stroke: '#000000', 'stroke-width': 1, "d": 'M 10 0 L 10 10 M 10 5 L 0 5' }
        });
        link.label(0 ,{position: 0.5, attrs: {text: {text: 'or'}}});

      }else if (this._cellView.model.prop("sublink-type") == 'and'){
        link.attr({
          '.connection': {stroke: '#000000', 'stroke-dasharray': '0 0'},
          '.marker-source': {'d': 'M 0 0'},
          '.marker-target': {stroke: '#000000', "d": 'M 10 0 L 0 5 L 10 10 z'}
        });
        link.label(0 ,{position: 0.5, attrs: {text: {text: 'and'}}});
      }
      else {
        console.log('Error, this should not happen');
      }
    }

    else if (linktype == "Contribution"){
      link.attr({
        '.connection': {stroke: '#000000', 'stroke-dasharray': '0 0'},
        '.marker-source': {'d': 'M 0 0'},
        '.marker-target': {stroke: '#000000', "d": 'M 12 -3 L 5 5 L 12 13 M 5 5 L 30 5'}
      });
      link.label(0 ,{position: 0.5, attrs: {text: {text: link.prop("sublink-type")}}});
    }
    else if (linktype == "NeededBy"){
      link.attr({
          '.connection': {stroke: '#000000', 'stroke-dasharray': '0 0'},
          '.marker-source': {'d': 'M 0 0'},
          '.marker-target': {stroke: '#000000', "d": 'M-4,0a4,4 0 1,0 8,0a4,4 0 1,0 -8,0'}
        });
    }
    else if (linktype == "Qualification"){
      link.attr({
        '.connection': {stroke: '#000000', 'stroke-dasharray': '5 2'},
        '.marker-source': {'d': 'M 0 0'},
        '.marker-target': {'d': 'M 0 0'}
      });
    }
    else{
      link.attr({
        '.connection': {stroke: '#000000', 'stroke-dasharray': '0 0'},
        '.marker-source': {'d': 'M 0 0'},
        '.marker-target': {stroke: '#000000', "d": 'M 12 -3 L 5 5 L 12 13 M 5 5 L 30 5'}
      });
      link.label(0 ,{position: 0.5, attrs: {text: {text: link.prop("sublink-type")}}});
    }

  },

  //Displays the additional options when delayed propagation is checked.
  checkboxHandler: function(e){
    if (e.currentTarget.checked){
      document.getElementById("hidden").removeAttribute("style");
    }
    else{
      document.getElementById("hidden").setAttribute("style", "display:none");
    }
  },

  clear: function(){
    this.$el.html('');
  }
});
<|endoftext|>


<commit_before>var colors = ["red", "green", "orange", "blue", "purple", "pink"]
var color_i = 0;

function Block(prev, time, miner) {
	this._prev = function() {
		return prev;
	}

	if (miner)
		this.credit = miner.id;
	else
		this.credit = false;

	this.id = StateTransition.rand();
	this.time = time;
	this.color = colors[color_i]
	if (typeof this.color == "undefined") {
		color_i = 0;
		this.color = colors[color_i]
	} else {
		color_i++;
	}

	if (prev) {
		this.h = prev.h + 1;
		this.prev = prev.id;
		this.difficulty = prev.difficulty;
		this.work = prev.work + prev.difficulty;

		// TODO: difficulty adjustment
		if (!(this.h % this.difficulty_adjustment_period)) {
			this.difficultyAdjustment()
		}
	}
	else {
		this.h = 0;
		this.prev = false;
		this.difficulty = 110000;
		this.work = 0;
	}
}

Block.prototype = {
	target_avg_between_blocks: 2.5 * 60 * 1000, // 2.5 minutes = litecoin
	difficulty_adjustment_period: 2016,

	difficultyAdjustment: function() {
		var total = 0;
		var last = this.time;
		var cur = this._prev();

		for (var i=0;i<this.difficulty_adjustment_period;i++) {
			total += last - cur.time;
			last = cur.time;
			cur = cur._prev()
		}
		var avg = total / this.difficulty_adjustment_period;

		var old = this.difficulty;
		this.difficulty *= this.target_avg_between_blocks / avg;

		console.log("(h=" + this.h + ") difficulty adjustment " + (this.target_avg_between_blocks / avg) + "x")
	}
}

var GenesisBlock = new Block(false, 0);

function Chainstate(head, self) {
	this.self = self;
	this.forward(head)
}

Chainstate.prototype = {
	forward: function(b) {
		this.self.setColor(b.color)
		this.head = b
		// TODO: run transactions here
	},
	reverse: function() {
		this.head = this.head._prev()
	},
	/*
		This function attempts to enter the block into the chainstate.
	*/
	enter: function(block, force) {
		if (block == this.head)
			return -1

		if (typeof force == "undefined")
			force = false;
		else if (force)
			this.self.log("\tchainstate forcefully entering branch")

		var numorphan = -1;

		if ((this.head.work < block.work) || force) {
			// the current head is now obsolete

			numorphan = 0;
			var forwards = []
			var cur = block

			reorg:
			while(true) {
				if (cur.h > this.head.h) {
					forwards.push(cur)
					cur = cur._prev()
				} else if (cur == this.head) {
					while(true) {
						if (forwards.length > 0) {
							this.forward(forwards.pop())
						} else {
							break reorg;
						}
					}
				} else {
					numorphan++;
					this.reverse()
				}
			}
		} else if (this.head.work == block.work) {
			this.self.log("\tblock rejected; already seen one at this chainlength")
		}

		return numorphan
	}
}

function Blockchain(self, instance) {
	if (typeof instance == "undefined")
		instance = "blockchain"

	self[instance] = this;
	this.chainstate = new Chainstate(GenesisBlock, self);

	this.onBlock = function(b) {
		this.chainstate.enter(b)
	}

	this.onMine = function(b, force) {
		if (this.chainstate.enter(b, force) != -1) {
			self.log("\tpushing new inventory object")
			self.inventory.createObj("block", {name:b.id,block:b})
		}
	}

	this.mineBlock = function() {
		var newb = new Block(this.chainstate.head, self.now(), self)

		this.onMine(newb)
	}

	self.on("inv:block", function(from, o) {
		this.onBlock(o.obj.block)
	}, this)

	self.inventory.subscribe("block")
}<commit_msg>use bitcoin target avg between blocks<commit_after>var colors = ["red", "green", "orange", "blue", "purple", "pink"]
var color_i = 0;

function Block(prev, time, miner) {
	this._prev = function() {
		return prev;
	}

	if (miner)
		this.credit = miner.id;
	else
		this.credit = false;

	this.id = StateTransition.rand();
	this.time = time;
	this.color = colors[color_i]
	if (typeof this.color == "undefined") {
		color_i = 0;
		this.color = colors[color_i]
	} else {
		color_i++;
	}

	if (prev) {
		this.h = prev.h + 1;
		this.prev = prev.id;
		this.difficulty = prev.difficulty;
		this.work = prev.work + prev.difficulty;

		// TODO: difficulty adjustment
		if (!(this.h % this.difficulty_adjustment_period)) {
			this.difficultyAdjustment()
		}
	}
	else {
		this.h = 0;
		this.prev = false;
		this.difficulty = 110000;
		this.work = 0;
	}
}

Block.prototype = {
	target_avg_between_blocks: 10 * 60 * 1000, // 2.5 minutes = litecoin
	difficulty_adjustment_period: 2016,

	difficultyAdjustment: function() {
		var total = 0;
		var last = this.time;
		var cur = this._prev();

		for (var i=0;i<this.difficulty_adjustment_period;i++) {
			total += last - cur.time;
			last = cur.time;
			cur = cur._prev()
		}
		var avg = total / this.difficulty_adjustment_period;

		var old = this.difficulty;
		this.difficulty *= this.target_avg_between_blocks / avg;

		console.log("(h=" + this.h + ") difficulty adjustment " + (this.target_avg_between_blocks / avg) + "x")
	}
}

var GenesisBlock = new Block(false, 0);

function Chainstate(head, self) {
	this.self = self;
	this.forward(head)
}

Chainstate.prototype = {
	forward: function(b) {
		this.self.setColor(b.color)
		this.head = b
		// TODO: run transactions here
	},
	reverse: function() {
		this.head = this.head._prev()
	},
	/*
		This function attempts to enter the block into the chainstate.
	*/
	enter: function(block, force) {
		if (block == this.head)
			return -1

		if (typeof force == "undefined")
			force = false;
		else if (force)
			this.self.log("\tchainstate forcefully entering branch")

		var numorphan = -1;

		if ((this.head.work < block.work) || force) {
			// the current head is now obsolete

			numorphan = 0;
			var forwards = []
			var cur = block

			reorg:
			while(true) {
				if (cur.h > this.head.h) {
					forwards.push(cur)
					cur = cur._prev()
				} else if (cur == this.head) {
					while(true) {
						if (forwards.length > 0) {
							this.forward(forwards.pop())
						} else {
							break reorg;
						}
					}
				} else {
					numorphan++;
					this.reverse()
				}
			}
		} else if (this.head.work == block.work) {
			this.self.log("\tblock rejected; already seen one at this chainlength")
		}

		return numorphan
	}
}

function Blockchain(self, instance) {
	if (typeof instance == "undefined")
		instance = "blockchain"

	self[instance] = this;
	this.chainstate = new Chainstate(GenesisBlock, self);

	this.onBlock = function(b) {
		this.chainstate.enter(b)
	}

	this.onMine = function(b, force) {
		if (this.chainstate.enter(b, force) != -1) {
			self.log("\tpushing new inventory object")
			self.inventory.createObj("block", {name:b.id,block:b})
		}
	}

	this.mineBlock = function() {
		var newb = new Block(this.chainstate.head, self.now(), self)

		this.onMine(newb)
	}

	self.on("inv:block", function(from, o) {
		this.onBlock(o.obj.block)
	}, this)

	self.inventory.subscribe("block")
}<|endoftext|>


<commit_before>(function ($, window, chat) {
    var trimRoomHistoryMaxMessages = 200;

    function glowTab($tab, n) {
        // Stop if we're not unread anymore
        if (!$tab.hasClass('unread')) {
            return;
        }

        // Go light
        $tab.animate({ backgroundColor: '#e5e5e5', color: '#77d42a' }, 800, function () {
            // Stop if we're not unread anymore
            if (!$tab.hasClass('unread')) {
                return;
            }

            n--;

            // Check if we're on our last glow
            if (n !== 0) {
                // Go dark
                $tab.animate({ backgroundColor: '#164C85', color: '#ffffff' }, 800, function () {
                    // Glow the tab again
                    glowTab($tab, n);
                });
            }
            else {
                // Leave the tab highlighted
                $tab.animate({ backgroundColor: '#043C4C', color: '#ffffff' }, 800);
            }
        });
    }

    function getUserClassName(userName) {
        return '[data-name="' + userName + '"]';
    }

    function Room($tab, $usersContainer, $usersOwners, $usersActive, $messages, $roomTopic) {
        this.tab = $tab;
        this.users = $usersContainer;
        this.owners = $usersOwners;
        this.activeUsers = $usersActive;
        this.messages = $messages;
        this.roomTopic = $roomTopic;

        this.templates = {
            separator: $('#message-separator-template')
        };

    }

    Room.prototype.isLocked = function () {
        return this.tab.hasClass('locked');
    };

    Room.prototype.isLobby = function () {
        return this.tab.hasClass('lobby');
    };

    Room.prototype.hasUnread = function () {
        return this.tab.hasClass('unread');
    };

    Room.prototype.hasMessages = function () {
        return this.tab.data('messages');
    };

    Room.prototype.updateMessages = function (value) {
        this.tab.data('messages', value);
    };

    Room.prototype.getUnread = function () {
        return this.tab.data('unread') || 0;
    };

    Room.prototype.hasSeparator = function () {
        return this.messages.find('.message-separator').length > 0;
    };

    Room.prototype.needsSeparator = function () {
        if (this.isActive()) {
            return false;
        }
        return this.isInitialized() && this.getUnread() === 5;
    };

    Room.prototype.addSeparator = function () {
        if (this.isLobby()) {
            return;
        }

        // find first correct unread message
        var n = this.getUnread(),
            $unread = this.messages.find('.message').eq(-(n + 1));

        $unread.after(this.templates.separator.tmpl())
            .data('unread', n); // store unread count

        this.scrollToBottom();
    };

    Room.prototype.removeSeparator = function () {
        this.messages.find('.message-separator').fadeOut(2000, function () {
            $(this).remove();
        });
    };

    Room.prototype.updateUnread = function (isMentioned) {
        var $tab = this.tab.addClass('unread'),
            $content = $tab.find('.content'),
            unread = ($tab.data('unread') || 0) + 1,
            hasMentions = $tab.data('hasMentions') || isMentioned; // Whether or not the user already has unread messages to him/her

        $content.text((hasMentions ? '*' : '') + '(' + unread + ') ' + this.getName());

        $tab.data('unread', unread);
        $tab.data('hasMentions', hasMentions);

        if (!this.isActive() && unread === 1) {
            // If this room isn't active then we're going to glow the tab
            // to get the user's attention
            glowTab($tab, 6);
        }
    };

    Room.prototype.scrollToBottom = function () {
        // IE will repaint if we do the Chrome bugfix and look jumpy
        if ($.browser.webkit) {
            // Chrome fix for hiding and showing scroll areas
            this.messages.scrollTop(this.messages.scrollTop() - 1);
        }
        this.messages.scrollTop(this.messages[0].scrollHeight);
    };

    Room.prototype.isNearTheEnd = function () {
        return this.messages.isNearTheEnd();
    };

    Room.prototype.getName = function () {
        return this.tab.data('name');
    };

    Room.prototype.isActive = function () {
        return this.tab.hasClass('current');
    };

    Room.prototype.exists = function () {
        return this.tab.length > 0;
    };

    Room.prototype.isClosed = function () {
        return this.tab.attr('data-closed') === 'true';
    };

    Room.prototype.close = function () {
        this.tab.attr('data-closed', true);
        this.tab.addClass('closed');
    };

    Room.prototype.unClose = function () {
        this.tab.attr('data-closed', false);
        this.tab.removeClass('closed');
    };

    Room.prototype.clear = function () {
        this.messages.empty();
        this.owners.empty();
        this.activeUsers.empty();
    };

    Room.prototype.makeInactive = function () {
        this.tab.removeClass('current');

        this.messages.removeClass('current')
                     .hide();

        this.users.removeClass('current')
                  .hide();

        this.roomTopic.removeClass('current')
                  .hide();
    };

    Room.prototype.makeActive = function () {
        var currUnread = this.getUnread(),
            lastUnread = this.messages.find('.message-separator').data('unread') || 0;

        this.tab.addClass('current')
                .removeClass('unread')
                .stop(true, true)
                .css('backgroundColor', '')
                .css('color', '')
                .data('unread', 0)
                .data('hasMentions', false)
                .find('.content')
                .text(this.getName());

        this.messages.addClass('current')
                     .show();

        this.users.addClass('current')
                  .show();

        this.roomTopic.addClass('current')
                  .show();

        // if no unread since last separator
        // remove previous separator
        if (currUnread <= lastUnread) {
            this.removeSeparator();
        }
    };

    Room.prototype.setInitialized = function () {
        this.tab.data('initialized', true);
    };

    Room.prototype.isInitialized = function () {
        return this.tab.data('initialized') === true;
    };

    // Users
    Room.prototype.getUser = function (userName) {
        return this.users.find(getUserClassName(userName));
    };

    Room.prototype.getUserReferences = function (userName) {
        return $.merge(this.getUser(userName),
                       this.messages.find(getUserClassName(userName)));
    };

    Room.prototype.setLocked = function () {
        this.tab.addClass('locked');
    };

    Room.prototype.setListState = function (list) {
        var emptyStatus = list.children('li.empty'),
            visibleItems = list.children('li:not(.empty)').filter(function() { return $(this).css('display') !== 'none'; });

        if (visibleItems.length > 0) {
            emptyStatus.remove();
        } else if (emptyStatus.length === 0) {
            list.append($('
').text(list.data('emptyMessage')));
        }
    };

    Room.prototype.addUser = function (userViewModel, $user) {
        if (userViewModel.owner) {
            this.addUserToList($user, this.owners);
        } else {
            this.changeIdle($user, userViewModel.active);

            this.addUserToList($user, this.activeUsers);

        }
    };

    Room.prototype.changeIdle = function ($user, isActive) {
        if (isActive) {
            $user.removeClass('idle');
        } else {
            $user.addClass('idle');
        }
    };

    Room.prototype.addUserToList = function ($user, list) {
        var oldParentList = $user.parent('ul');
        $user.appendTo(list);
        this.setListState(list);
        if (oldParentList.length > 0) {
            this.setListState(oldParentList);
        }
        this.sortList(list, $user);
    };

    Room.prototype.appearsInList = function ($user, list) {
        return $user.parent('ul').attr('id') === list.attr('id');
    };

    Room.prototype.updateUserStatus = function ($user) {
        var owner = $user.data('owner') || false;

        if (owner === true) {
            if (!this.appearsInList($user, this.owners)) {
                this.addUserToList($user, this.owners);
            }
            return;
        }

        var status = $user.data('active');
        if (typeof status === "undefined") {
            return;
        }

        if (!this.appearsInList($user, this.activeUsers)) {
            this.changeIdle($user, status);

            this.addUserToList($user, this.activeUsers);
        }
    };

    Room.prototype.sortLists = function (user) {
        var isOwner = $(user).data('owner');
        if (isOwner) {
            this.sortList(this.owners, user);
        } else {
            this.sortList(this.activeUsers, user);
        }
    };

    Room.prototype.sortList = function (listToSort, user) {
        var listItems = listToSort.children('li:not(.empty)').get(),
            userName = $(user).data('name').toString(),
            userActive = $(user).data('active');

        for (var i = 0; i < listItems.length; i++) {
            var otherName = $(listItems[i]).data('name').toString(),
                otherActive = $(listItems[i]).data('active');

            if ((userActive && !otherActive) ||
                (userActive === otherActive &&
                    userName.toUpperCase() < otherName.toUpperCase())) {
                $(listItems[i]).before(user);
                break;
            }
        }
    };

    Room.prototype.canTrimHistory = function () {
        return this.tab.data('trimmable') !== false;
    };

    Room.prototype.setTrimmable = function (canTrimMessages) {
        this.tab.data('trimmable', canTrimMessages);
    };

    Room.prototype.trimHistory = function (numberOfMessagesToKeep) {
        var lastIndex = null,
            $messagesToRemove = null,
            $roomMessages = this.messages.find('li'),
            messageCount = $roomMessages.length;

        numberOfMessagesToKeep = numberOfMessagesToKeep || trimRoomHistoryMaxMessages;

        if (this.isLobby() || !this.canTrimHistory()) {
            return;
        }

        if (numberOfMessagesToKeep < trimRoomHistoryMaxMessages) {
            numberOfMessagesToKeep = trimRoomHistoryMaxMessages;
        }

        if (messageCount < numberOfMessagesToKeep) {
            return;
        }

        lastIndex = messageCount - numberOfMessagesToKeep;
        $messagesToRemove = $roomMessages.filter('li:lt(' + lastIndex + ')');

        $messagesToRemove.remove();
    };

    chat.Room = Room;
}(jQuery, window, window.chat));
<commit_msg>Fix issue where user was not sorted properly after going inactive<commit_after>(function ($, window, chat) {
    var trimRoomHistoryMaxMessages = 200;

    function glowTab($tab, n) {
        // Stop if we're not unread anymore
        if (!$tab.hasClass('unread')) {
            return;
        }

        // Go light
        $tab.animate({ backgroundColor: '#e5e5e5', color: '#77d42a' }, 800, function () {
            // Stop if we're not unread anymore
            if (!$tab.hasClass('unread')) {
                return;
            }

            n--;

            // Check if we're on our last glow
            if (n !== 0) {
                // Go dark
                $tab.animate({ backgroundColor: '#164C85', color: '#ffffff' }, 800, function () {
                    // Glow the tab again
                    glowTab($tab, n);
                });
            }
            else {
                // Leave the tab highlighted
                $tab.animate({ backgroundColor: '#043C4C', color: '#ffffff' }, 800);
            }
        });
    }

    function getUserClassName(userName) {
        return '[data-name="' + userName + '"]';
    }

    function Room($tab, $usersContainer, $usersOwners, $usersActive, $messages, $roomTopic) {
        this.tab = $tab;
        this.users = $usersContainer;
        this.owners = $usersOwners;
        this.activeUsers = $usersActive;
        this.messages = $messages;
        this.roomTopic = $roomTopic;

        this.templates = {
            separator: $('#message-separator-template')
        };

    }

    Room.prototype.isLocked = function () {
        return this.tab.hasClass('locked');
    };

    Room.prototype.isLobby = function () {
        return this.tab.hasClass('lobby');
    };

    Room.prototype.hasUnread = function () {
        return this.tab.hasClass('unread');
    };

    Room.prototype.hasMessages = function () {
        return this.tab.data('messages');
    };

    Room.prototype.updateMessages = function (value) {
        this.tab.data('messages', value);
    };

    Room.prototype.getUnread = function () {
        return this.tab.data('unread') || 0;
    };

    Room.prototype.hasSeparator = function () {
        return this.messages.find('.message-separator').length > 0;
    };

    Room.prototype.needsSeparator = function () {
        if (this.isActive()) {
            return false;
        }
        return this.isInitialized() && this.getUnread() === 5;
    };

    Room.prototype.addSeparator = function () {
        if (this.isLobby()) {
            return;
        }

        // find first correct unread message
        var n = this.getUnread(),
            $unread = this.messages.find('.message').eq(-(n + 1));

        $unread.after(this.templates.separator.tmpl())
            .data('unread', n); // store unread count

        this.scrollToBottom();
    };

    Room.prototype.removeSeparator = function () {
        this.messages.find('.message-separator').fadeOut(2000, function () {
            $(this).remove();
        });
    };

    Room.prototype.updateUnread = function (isMentioned) {
        var $tab = this.tab.addClass('unread'),
            $content = $tab.find('.content'),
            unread = ($tab.data('unread') || 0) + 1,
            hasMentions = $tab.data('hasMentions') || isMentioned; // Whether or not the user already has unread messages to him/her

        $content.text((hasMentions ? '*' : '') + '(' + unread + ') ' + this.getName());

        $tab.data('unread', unread);
        $tab.data('hasMentions', hasMentions);

        if (!this.isActive() && unread === 1) {
            // If this room isn't active then we're going to glow the tab
            // to get the user's attention
            glowTab($tab, 6);
        }
    };

    Room.prototype.scrollToBottom = function () {
        // IE will repaint if we do the Chrome bugfix and look jumpy
        if ($.browser.webkit) {
            // Chrome fix for hiding and showing scroll areas
            this.messages.scrollTop(this.messages.scrollTop() - 1);
        }
        this.messages.scrollTop(this.messages[0].scrollHeight);
    };

    Room.prototype.isNearTheEnd = function () {
        return this.messages.isNearTheEnd();
    };

    Room.prototype.getName = function () {
        return this.tab.data('name');
    };

    Room.prototype.isActive = function () {
        return this.tab.hasClass('current');
    };

    Room.prototype.exists = function () {
        return this.tab.length > 0;
    };

    Room.prototype.isClosed = function () {
        return this.tab.attr('data-closed') === 'true';
    };

    Room.prototype.close = function () {
        this.tab.attr('data-closed', true);
        this.tab.addClass('closed');
    };

    Room.prototype.unClose = function () {
        this.tab.attr('data-closed', false);
        this.tab.removeClass('closed');
    };

    Room.prototype.clear = function () {
        this.messages.empty();
        this.owners.empty();
        this.activeUsers.empty();
    };

    Room.prototype.makeInactive = function () {
        this.tab.removeClass('current');

        this.messages.removeClass('current')
                     .hide();

        this.users.removeClass('current')
                  .hide();

        this.roomTopic.removeClass('current')
                  .hide();
    };

    Room.prototype.makeActive = function () {
        var currUnread = this.getUnread(),
            lastUnread = this.messages.find('.message-separator').data('unread') || 0;

        this.tab.addClass('current')
                .removeClass('unread')
                .stop(true, true)
                .css('backgroundColor', '')
                .css('color', '')
                .data('unread', 0)
                .data('hasMentions', false)
                .find('.content')
                .text(this.getName());

        this.messages.addClass('current')
                     .show();

        this.users.addClass('current')
                  .show();

        this.roomTopic.addClass('current')
                  .show();

        // if no unread since last separator
        // remove previous separator
        if (currUnread <= lastUnread) {
            this.removeSeparator();
        }
    };

    Room.prototype.setInitialized = function () {
        this.tab.data('initialized', true);
    };

    Room.prototype.isInitialized = function () {
        return this.tab.data('initialized') === true;
    };

    // Users
    Room.prototype.getUser = function (userName) {
        return this.users.find(getUserClassName(userName));
    };

    Room.prototype.getUserReferences = function (userName) {
        return $.merge(this.getUser(userName),
                       this.messages.find(getUserClassName(userName)));
    };

    Room.prototype.setLocked = function () {
        this.tab.addClass('locked');
    };

    Room.prototype.setListState = function (list) {
        var emptyStatus = list.children('li.empty'),
            visibleItems = list.children('li:not(.empty)').filter(function() { return $(this).css('display') !== 'none'; });

        if (visibleItems.length > 0) {
            emptyStatus.remove();
        } else if (emptyStatus.length === 0) {
            list.append($('
').text(list.data('emptyMessage')));
        }
    };

    Room.prototype.addUser = function (userViewModel, $user) {
        if (userViewModel.owner) {
            this.addUserToList($user, this.owners);
        } else {
            this.changeIdle($user, userViewModel.active);

            this.addUserToList($user, this.activeUsers);

        }
    };

    Room.prototype.changeIdle = function ($user, isActive) {
        if (isActive) {
            $user.removeClass('idle');
        } else {
            $user.addClass('idle');
        }
    };

    Room.prototype.addUserToList = function ($user, list) {
        var oldParentList = $user.parent('ul');
        $user.appendTo(list);
        this.setListState(list);
        if (oldParentList.length > 0) {
            this.setListState(oldParentList);
        }
        this.sortList(list, $user);
    };

    Room.prototype.appearsInList = function ($user, list) {
        return $user.parent('ul').attr('id') === list.attr('id');
    };

    Room.prototype.updateUserStatus = function ($user) {
        var owner = $user.data('owner') || false;

        if (owner === true) {
            if (!this.appearsInList($user, this.owners)) {
                this.addUserToList($user, this.owners);
            }
            return;
        }

        var status = $user.data('active');
        if (typeof status === "undefined") {
            return;
        }

        if (!this.appearsInList($user, this.activeUsers)) {
            this.changeIdle($user, status);

            this.addUserToList($user, this.activeUsers);
        }
    };

    Room.prototype.sortLists = function (user) {
        var isOwner = $(user).data('owner');
        if (isOwner) {
            this.sortList(this.owners, user);
        } else {
            this.sortList(this.activeUsers, user);
        }
    };

    Room.prototype.sortList = function (listToSort, user) {
        var listItems = listToSort.children('li:not(.empty)').get(),
            userName = $(user).data('name').toString(),
            userActive = $(user).data('active');

        for (var i = 0; i < listItems.length; i++) {
            var otherName = $(listItems[i]).data('name').toString(),
                otherActive = $(listItems[i]).data('active');

            if (userActive === otherActive &&
                userName.toUpperCase() < otherName.toUpperCase()) {
                $(listItems[i]).before(user);
                break;
            } else if (userActive && !otherActive) {
                $(listItems[i]).before(user);
                break;
            } else if (i === (listItems.length - 1)) {
                $(listItems[i]).after(user);
                break;
            }

            //if (userActive && !otherActive) {
            //    $(listItems[i]).before(user);
            //    break;
            //} else if (userActive === otherActive &&
            //        userName.toUpperCase() < otherName.toUpperCase()) {
            //    $(listItems[i]).before(user);
            //    break;
            //} else if ((!userActive && otherActive) && i === listItems.length - 1) {
            //    $(listItems[i]).after(user);
            //}
        }
    };

    Room.prototype.canTrimHistory = function () {
        return this.tab.data('trimmable') !== false;
    };

    Room.prototype.setTrimmable = function (canTrimMessages) {
        this.tab.data('trimmable', canTrimMessages);
    };

    Room.prototype.trimHistory = function (numberOfMessagesToKeep) {
        var lastIndex = null,
            $messagesToRemove = null,
            $roomMessages = this.messages.find('li'),
            messageCount = $roomMessages.length;

        numberOfMessagesToKeep = numberOfMessagesToKeep || trimRoomHistoryMaxMessages;

        if (this.isLobby() || !this.canTrimHistory()) {
            return;
        }

        if (numberOfMessagesToKeep < trimRoomHistoryMaxMessages) {
            numberOfMessagesToKeep = trimRoomHistoryMaxMessages;
        }

        if (messageCount < numberOfMessagesToKeep) {
            return;
        }

        lastIndex = messageCount - numberOfMessagesToKeep;
        $messagesToRemove = $roomMessages.filter('li:lt(' + lastIndex + ')');

        $messagesToRemove.remove();
    };

    chat.Room = Room;
}(jQuery, window, window.chat));
<|endoftext|>


<commit_before>import config from "../"
import stylelint from "stylelint"
import test from "ava"

const validCss = (
`/**
 * Multi-line comment
 */

.selector-1,
.selector-2,
.selector-3[type="text"] {
  background: linear-gradient(#fff, rgba(0, 0, 0, 0.8));
  box-sizing: border-box;
  display: block;
  color: #333;
}

.selector-a,
.selector-b {
  padding: 10px !important;
  top: calc(calc(1em * 2) / 3);
}

.selector-x { width: 10%; }
.selector-y { width: 20%; }
.selector-z { width: 30%; }

/* Single-line comment */

@media (min-width >= 60em) {
  .selector {
    transform: translate(1, 1) scale(3);
  }
}

@media (min-orientation: portrait), projection and (color) {
  .selector-i + .selector-ii {
    background: color(rgb(0, 0, 0) lightness(50%));
    font-family: helvetica, arial, sans-serif;
  }
}

@media screen and (min-device-pixel-ratio: 2),
  screen and (min-resolution: 192dpi),
  screen and (min-resolution: 2dppx) {

  .selector {
    background-image:
      repeating-linear-gradient(
        -45deg,
        transparent,
        #fff 25px,
        rgba(255, 255, 255, 1) 50px
      );
    margin: 10px;
    margin-bottom: 5px;
    box-shadow:
      0 1px 1px #000,
      0 1px 0 #fff,
      2px 2px 1px 1px #ccc inset;
    height: 10rem;
  }

  .selector::after {
    content: "→";
    background-image: url("x.svg");
  }
}

`)

const invalidCss = (
`a {
  top: .2em;
}

`)

test("no warnings with valid css", t => {
  stylelint.lint({
    code: validCss,
    config: config,
  })
  .then(data => {
    const { errored, results } = data
    const { warnings } = results[0]
    t.notOk(errored, "no errored")
    t.is(warnings.length, 0, "flags no warnings")
  })
  .catch(function (err) {
    console.error(err.stack)
  })
})

test("a warning with invalid css", t => {
  stylelint.lint({
    code: invalidCss,
    config: config,
  })
  .then(data => {
    const { errored, results } = data
    const { warnings } = results[0]
    t.ok(errored, "errored")
    t.is(warnings.length, 1, "flags one warning")
    t.is(warnings[0].text, "Expected a leading zero (number-leading-zero)", "correct warning text")
  })
  .catch(function (err) {
    console.error(err.stack)
  })
})
<commit_msg>Return in tests<commit_after>import config from "../"
import stylelint from "stylelint"
import test from "ava"

const validCss = (
`/**
 * Multi-line comment
 */

.selector-1,
.selector-2,
.selector-3[type="text"] {
  background: linear-gradient(#fff, rgba(0, 0, 0, 0.8));
  box-sizing: border-box;
  display: block;
  color: #333;
}

.selector-a,
.selector-b {
  padding: 10px !important;
  top: calc(calc(1em * 2) / 3);
}

.selector-x { width: 10%; }
.selector-y { width: 20%; }
.selector-z { width: 30%; }

/* Single-line comment */

@media (min-width >= 60em) {
  .selector {
    transform: translate(1, 1) scale(3);
  }
}

@media (min-orientation: portrait), projection and (color) {
  .selector-i + .selector-ii {
    background: color(rgb(0, 0, 0) lightness(50%));
    font-family: helvetica, arial, sans-serif;
  }
}

@media screen and (min-device-pixel-ratio: 2),
  screen and (min-resolution: 192dpi),
  screen and (min-resolution: 2dppx) {

  .selector {
    background-image:
      repeating-linear-gradient(
        -45deg,
        transparent,
        #fff 25px,
        rgba(255, 255, 255, 1) 50px
      );
    margin: 10px;
    margin-bottom: 5px;
    box-shadow:
      0 1px 1px #000,
      0 1px 0 #fff,
      2px 2px 1px 1px #ccc inset;
    height: 10rem;
  }

  .selector::after {
    content: "→";
    background-image: url("x.svg");
  }
}

`)

const invalidCss = (
`a {
  top: .2em;
}

`)

test("no warnings with valid css", t => {
  return stylelint.lint({
    code: validCss,
    config: config,
  })
  .then(data => {
    const { errored, results } = data
    const { warnings } = results[0]
    t.notOk(errored, "no errored")
    t.is(warnings.length, 0, "flags no warnings")
  })
  .catch(function (err) {
    console.error(err.stack)
  })
})

test("a warning with invalid css", t => {
  return stylelint.lint({
    code: invalidCss,
    config: config,
  })
  .then(data => {
    const { errored, results } = data
    const { warnings } = results[0]
    t.ok(errored, "errored")
    t.is(warnings.length, 1, "flags one warning")
    t.is(warnings[0].text, "Expected a leading zero (number-leading-zero)", "correct warning text")
  })
  .catch(function (err) {
    console.error(err.stack)
  })
})
<|endoftext|>


<commit_before>/* See license.txt for terms of usage */

define([
    "firebug/lib/object",
    "firebug/firebug",
    "firebug/firefox/xpcom",
    "firebug/lib/url",
    "firebug/net/httpLib",
    "firebug/lib/string",
],
function(Obj, Firebug, Xpcom, Url, Http, Str) {

// ************************************************************************************************
// Constants

const Cc = Components.classes;
const Ci = Components.interfaces;
const nsIIOService = Ci.nsIIOService;
const nsIRequest = Ci.nsIRequest;
const nsICachingChannel = Ci.nsICachingChannel;
const nsIScriptableInputStream = Ci.nsIScriptableInputStream;
const nsIUploadChannel = Ci.nsIUploadChannel;
const nsIHttpChannel = Ci.nsIHttpChannel;

const IOService = Cc["@mozilla.org/network/io-service;1"];
const ioService = IOService.getService(nsIIOService);
const ScriptableInputStream = Cc["@mozilla.org/scriptableinputstream;1"];
const chromeReg = Xpcom.CCSV("@mozilla.org/chrome/chrome-registry;1", "nsIToolkitChromeRegistry");

const LOAD_FROM_CACHE = nsIRequest.LOAD_FROM_CACHE;
const LOAD_BYPASS_LOCAL_CACHE_IF_BUSY = nsICachingChannel.LOAD_BYPASS_LOCAL_CACHE_IF_BUSY;

const NS_BINDING_ABORTED = 0x804b0002;

// ************************************************************************************************

Firebug.SourceCache = function(context)
{
    this.context = context;
    this.cache = {};
};

Firebug.SourceCache.prototype = Obj.extend(new Firebug.Listener(),
{
    isCached: function(url)
    {
        return (this.cache[url] ? true : false);
    },

    loadText: function(url, method, file)
    {
        var lines = this.load(url, method, file);
        return lines ? lines.join("") : null;
    },

    load: function(url, method, file)
    {
        if (FBTrace.DBG_CACHE)
        {
            FBTrace.sysout("sourceCache.load: " + url);

            if (!this.cache.hasOwnProperty(url) && this.cache[url])
                FBTrace.sysout("sourceCache.load; ERROR - hasOwnProperty returns false, " +
                    "but the URL is cached: " + url, this.cache[url]);
        }

        // xxxHonza: sometimes hasOwnProperty return false even if the URL is obviously there.
        //if (this.cache.hasOwnProperty(url))
        var response = this.cache[this.removeAnchor(url)];
        if (response)
            return response;

        if (FBTrace.DBG_CACHE)
        {
            var urls = [];
            for (var prop in this.cache)
                urls.push(prop);

            FBTrace.sysout("sourceCache.load: Not in the Firebug internal cache", urls);
        }

        var d = Url.splitDataURL(url);  //TODO the RE should not have baseLine
        if (d)
        {
            var src = d.encodedContent;
            var data = decodeURIComponent(src);
            var lines = Str.splitLines(data)
            this.cache[url] = lines;

            return lines;
        }

        var j = Url.reJavascript.exec(url);
        if (j)
        {
            var src = url.substring(Url.reJavascript.lastIndex);
            var lines = Str.splitLines(src);
            this.cache[url] = lines;

            return lines;
        }

        var c = Url.reChrome.test(url);
        if (c)
        {
            if (Firebug.filterSystemURLs)
                return ["Filtered chrome url "+url];  // ignore chrome

            // If the chrome.manifest has  xpcnativewrappers=no, platform munges the url
            var reWrapperMunge = /(\S*)\s*->\s*(\S*)/;
            var m = reWrapperMunge.exec(url);
            if (m)
            {
                url = m[2];
                if (FBTrace.DBG_CACHE)
                    FBTrace.sysout("sourceCache found munged xpcnativewrapper url and set it to "+url+" m "+m+" m[0]:"+m[0]+" [1]"+m[1], m);
            }

            var chromeURI = Url.makeURI(url);
            if (!chromeURI)
            {
                if (FBTrace.DBG_CACHE)
                    FBTrace.sysout("sourceCache.load failed to convert chrome to local: "+url);
                return ["sourceCache failed to make URI from "+url];
            }

            var localURI = chromeReg.convertChromeURL(chromeURI);
            if (FBTrace.DBG_CACHE)
                FBTrace.sysout("sourceCache.load converting chrome to local: "+url, " -> "+localURI.spec);
            return this.loadFromLocal(localURI.spec);
        }

        c = Url.reFile.test(url);
        if (c)
        {
            return this.loadFromLocal(url);
        }

        if (url.indexOf('resource://') === 0)
        {
            var fileURL = Url.resourceToFile(url);
            return this.loadFromLocal(url);
        }

        // Unfortunately, the URL isn't available so, let's try to use FF cache.
        // Notice that additional network request to the server can be made in
        // this method (double-load).
        return this.loadFromCache(url, method, file);
    },

    store: function(url, text)
    {
        var tempURL = this.removeAnchor(url);

        if (FBTrace.DBG_CACHE)
            FBTrace.sysout("sourceCache for " + this.context.getName() + " store url=" +
                url + ((tempURL != url) ? " -> " + tempURL : ""), text);

        var lines = Str.splitLines(text);
        return this.storeSplitLines(tempURL, lines);
    },

    removeAnchor: function(url)
    {
        var index = url.indexOf("#");
        if (index < 0)
            return url;

        return url.substr(0, index);
    },

    loadFromLocal: function(url)
    {
        // if we get this far then we have either a file: or chrome: url converted to file:
        var src = Http.getResource(url);
        if (src)
        {
            var lines = Str.splitLines(src);
            this.cache[url] = lines;

            return lines;
        }
    },

    loadFromCache: function(url, method, file)
    {
        if (FBTrace.DBG_CACHE) FBTrace.sysout("sourceCache.loadFromCache url:"+url);

        var doc = this.context.window.document;
        if (doc)
            var charset = doc.characterSet;
        else
            var charset = "UTF-8";

        var channel;
        try
        {
            channel = ioService.newChannel(url, null, null);
            channel.loadFlags |= LOAD_FROM_CACHE | LOAD_BYPASS_LOCAL_CACHE_IF_BUSY;

            if (method && (channel instanceof nsIHttpChannel))
            {
                var httpChannel = Xpcom.QI(channel, nsIHttpChannel);
                httpChannel.requestMethod = method;
            }
        }
        catch (exc)
        {
            if (FBTrace.DBG_CACHE)
                FBTrace.sysout("sourceCache for url:"+url+" window="+this.context.window.location.href+" FAILS:", exc);
            return;
        }

        if (url == this.context.browser.contentWindow.location.href)
        {
            if (FBTrace.DBG_CACHE) FBTrace.sysout("sourceCache.load content window href\n");
            if (channel instanceof nsIUploadChannel)
            {
                var postData = getPostStream(this.context);
                if (postData)
                {
                    var uploadChannel = Xpcom.QI(channel, nsIUploadChannel);
                    uploadChannel.setUploadStream(postData, "", -1);
                    if (FBTrace.DBG_CACHE) FBTrace.sysout("sourceCache.load uploadChannel set\n");
                }
            }

            if (channel instanceof nsICachingChannel)
            {
                var cacheChannel = Xpcom.QI(channel, nsICachingChannel);
                cacheChannel.cacheKey = getCacheKey(this.context);
                if (FBTrace.DBG_CACHE) FBTrace.sysout("sourceCache.load cacheChannel key"+cacheChannel.cacheKey+"\n");
            }
        }
        else if ((method == "PUT" || method == "POST") && file)
        {
            if (channel instanceof nsIUploadChannel)
            {
                // In case of PUT and POST, don't forget to use the original body.
                var postData = getPostText(file, this.context);
                if (postData)
                {
                    var postDataStream = Http.getInputStreamFromString(postData);
                    var uploadChannel = Xpcom.QI(channel, nsIUploadChannel);
                    uploadChannel.setUploadStream(postDataStream, "application/x-www-form-urlencoded", -1);
                    if (FBTrace.DBG_CACHE) FBTrace.sysout("sourceCache.load uploadChannel set\n");
                }
            }
        }

        var stream;
        try
        {
            if (FBTrace.DBG_CACHE) FBTrace.sysout("sourceCache.load url:"+url+" with charset"+charset+"\n");
            stream = channel.open();
        }
        catch (exc)
        {
            if (FBTrace.DBG_ERRORS)
            {
                var isCache = (channel instanceof nsICachingChannel)?"nsICachingChannel":"NOT caching channel";
                var isUp = (channel instanceof nsIUploadChannel)?"nsIUploadChannel":"NOT nsIUploadChannel";
                FBTrace.sysout(url+" vs "+this.context.browser.contentWindow.location.href+" and "+isCache+" "+isUp+"\n");
                FBTrace.sysout("sourceCache.load fails channel.open for url="+url+ " cause:", exc);
                FBTrace.sysout("sourceCache.load fails channel=", channel);
            }
            return ["sourceCache.load FAILS for url="+url, exc.toString()];
        }

        try
        {
            var data = Http.readFromStream(stream, charset);
            var lines = Str.splitLines(data);
            this.cache[url] = lines;
            return lines;
        }
        catch (exc)
        {
            if (FBTrace.DBG_ERRORS)
                FBTrace.sysout("sourceCache.load FAILS, url="+url, exc);
            return ["sourceCache.load FAILS for url="+url, exc.toString()];
        }
        finally
        {
            stream.close();
        }
    },

    storeSplitLines: function(url, lines)
    {
        if (FBTrace.DBG_CACHE)
            FBTrace.sysout("sourceCache for window="+this.context.getName()+" store url="+url+"\n");
        return this.cache[url] = lines;
    },

    invalidate: function(url)
    {
        url = this.removeAnchor(url);

        if (FBTrace.DBG_CACHE)
            FBTrace.sysout("sourceCache.invalidate; " + url);

        delete this.cache[url];
    },

    getLine: function(url, lineNo)
    {
        var lines;

        try
        {
            lines = this.load(url);
        }
        catch (e)
        {
            if (FBTrace.DBG_ERRORS)
                FBTrace.sysout("sourceCache.getLine; EXCEPTION " + e, e);
        }

        if (!lines)
            return "(no source for " + url + ")";

        if (lineNo <= lines.length)
        {
            return lines[lineNo-1];
        }
        else
        {
            return (lines.length == 1) ?
                lines[0] : "(" + lineNo + " out of range " + lines.length + ")";
        }
    }
});

// xxxHonza getPostText and Http.readPostTextFromRequest are copied from
// net.js. These functions should be removed when this cache is
// refactored due to the double-load problem.
function getPostText(file, context)
{
    if (!file.postText)
        file.postText = Http.readPostTextFromPage(file.href, context);

    if (!file.postText)
        file.postText = Http.readPostTextFromRequest(file.request, context);

    return file.postText;
}

// ************************************************************************************************

function getPostStream(context)
{
    try
    {
        var webNav = context.browser.webNavigation;
        var descriptor = Xpcom.QI(webNav, Ci.nsIWebPageDescriptor).currentDescriptor;
        var entry = Xpcom.QI(descriptor, Ci.nsISHEntry);

        if (entry.postData)
        {
            // Seek to the beginning, or it will probably start reading at the end
            var postStream = Xpcom.QI(entry.postData, Ci.nsISeekableStream);
            postStream.seek(0, 0);
            return postStream;
        }
     }
     catch (exc)
     {
     }
}

function getCacheKey(context)
{
    try
    {
        var webNav = context.browser.webNavigation;
        var descriptor = Xpcom.QI(webNav, Ci.nsIWebPageDescriptor).currentDescriptor;
        var entry = Xpcom.QI(descriptor, Ci.nsISHEntry);
        return entry.cacheKey;
     }
     catch (exc)
     {
     }
}

// ************************************************************************************************
// Registration

return Firebug.SourceCache;

// ************************************************************************************************
});
<commit_msg>[1.9] Issue 1328: Script tag does not always reflect the actual content<commit_after>/* See license.txt for terms of usage */

define([
    "firebug/lib/object",
    "firebug/firebug",
    "firebug/firefox/xpcom",
    "firebug/lib/url",
    "firebug/net/httpLib",
    "firebug/lib/string",
],
function(Obj, Firebug, Xpcom, Url, Http, Str) {

// ************************************************************************************************
// Constants

const Cc = Components.classes;
const Ci = Components.interfaces;
const nsIIOService = Ci.nsIIOService;
const nsIRequest = Ci.nsIRequest;
const nsICachingChannel = Ci.nsICachingChannel;
const nsIScriptableInputStream = Ci.nsIScriptableInputStream;
const nsIUploadChannel = Ci.nsIUploadChannel;
const nsIHttpChannel = Ci.nsIHttpChannel;

const IOService = Cc["@mozilla.org/network/io-service;1"];
const ioService = IOService.getService(nsIIOService);
const ScriptableInputStream = Cc["@mozilla.org/scriptableinputstream;1"];
const chromeReg = Xpcom.CCSV("@mozilla.org/chrome/chrome-registry;1", "nsIToolkitChromeRegistry");

const LOAD_FROM_CACHE = nsIRequest.LOAD_FROM_CACHE;
const LOAD_BYPASS_LOCAL_CACHE_IF_BUSY = nsICachingChannel.LOAD_BYPASS_LOCAL_CACHE_IF_BUSY;

const NS_BINDING_ABORTED = 0x804b0002;

// ************************************************************************************************

Firebug.SourceCache = function(context)
{
    this.context = context;
    this.cache = {};
};

Firebug.SourceCache.prototype = Obj.extend(new Firebug.Listener(),
{
    isCached: function(url)
    {
        return (this.cache[url] ? true : false);
    },

    loadText: function(url, method, file)
    {
        var lines = this.load(url, method, file);
        return lines ? lines.join("") : null;
    },

    load: function(url, method, file)
    {
        if (FBTrace.DBG_CACHE)
        {
            FBTrace.sysout("sourceCache.load: " + url);

            if (!this.cache.hasOwnProperty(url) && this.cache[url])
                FBTrace.sysout("sourceCache.load; ERROR - hasOwnProperty returns false, " +
                    "but the URL is cached: " + url, this.cache[url]);
        }

        // xxxHonza: sometimes hasOwnProperty return false even if the URL is obviously there.
        //if (this.cache.hasOwnProperty(url))
        var response = this.cache[this.removeAnchor(url)];
        if (response)
            return response;

        if (FBTrace.DBG_CACHE)
        {
            var urls = [];
            for (var prop in this.cache)
                urls.push(prop);

            FBTrace.sysout("sourceCache.load: Not in the Firebug internal cache", urls);
        }

        var d = Url.splitDataURL(url);  //TODO the RE should not have baseLine
        if (d)
        {
            var src = d.encodedContent;
            var data = decodeURIComponent(src);
            var lines = Str.splitLines(data)
            this.cache[url] = lines;

            return lines;
        }

        var j = Url.reJavascript.exec(url);
        if (j)
        {
            var src = url.substring(Url.reJavascript.lastIndex);
            var lines = Str.splitLines(src);
            this.cache[url] = lines;

            return lines;
        }

        var c = Url.reChrome.test(url);
        if (c)
        {
            if (Firebug.filterSystemURLs)
                return ["Filtered chrome url "+url];  // ignore chrome

            // If the chrome.manifest has  xpcnativewrappers=no, platform munges the url
            var reWrapperMunge = /(\S*)\s*->\s*(\S*)/;
            var m = reWrapperMunge.exec(url);
            if (m)
            {
                url = m[2];
                if (FBTrace.DBG_CACHE)
                    FBTrace.sysout("sourceCache found munged xpcnativewrapper url and set it to "+url+" m "+m+" m[0]:"+m[0]+" [1]"+m[1], m);
            }

            var chromeURI = Url.makeURI(url);
            if (!chromeURI)
            {
                if (FBTrace.DBG_CACHE)
                    FBTrace.sysout("sourceCache.load failed to convert chrome to local: "+url);
                return ["sourceCache failed to make URI from "+url];
            }

            var localURI = chromeReg.convertChromeURL(chromeURI);
            if (FBTrace.DBG_CACHE)
                FBTrace.sysout("sourceCache.load converting chrome to local: "+url, " -> "+localURI.spec);
            return this.loadFromLocal(localURI.spec);
        }

        c = Url.reFile.test(url);
        if (c)
        {
            return this.loadFromLocal(url);
        }

        if (url.indexOf('resource://') === 0)
        {
            var fileURL = Url.resourceToFile(url);
            return this.loadFromLocal(url);
        }

        // Unfortunately, the URL isn't available so, let's try to use FF cache.
        // Notice that additional network request to the server can be made in
        // this method (double-load).
        return this.loadFromCache(url, method, file);
    },

    store: function(url, text)
    {
        var tempURL = this.removeAnchor(url);

        if (FBTrace.DBG_CACHE)
            FBTrace.sysout("sourceCache for " + this.context.getName() + " store url=" +
                url + ((tempURL != url) ? " -> " + tempURL : ""), text);

        var lines = Str.splitLines(text);
        return this.storeSplitLines(tempURL, lines);
    },

    removeAnchor: function(url)
    {
        var index = url.indexOf("#");
        if (index < 0)
            return url;

        return url.substr(0, index);
    },

    loadFromLocal: function(url)
    {
        if (FBTrace.DBG_CACHE)
            FBTrace.sysout("tabCache.loadFromLocal url: " + url);

        // if we get this far then we have either a file: or chrome: url converted to file:
        var src = Http.getResource(url);
        if (src)
        {
            var lines = Str.splitLines(src);

            // Don't cache locale files to get latest version (issue 1238)
            // Local files can be currently fetched any time.
            //this.cache[url] = lines;

            return lines;
        }
    },

    loadFromCache: function(url, method, file)
    {
        if (FBTrace.DBG_CACHE) FBTrace.sysout("sourceCache.loadFromCache url:"+url);

        var doc = this.context.window.document;
        if (doc)
            var charset = doc.characterSet;
        else
            var charset = "UTF-8";

        var channel;
        try
        {
            channel = ioService.newChannel(url, null, null);
            channel.loadFlags |= LOAD_FROM_CACHE | LOAD_BYPASS_LOCAL_CACHE_IF_BUSY;

            if (method && (channel instanceof nsIHttpChannel))
            {
                var httpChannel = Xpcom.QI(channel, nsIHttpChannel);
                httpChannel.requestMethod = method;
            }
        }
        catch (exc)
        {
            if (FBTrace.DBG_CACHE)
                FBTrace.sysout("sourceCache for url:"+url+" window="+this.context.window.location.href+" FAILS:", exc);
            return;
        }

        if (url == this.context.browser.contentWindow.location.href)
        {
            if (FBTrace.DBG_CACHE) FBTrace.sysout("sourceCache.load content window href\n");
            if (channel instanceof nsIUploadChannel)
            {
                var postData = getPostStream(this.context);
                if (postData)
                {
                    var uploadChannel = Xpcom.QI(channel, nsIUploadChannel);
                    uploadChannel.setUploadStream(postData, "", -1);
                    if (FBTrace.DBG_CACHE) FBTrace.sysout("sourceCache.load uploadChannel set\n");
                }
            }

            if (channel instanceof nsICachingChannel)
            {
                var cacheChannel = Xpcom.QI(channel, nsICachingChannel);
                cacheChannel.cacheKey = getCacheKey(this.context);
                if (FBTrace.DBG_CACHE) FBTrace.sysout("sourceCache.load cacheChannel key"+cacheChannel.cacheKey+"\n");
            }
        }
        else if ((method == "PUT" || method == "POST") && file)
        {
            if (channel instanceof nsIUploadChannel)
            {
                // In case of PUT and POST, don't forget to use the original body.
                var postData = getPostText(file, this.context);
                if (postData)
                {
                    var postDataStream = Http.getInputStreamFromString(postData);
                    var uploadChannel = Xpcom.QI(channel, nsIUploadChannel);
                    uploadChannel.setUploadStream(postDataStream, "application/x-www-form-urlencoded", -1);
                    if (FBTrace.DBG_CACHE) FBTrace.sysout("sourceCache.load uploadChannel set\n");
                }
            }
        }

        var stream;
        try
        {
            if (FBTrace.DBG_CACHE) FBTrace.sysout("sourceCache.load url:"+url+" with charset"+charset+"\n");
            stream = channel.open();
        }
        catch (exc)
        {
            if (FBTrace.DBG_ERRORS)
            {
                var isCache = (channel instanceof nsICachingChannel)?"nsICachingChannel":"NOT caching channel";
                var isUp = (channel instanceof nsIUploadChannel)?"nsIUploadChannel":"NOT nsIUploadChannel";
                FBTrace.sysout(url+" vs "+this.context.browser.contentWindow.location.href+" and "+isCache+" "+isUp+"\n");
                FBTrace.sysout("sourceCache.load fails channel.open for url="+url+ " cause:", exc);
                FBTrace.sysout("sourceCache.load fails channel=", channel);
            }
            return ["sourceCache.load FAILS for url="+url, exc.toString()];
        }

        try
        {
            var data = Http.readFromStream(stream, charset);
            var lines = Str.splitLines(data);
            this.cache[url] = lines;
            return lines;
        }
        catch (exc)
        {
            if (FBTrace.DBG_ERRORS)
                FBTrace.sysout("sourceCache.load FAILS, url="+url, exc);
            return ["sourceCache.load FAILS for url="+url, exc.toString()];
        }
        finally
        {
            stream.close();
        }
    },

    storeSplitLines: function(url, lines)
    {
        if (FBTrace.DBG_CACHE)
            FBTrace.sysout("sourceCache for window="+this.context.getName()+" store url="+url+"\n");
        return this.cache[url] = lines;
    },

    invalidate: function(url)
    {
        url = this.removeAnchor(url);

        if (FBTrace.DBG_CACHE)
            FBTrace.sysout("sourceCache.invalidate; " + url);

        delete this.cache[url];
    },

    getLine: function(url, lineNo)
    {
        var lines;

        try
        {
            lines = this.load(url);
        }
        catch (e)
        {
            if (FBTrace.DBG_ERRORS)
                FBTrace.sysout("sourceCache.getLine; EXCEPTION " + e, e);
        }

        if (!lines)
            return "(no source for " + url + ")";

        if (lineNo <= lines.length)
        {
            return lines[lineNo-1];
        }
        else
        {
            return (lines.length == 1) ?
                lines[0] : "(" + lineNo + " out of range " + lines.length + ")";
        }
    }
});

// xxxHonza getPostText and Http.readPostTextFromRequest are copied from
// net.js. These functions should be removed when this cache is
// refactored due to the double-load problem.
function getPostText(file, context)
{
    if (!file.postText)
        file.postText = Http.readPostTextFromPage(file.href, context);

    if (!file.postText)
        file.postText = Http.readPostTextFromRequest(file.request, context);

    return file.postText;
}

// ************************************************************************************************

function getPostStream(context)
{
    try
    {
        var webNav = context.browser.webNavigation;
        var descriptor = Xpcom.QI(webNav, Ci.nsIWebPageDescriptor).currentDescriptor;
        var entry = Xpcom.QI(descriptor, Ci.nsISHEntry);

        if (entry.postData)
        {
            // Seek to the beginning, or it will probably start reading at the end
            var postStream = Xpcom.QI(entry.postData, Ci.nsISeekableStream);
            postStream.seek(0, 0);
            return postStream;
        }
     }
     catch (exc)
     {
     }
}

function getCacheKey(context)
{
    try
    {
        var webNav = context.browser.webNavigation;
        var descriptor = Xpcom.QI(webNav, Ci.nsIWebPageDescriptor).currentDescriptor;
        var entry = Xpcom.QI(descriptor, Ci.nsISHEntry);
        return entry.cacheKey;
     }
     catch (exc)
     {
     }
}

// ************************************************************************************************
// Registration

return Firebug.SourceCache;

// ************************************************************************************************
});
<|endoftext|>


<commit_before> /**
 * @author Cornelius Kölbel <cornelius.koelbel@netknights.it>
 * @license AGPL-3.0
 *
 * This code is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License, version 3,
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License, version 3,
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
 *
 */

var BASE_URL = '/apps/twofactor_privacyidea/';

$(document).ready(function () {
    /* Use the /getValue API call to retrieve a string value from the app config */
    var getValue = function (key, callback) {
        $.get(OC.generateUrl(BASE_URL + 'getValue'), {key: key}).done(
            function(result) {
                callback(result);
            }
        );
    };
    /* Use the /setValue API call to set a string value in the app config. */
    var setValue = function (key, value) {
        OC.msg.startSaving('#pi_settings_msg');
        $.post(OC.generateUrl(BASE_URL + 'setValue'), {
            key: key,
            value: value
        }, function (data) {
            OC.msg.finishedSuccess('#pi_settings_msg', "Saved");
        });
    };
    var testAuthentication = function (user, pass, cb) {
        $.post(OC.generateUrl(BASE_URL + 'testAuthentication'), {
            user: user,
            pass: pass
        }, cb);
    };
    var testServiceAccount = function (user, pass, cb) {
        $.post(OC.generateUrl(BASE_URL + 'testServiceAccount'), {
            user: user,
            pass: pass
        }, cb);
    };

    /* privacyIDEA instance URL */
    getValue("url", function (url) {
       $("#piSettings #piurl").val(url);
    });
    $("#piSettings #piurl").change(function() {
        // We simple save the value always ;-)
        console.log("pi: Saving URL");
        var value = $("#piSettings #piurl").val();
        console.log(value);
        setValue("url", value);
    });

    /* "Check SSL" checkbox */
    getValue("checkssl", function (checkssl) {
        /* NOTE: We check for `!== "0"` instead of `=== "1"` here in order to be consistent with the Provider. */
        $("#piSettings #checkssl").prop('checked', checkssl !== "0");
    });
    $("#piSettings #checkssl").change(function() {
        setValue("checkssl", $(this).is(":checked") ? "1" : "0");
    });

    /* Activate privacyIDEA */
    getValue("piactive", function(piactive) {
        $("#piSettings #piactive").prop('checked', piactive === "1");
    });
    $('#piSettings #piactive').change(function() {
       setValue("piactive", $(this).is(":checked") ? "1" : "0");
    });

    getValue("pitimeout", function (pitimeout) {
        $("#piSettings #pitimeout").val(pitimeout);
    })
    $("#piSettings #pitimeout").change(function () {
        console.log("pi: Saving Timeout");
        var value = $("#piSettings #pitimeout").val();
        setValue("pitimeout", value);
    });

    /* "Bypass Proxy" checkbox */
    getValue("noproxy", function (noproxy) {
        $("#piSettings #noproxy").prop('checked', noproxy === "1");
    });
    $("#piSettings #noproxy").change(function() {
        setValue("noproxy", $(this).is(":checked") ? "1" : "0");
    });

    /* privacyIDEA realm */
    getValue("realm", function (realm) {
        $("#piSettings #pirealm").val(realm);
    });
    $("#piSettings #pirealm").change(function() {
        // We simple save the value always ;-)
        console.log("pi: Saving Realm");
        var value = $("#piSettings #pirealm").val();
        console.log(value);
        setValue("realm", value);
    });

    /* Enable/Disable challenge triggering */
    var displayServerCredentials = function (show) {
        if(show) {
            $("#piserviceaccount_credentials").show();
        } else {
            $("#piserviceaccount_credentials").hide();
        };
    };

    getValue("triggerchallenges", function (trigger) {
        var value = (trigger === "1");
        $("#piSettings #triggerchallenges").prop('checked', value);
        displayServerCredentials(value);
    });

    $("#piSettings #triggerchallenges").change(function() {
        var checked = $(this).is(":checked");
        setValue("triggerchallenges", checked ? "1" : "0");
        displayServerCredentials(checked);
    });

    /* in or exclude owncloud user groups */
    radioinclude = document.getElementById('piinclude');
    radioexclude = document.getElementById('piexclude');
    getValue("piexclude", function (piexclude) {
        $("#piSettings #piinclude").prop('checked', piexclude ==="0");
        $("#piSettings #piexclude").prop('checked', piexclude ==="1");
    })

    $("#piSettings #piinclude").change(function () {
        if(radioinclude.checked){
            setValue("piexclude", "0");
        }
    })
    $("#piSettings #piexclude").change(function () {
        if(radioexclude.checked){
            setValue("piexclude", "1");
        }
    })

    getValue("piexcludegroups", function (excludegroups) {
       $("#piSettings #piexcludegroups").val(excludegroups);
        OC.Settings.setupGroupsSelect($('#piSettings #piexcludegroups'));
    });

    $("#piSettings #piexcludegroups").change(function () {
       console.log("pi: Saving Excluse groups");
       var value = $("#piSettings #piexcludegroups").val();
       setValue("piexcludegroups", value);
    });

    getValue("piexcludeips", function (excludeips) {
        $("#piSettings #piexcludeips").val(excludeips);
    });

    $("#piSettings #piexcludeips").change(function () {
        console.log("pi: Saving excluded ips");
        var value = $("#piSettings #piexcludeips").val();
        setValue("piexcludeips", value);
    });

    /* privacyIDEA service account username */
    getValue("serviceaccount_user", function (user) {
        $("#piSettings #piserviceaccount_user").val(user);
    });

    $("#piSettings #piserviceaccount_user").change(function () {
        console.log("pi: Saving Service Account User");
        var value = $("#piSettings #piserviceaccount_user").val();
        setValue("serviceaccount_user", value);
    });

    /* privacyIDEA service account password */
    getValue("serviceaccount_password", function (password) {
        $("#piSettings #piserviceaccount_password").val(password);
    });

    $("#piSettings #piserviceaccount_password").change(function () {
        console.log("pi: Saving Service Account Password");
        var value = $("#piSettings #piserviceaccount_password").val();
        setValue("serviceaccount_password", value);
    });

    /* Test Authentication button */
    $("#piSettings #pitestauthentication").click(function (event) {
        event.preventDefault();
        // Use this trick to ensure that the `change` events of inputs
        // are handled before we test the authentication, so that
        // new values are already taken into account.
        setTimeout(function () {
            var user = $("#piSettings #pitestauthentication_user").val();
            var password = $("#piSettings #pitestauthentication_password").val();
            OC.msg.startAction("#pitestauthentication_msg", "Authenticating ...");
            testAuthentication(user, password, function (data) {
                OC.msg.finishedAction("#pitestauthentication_msg", data);
            });
        }, 0);
    });

    /* Test Service Account button */
    $("#piSettings #piserviceaccount_test").click(function (event) {
        event.preventDefault();
        // Use this trick to ensure that the `change` events of inputs
        // are handled before we test the authentication, so that
        // new values are already taken into account.
        setTimeout(function () {
            var user = $("#piSettings #piserviceaccount_user").val();
            var password = $("#piSettings #piserviceaccount_password").val();
            OC.msg.startAction("#piserviceaccount_msg", "Checking credentials ...");
            testServiceAccount(user, password, function (data) {
                OC.msg.finishedAction("#piserviceaccount_msg", data);
            });
        }, 0);
    });

});
<commit_msg>Fix typo<commit_after> /**
 * @author Cornelius Kölbel <cornelius.koelbel@netknights.it>
 * @license AGPL-3.0
 *
 * This code is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License, version 3,
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License, version 3,
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
 *
 */

var BASE_URL = '/apps/twofactor_privacyidea/';

$(document).ready(function () {
    /* Use the /getValue API call to retrieve a string value from the app config */
    var getValue = function (key, callback) {
        $.get(OC.generateUrl(BASE_URL + 'getValue'), {key: key}).done(
            function(result) {
                callback(result);
            }
        );
    };
    /* Use the /setValue API call to set a string value in the app config. */
    var setValue = function (key, value) {
        OC.msg.startSaving('#pi_settings_msg');
        $.post(OC.generateUrl(BASE_URL + 'setValue'), {
            key: key,
            value: value
        }, function (data) {
            OC.msg.finishedSuccess('#pi_settings_msg', "Saved");
        });
    };
    var testAuthentication = function (user, pass, cb) {
        $.post(OC.generateUrl(BASE_URL + 'testAuthentication'), {
            user: user,
            pass: pass
        }, cb);
    };
    var testServiceAccount = function (user, pass, cb) {
        $.post(OC.generateUrl(BASE_URL + 'testServiceAccount'), {
            user: user,
            pass: pass
        }, cb);
    };

    /* privacyIDEA instance URL */
    getValue("url", function (url) {
       $("#piSettings #piurl").val(url);
    });
    $("#piSettings #piurl").change(function() {
        // We simple save the value always ;-)
        console.log("pi: Saving URL");
        var value = $("#piSettings #piurl").val();
        console.log(value);
        setValue("url", value);
    });

    /* "Check SSL" checkbox */
    getValue("checkssl", function (checkssl) {
        /* NOTE: We check for `!== "0"` instead of `=== "1"` here in order to be consistent with the Provider. */
        $("#piSettings #checkssl").prop('checked', checkssl !== "0");
    });
    $("#piSettings #checkssl").change(function() {
        setValue("checkssl", $(this).is(":checked") ? "1" : "0");
    });

    /* Activate privacyIDEA */
    getValue("piactive", function(piactive) {
        $("#piSettings #piactive").prop('checked', piactive === "1");
    });
    $('#piSettings #piactive').change(function() {
       setValue("piactive", $(this).is(":checked") ? "1" : "0");
    });

    getValue("pitimeout", function (pitimeout) {
        $("#piSettings #pitimeout").val(pitimeout);
    })
    $("#piSettings #pitimeout").change(function () {
        console.log("pi: Saving Timeout");
        var value = $("#piSettings #pitimeout").val();
        setValue("pitimeout", value);
    });

    /* "Bypass Proxy" checkbox */
    getValue("noproxy", function (noproxy) {
        $("#piSettings #noproxy").prop('checked', noproxy === "1");
    });
    $("#piSettings #noproxy").change(function() {
        setValue("noproxy", $(this).is(":checked") ? "1" : "0");
    });

    /* privacyIDEA realm */
    getValue("realm", function (realm) {
        $("#piSettings #pirealm").val(realm);
    });
    $("#piSettings #pirealm").change(function() {
        // We simple save the value always ;-)
        console.log("pi: Saving Realm");
        var value = $("#piSettings #pirealm").val();
        console.log(value);
        setValue("realm", value);
    });

    /* Enable/Disable challenge triggering */
    var displayServerCredentials = function (show) {
        if(show) {
            $("#piserviceaccount_credentials").show();
        } else {
            $("#piserviceaccount_credentials").hide();
        };
    };

    getValue("triggerchallenges", function (trigger) {
        var value = (trigger === "1");
        $("#piSettings #triggerchallenges").prop('checked', value);
        displayServerCredentials(value);
    });

    $("#piSettings #triggerchallenges").change(function() {
        var checked = $(this).is(":checked");
        setValue("triggerchallenges", checked ? "1" : "0");
        displayServerCredentials(checked);
    });

    /* in or exclude owncloud user groups */
    radioinclude = document.getElementById('piinclude');
    radioexclude = document.getElementById('piexclude');
    getValue("piexclude", function (piexclude) {
        $("#piSettings #piinclude").prop('checked', piexclude ==="0");
        $("#piSettings #piexclude").prop('checked', piexclude ==="1");
    })

    $("#piSettings #piinclude").change(function () {
        if(radioinclude.checked){
            setValue("piexclude", "0");
        }
    })
    $("#piSettings #piexclude").change(function () {
        if(radioexclude.checked){
            setValue("piexclude", "1");
        }
    })

    getValue("piexcludegroups", function (excludegroups) {
       $("#piSettings #piexcludegroups").val(excludegroups);
        OC.Settings.setupGroupsSelect($('#piSettings #piexcludegroups'));
    });

    $("#piSettings #piexcludegroups").change(function () {
       console.log("pi: Saving Exclude groups");
       var value = $("#piSettings #piexcludegroups").val();
       setValue("piexcludegroups", value);
    });

    getValue("piexcludeips", function (excludeips) {
        $("#piSettings #piexcludeips").val(excludeips);
    });

    $("#piSettings #piexcludeips").change(function () {
        console.log("pi: Saving excluded ips");
        var value = $("#piSettings #piexcludeips").val();
        setValue("piexcludeips", value);
    });

    /* privacyIDEA service account username */
    getValue("serviceaccount_user", function (user) {
        $("#piSettings #piserviceaccount_user").val(user);
    });

    $("#piSettings #piserviceaccount_user").change(function () {
        console.log("pi: Saving Service Account User");
        var value = $("#piSettings #piserviceaccount_user").val();
        setValue("serviceaccount_user", value);
    });

    /* privacyIDEA service account password */
    getValue("serviceaccount_password", function (password) {
        $("#piSettings #piserviceaccount_password").val(password);
    });

    $("#piSettings #piserviceaccount_password").change(function () {
        console.log("pi: Saving Service Account Password");
        var value = $("#piSettings #piserviceaccount_password").val();
        setValue("serviceaccount_password", value);
    });

    /* Test Authentication button */
    $("#piSettings #pitestauthentication").click(function (event) {
        event.preventDefault();
        // Use this trick to ensure that the `change` events of inputs
        // are handled before we test the authentication, so that
        // new values are already taken into account.
        setTimeout(function () {
            var user = $("#piSettings #pitestauthentication_user").val();
            var password = $("#piSettings #pitestauthentication_password").val();
            OC.msg.startAction("#pitestauthentication_msg", "Authenticating ...");
            testAuthentication(user, password, function (data) {
                OC.msg.finishedAction("#pitestauthentication_msg", data);
            });
        }, 0);
    });

    /* Test Service Account button */
    $("#piSettings #piserviceaccount_test").click(function (event) {
        event.preventDefault();
        // Use this trick to ensure that the `change` events of inputs
        // are handled before we test the authentication, so that
        // new values are already taken into account.
        setTimeout(function () {
            var user = $("#piSettings #piserviceaccount_user").val();
            var password = $("#piSettings #piserviceaccount_password").val();
            OC.msg.startAction("#piserviceaccount_msg", "Checking credentials ...");
            testServiceAccount(user, password, function (data) {
                OC.msg.finishedAction("#piserviceaccount_msg", data);
            });
        }, 0);
    });

});
<|endoftext|>


<commit_before>(function(w, overthrow) {
	var lib = overthrow.sidescroller;

	function append( event ) {
		var options = event.overthrow || {}, append, scroller, ul;

		if( !options.name === "append" ){
			return;
		}

		append = options.arguments[0];
		scroller = event.target || event.srcElement;
		ul = scroller.querySelector( "ul" );

		// make sure the new element doesn't jog the scroll bar
		append.style.visibility = "hidden";
		append.style.position = "absolute";

		// add the new element to the dom so we can get an accurate width
		ul.appendChild( append );
		ul.style.width = (ul.offsetWidth + append.offsetWidth) + "px";

		// return the element to normal operating for the purposes of the scroller
		append.style.visibility = "visible";
		append.style.position = "static";
	}

	lib.onEvent( "overthrow-init", w.document.documentElement, function( event ) {
		var scroller = event.overthrow.sideScroll,
			options = event.overthrow.options || {};

		lib.onEvent( "overthrow-method", scroller, append);
	});
})( this, this.overthrow );<commit_msg>removed duplicate, misnamed append method extension<commit_after><|endoftext|>


<commit_before><commit_msg>Função que formata data<commit_after><|endoftext|>


<commit_before>var wechatBot = require('wechat-bot');
var request = require('request');

var debug = require('debug')('wechat:letsface-api');
var _ = require('lodash');

/* include all apis */
exports = module.exports = function wechatLetsfaceApi(options) {
  _.assign(exports.options, options);
  exports.options.wxApi = options && (options.wxApi || wechat.API(options.appid, options.appsecret));
  var bot = wechatBot();
  bot.use(exports.clubs(exports.options));
  bot.use(exports.checkIn(exports.options));
  return bot;
};

/* global options for all instance */
exports.options = {
  lfApi: 'http://localhost:3000'
};

/* list clubs */
exports.clubs = function clubs(options) {
  return function clubs(req, res, next) {
    var msg = req.weixin;
    if (msg.MsgType === 'text' && msg.Content.toLowerCase() === 'clubs') {
      request({
        uri: options.lfApi + '/clubs/',
        json: true
      }, function gotClub(err, httpResponse, body) {
        if (err) {
          return next(err);
        } else {
          var total = body.clubs.length;
          debug('get %d clubs', total);
          return res.reply(total + ' clubs');
        }
      });
    } else {
      return next();
    }
  };
};

var wechat = require('wechat');
var util = require('util');

/* check in using wechat profile */
exports.checkIn = function checkIn(options) {
  var wxApi = options.wxApi;
  return function checkIn(req, res, next) {
    var msg = req.weixin;

    if (msg.MsgType !== 'text') return next();

    var match = new RegExp(/^check in\s+(.*)\s+(.*)/i).exec(msg.Content);
    if (!match || match.length < 3) return next();

    var club = match[1];
    var event = match[2];
    var user = msg.FromUserName;

    wxApi.getUser(user, function gotUser(err, result) {
      if (err) next(err);
      debug('user id=%s, name=%s, avatar=%s',
            result.openid, result.nickname, result.headimgurl);
      var r = request({
        uri: util.format('%s/club/%s/event/%s/checkin',
                         options.lfApi, club, event),
        json: true,
        method: 'POST'
      }, function checkedIn(err, httpResponse, body) {
        if (err) return next(err);
        debug('check in result: %s, msg: %s', body.result, body.msg);
        return res.reply('check in ' + body.result);
      });
      var form = r.form();
      form.append('name', result.nickname);
      form.append('email', 'fake@email.com');
      form.append('mobile', '10086');
      form.append('photo', request(result.headimgurl));
    });
  };
};
<commit_msg>Add help message<commit_after>var wechatBot = require('wechat-bot');
var request = require('request');

var debug = require('debug')('wechat:letsface-api');
var _ = require('lodash');

/* include all apis */
exports = module.exports = function wechatLetsfaceApi(options) {
  _.assign(exports.options, options);
  exports.options.wxApi = options && (options.wxApi || wechat.API(options.appid, options.appsecret));
  var bot = wechatBot();
  bot.use(exports.clubs(exports.options));
  bot.use(exports.checkIn(exports.options));
  return bot;
};

/* global options for all instance */
exports.options = {
  lfApi: 'http://localhost:3000'
};

/* list clubs */
exports.clubs = function createClubs(options) {
  function clubs(req, res, next) {
    var msg = req.weixin;
    if (msg.MsgType === 'text' && msg.Content.toLowerCase() === 'clubs') {
      request({
        uri: options.lfApi + '/clubs/',
        json: true
      }, function gotClub(err, httpResponse, body) {
        if (err) {
          return next(err);
        } else {
          var total = body.clubs.length;
          debug('get %d clubs', total);
          return res.reply(total + ' clubs');
        }
      });
    } else {
      return next();
    }
  }
  clubs.help = "clubs";
  return clubs;
};

var wechat = require('wechat');
var util = require('util');

/* check in using wechat profile */
exports.checkIn = function createCheckIn(options) {
  var wxApi = options.wxApi;
  function checkIn(req, res, next) {
    var msg = req.weixin;

    if (msg.MsgType !== 'text') return next();

    var match = new RegExp(/^check in\s+(.*)\s+(.*)/i).exec(msg.Content);
    if (!match || match.length < 3) return next();

    var club = match[1];
    var event = match[2];
    var user = msg.FromUserName;

    wxApi.getUser(user, function gotUser(err, result) {
      if (err) next(err);
      debug('user id=%s, name=%s, avatar=%s',
            result.openid, result.nickname, result.headimgurl);
      var r = request({
        uri: util.format('%s/club/%s/event/%s/checkin',
                         options.lfApi, club, event),
        json: true,
        method: 'POST'
      }, function checkedIn(err, httpResponse, body) {
        if (err) return next(err);
        debug('check in result: %s, msg: %s', body.result, body.msg);
        return res.reply('check in ' + body.result);
      });
      var form = r.form();
      form.append('name', result.nickname);
      form.append('photo', request(result.headimgurl));
    });
  }
  checkIn.help = "check in <club_id> <event_id>";
  return checkIn;
};
<|endoftext|>