<commit_before>/* global $ */

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

    var LiveEditor = function LiveEditor (params) {
        console.log('Live Editor Init...');
        this.init(params);
        console.log('Live Editor Done...');
    }

    LiveEditor.prototype.init = function (params) {
        this.initVars(params);
        this.domOutlineInit();
        this.floatingMenuInit();
        this.bindEvents();
    };

    LiveEditor.prototype.initVars = function (params) {
        this.$editor = $(params.editor).find('iframe');
        this.$codePainel = $('#code-painel').find('textarea');
        this.$editHtmlModal = $('#edit-html-modal');
        this.domOutline = null;
        this.scriptList = [];
    };

    LiveEditor.prototype.domOutlineInit = function () {
        this.domOutline = DomOutline({
            realtime: true,
            onClick: this.sendEventOnClick,
            elem: this.$editor.contents().find('html body'),
            initialPosition: this.$editor.offset()
        });
        this.domOutline.start();
    };

    LiveEditor.prototype.floatingMenuInit = function () {
        window.floatingMenu = new FloatingMenu();
    };

    LiveEditor.prototype.modalEvents = function () {
        var self = this;

        this.$editHtmlModal.on('show.bs.modal', function () {
            var html = self.$currentSelected[0].outerHTML;
            $(this).find('.modal-body textarea').val(html);
        });

        $('#edit-html-modal-save').on('click', function() {
            self.operationInit('edit-html-save');
            self.$editHtmlModal.modal('hide');
        });
    };

    LiveEditor.prototype.bindEvents = function () {
        var self = this;

        this.modalEvents();

        document.addEventListener('domOutlineOnClick', function (e) {
            self.setCurrentElement(self.domOutline.element);
            self.openCurrentSettings();
            self.domOutline.pause();
        }, false);

        document.addEventListener('floatingMenuItemClicked', function (e) {
            self.operationInit(e.detail.operation);
        }, false);

        this.$editor.contents().find('html').on('click', function(e) {
            if (e.toElement != liveEditor.$currentSelected[0]) {
                floatingMenu.close();
                self.domOutline.start();
            }
        });
    };

    LiveEditor.prototype.sendEventOnClick = function () {
        var _event = new Event('domOutlineOnClick');
        document.dispatchEvent(_event);
    }
    LiveEditor.prototype.setCurrentElement = function (elem) {
        this.currentSelected = this.getElementPath(elem);
        this.$currentSelected = this.$editor.contents().find(this.currentSelected);
        console.log('Current: ' +  this.currentSelected);
    };

    LiveEditor.prototype.getElementPath = function (elem) {
        if (elem.length != 1)
            elem = $(elem);

        var path, node = elem;
        while (node.length) {
            var realNode = node[0], name = realNode.localName;
            if (!name) break;
            name = name.toLowerCase();

            var parent = node.parent();

            var siblings = parent.children(name);
            if (siblings.length > 1) {
                name += ':eq(' + siblings.index(realNode) + ')';
            }

            path = name + (path ? '>' + path : '');
            node = parent;
        }

        return path;
    };

    LiveEditor.prototype.getCurrentParentPath = function () {
        var a = this.$currentSelected[0];
        var els = [];
        while (a) {
            els.unshift(a);
            a = a.parentNode;
        }
        return els
    };

    LiveEditor.prototype.openCurrentSettings = function () {
        if (this.currentSelected) {
            var $DomOutlineBox = $('.DomOutline_box');

            floatingMenu.create({
                value: this.$currentSelected.prop('tagName').toLowerCase(),
                posLeft: $DomOutlineBox.offset().left + $DomOutlineBox.width(),
                posTop: $DomOutlineBox.offset().top,
                container: this.containerFormat()
            });
            floatingMenu.open();
        } else {
            console.log('No item has been selected...');
        }
    };

    LiveEditor.prototype.containerFormat = function () {
        var pathList = this.getCurrentParentPath(),
            _list = [];

        for (var i=0; i <= pathList.length - 1; i++) {
            if (pathList[i].tagName) {
                _list.push({
                    value: pathList[i].tagName.toLowerCase(),
                    attrs: {
                        'value': this.getElementPath(pathList[i])
                    }
                });
            }
        }

        return _list;
    };

    LiveEditor.prototype.operationInit = function (operation) {
        if (operation === 'remove') {
            this.currentSelectedRemove();
            floatingMenu.close();
            this.domOutline.start();
        }

        if (operation === 'edit-html-save') {
            this.currentSelectedEditHtml();
        }

        this.codePainelUpdate();
    };

    LiveEditor.prototype.currentSelectedRemove = function () {
        var str = '$("' + this.currentSelected + '").remove();';
        this.addToScript(str);
        this.$editor.contents().find(this.currentSelected).remove();
    };

    LiveEditor.prototype.currentSelectedEditHtml = function () {
        var html = this.$editHtmlModal.find('.modal-body textarea').val(),
            str = '$("' + this.currentSelected + '").replaceWith("' + html + '");';

        this.addToScript(str);
        this.$editor.contents().find(this.currentSelected).replaceWith(html)
    };

    LiveEditor.prototype.addToScript = function (str) {
        this.scriptList.push(str);
    };

    LiveEditor.prototype.codePainelUpdate = function () {
        this.$codePainel.val(this.scriptList);
    };

    window.LiveEditor = LiveEditor;
})(window, document, $);<commit_msg>Change edit html modal content<commit_after>/* global $ */

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

    var LiveEditor = function LiveEditor (params) {
        console.log('Live Editor Init...');
        this.init(params);
        console.log('Live Editor Done...');
    }

    LiveEditor.prototype.init = function (params) {
        this.initVars(params);
        this.domOutlineInit();
        this.floatingMenuInit();
        this.bindEvents();
    };

    LiveEditor.prototype.initVars = function (params) {
        this.$editor = $(params.editor).find('iframe');
        this.$codePainel = $('#code-painel').find('textarea');
        this.$editHtmlModal = $('#edit-html-modal');
        this.domOutline = null;
        this.scriptList = [];
    };

    LiveEditor.prototype.domOutlineInit = function () {
        this.domOutline = DomOutline({
            realtime: true,
            onClick: this.sendEventOnClick,
            elem: this.$editor.contents().find('html body'),
            initialPosition: this.$editor.offset()
        });
        this.domOutline.start();
    };

    LiveEditor.prototype.floatingMenuInit = function () {
        window.floatingMenu = new FloatingMenu();
    };

    LiveEditor.prototype.modalEvents = function () {
        var self = this;

        this.$editHtmlModal.on('show.bs.modal', function () {
            var current_without_cache = self.$editor.contents().find(self.currentSelected)[0],
                html = current_without_cache.outerHTML;
            $(this).find('.modal-body textarea').val(html);
        });

        $('#edit-html-modal-save').on('click', function() {
            self.operationInit('edit-html-save');
            self.$editHtmlModal.modal('hide');
        });
    };

    LiveEditor.prototype.bindEvents = function () {
        var self = this;

        this.modalEvents();

        document.addEventListener('domOutlineOnClick', function (e) {
            self.setCurrentElement(self.domOutline.element);
            self.openCurrentSettings();
            self.domOutline.pause();
        }, false);

        document.addEventListener('floatingMenuItemClicked', function (e) {
            self.operationInit(e.detail.operation);
        }, false);

        this.$editor.contents().find('html').on('click', function(e) {
            if (e.toElement != liveEditor.$currentSelected[0]) {
                floatingMenu.close();
                self.domOutline.start();
            }
        });
    };

    LiveEditor.prototype.sendEventOnClick = function () {
        var _event = new Event('domOutlineOnClick');
        document.dispatchEvent(_event);
    }
    LiveEditor.prototype.setCurrentElement = function (elem) {
        this.currentSelected = this.getElementPath(elem);
        this.$currentSelected = this.$editor.contents().find(this.currentSelected);
        console.log('Current: ' +  this.currentSelected);
    };

    LiveEditor.prototype.getElementPath = function (elem) {
        if (elem.length != 1)
            elem = $(elem);

        var path, node = elem;
        while (node.length) {
            var realNode = node[0], name = realNode.localName;
            if (!name) break;
            name = name.toLowerCase();

            var parent = node.parent();

            var siblings = parent.children(name);
            if (siblings.length > 1) {
                name += ':eq(' + siblings.index(realNode) + ')';
            }

            path = name + (path ? '>' + path : '');
            node = parent;
        }

        return path;
    };

    LiveEditor.prototype.getCurrentParentPath = function () {
        var a = this.$currentSelected[0];
        var els = [];
        while (a) {
            els.unshift(a);
            a = a.parentNode;
        }
        return els
    };

    LiveEditor.prototype.openCurrentSettings = function () {
        if (this.currentSelected) {
            var $DomOutlineBox = $('.DomOutline_box');

            floatingMenu.create({
                value: this.$currentSelected.prop('tagName').toLowerCase(),
                posLeft: $DomOutlineBox.offset().left + $DomOutlineBox.width(),
                posTop: $DomOutlineBox.offset().top,
                container: this.containerFormat()
            });
            floatingMenu.open();
        } else {
            console.log('No item has been selected...');
        }
    };

    LiveEditor.prototype.containerFormat = function () {
        var pathList = this.getCurrentParentPath(),
            _list = [];

        for (var i=0; i <= pathList.length - 1; i++) {
            if (pathList[i].tagName) {
                _list.push({
                    value: pathList[i].tagName.toLowerCase(),
                    attrs: {
                        'value': this.getElementPath(pathList[i])
                    }
                });
            }
        }

        return _list;
    };

    LiveEditor.prototype.operationInit = function (operation) {
        if (operation === 'remove') {
            this.currentSelectedRemove();
            floatingMenu.close();
            this.domOutline.start();
        }

        if (operation === 'edit-html-save') {
            this.currentSelectedEditHtml();
        }

        this.codePainelUpdate();
    };

    LiveEditor.prototype.currentSelectedRemove = function () {
        var str = '$("' + this.currentSelected + '").remove();';
        this.addToScript(str);
        this.$editor.contents().find(this.currentSelected).remove();
    };

    LiveEditor.prototype.currentSelectedEditHtml = function () {
        var html = this.$editHtmlModal.find('.modal-body textarea').val(),
            str = '$("' + this.currentSelected + '").replaceWith("' + html + '");';

        this.addToScript(str);
        this.$editor.contents().find(this.currentSelected).replaceWith(html)
    };

    LiveEditor.prototype.addToScript = function (str) {
        this.scriptList.push(str);
    };

    LiveEditor.prototype.codePainelUpdate = function () {
        this.$codePainel.val(this.scriptList);
    };

    window.LiveEditor = LiveEditor;
})(window, document, $);<|endoftext|>


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

var padeditbar = (function(){

  var syncAnimation = (function() {
    var SYNCING = -100;
    var DONE = 100;
    var state = DONE;
    var fps = 25;
    var step = 1/fps;
    var T_START = -0.5;
    var T_FADE = 1.0;
    var T_GONE = 1.5;
    var animator = padutils.makeAnimationScheduler(function() {
      if (state == SYNCING || state == DONE) {
        return false;
      }
      else if (state >= T_GONE) {
        state = DONE;
        $("#syncstatussyncing").css('display', 'none');
        $("#syncstatusdone").css('display', 'none');
        return false;
      }
      else if (state < 0) {
        state += step;
        if (state >= 0) {
          $("#syncstatussyncing").css('display', 'none');
          $("#syncstatusdone").css('display', 'block').css('opacity', 1);
        }
        return true;
      }
      else {
        state += step;
        if (state >= T_FADE) {
          $("#syncstatusdone").css('opacity', (T_GONE - state) / (T_GONE - T_FADE));
        }
        return true;
      }
    }, step*1000);
    return {
      syncing: function() {
        state = SYNCING;
        $("#syncstatussyncing").css('display', 'block');
        $("#syncstatusdone").css('display', 'none');
      },
      done: function() {
        state = T_START;
        animator.scheduleAnimation();
      }
    };
  }());

  var self = {
    init: function() {
      $("#editbar .editbarbutton").attr("unselectable", "on"); // for IE
      $("#editbar").removeClass("disabledtoolbar").addClass("enabledtoolbar");
    },
    isEnabled: function() {
      return ! $("#editbar").hasClass('disabledtoolbar');
    },
    disable: function() {
      $("#editbar").addClass('disabledtoolbar').removeClass("enabledtoolbar");
    },
    toolbarClick: function(cmd) {
      if (self.isEnabled()) {
        if (cmd == 'showusers') {
        $('#editbar').animate({height:'72px'});
        $('#editorcontainerbox').animate({top:'72px'});
        }
        if (cmd == 'save') {
          padsavedrevs.saveNow();
        } else {
	  padeditor.ace.callWithAce(function (ace) {
	    if (cmd == 'bold' || cmd == 'italic' || cmd == 'underline' || cmd == 'strikethrough')
	      ace.ace_toggleAttributeOnSelection(cmd);
            else if (cmd == 'undo' || cmd == 'redo')
	      ace.ace_doUndoRedo(cmd);
            else if (cmd == 'insertunorderedlist')
	      ace.ace_doInsertUnorderedList();
            else if (cmd == 'indent') {
	      if (! ace.ace_doIndentOutdent(false)) {
	       ace.ace_doInsertUnorderedList();
	      }
	    } else if (cmd == 'outdent') {
              ace.ace_doIndentOutdent(true);
	    } else if (cmd == 'clearauthorship') {
	      if ((!(ace.ace_getRep().selStart && ace.ace_getRep().selEnd)) || ace.ace_isCaret()) {
		if (window.confirm("Clear authorship colors on entire document?")) {
		  ace.ace_performDocumentApplyAttributesToCharRange(0, ace.ace_getRep().alltext.length,
							    [['author', '']]);
		}
	      } else {
		ace.ace_setAttributeOnSelection('author', '');
	      }
	    }
	  }, cmd, true);
        }
      }
      padeditor.ace.focus();
    },
    setSyncStatus: function(status) {
      if (status == "syncing") {
        syncAnimation.syncing();
      }
      else if (status == "done") {
        syncAnimation.done();
      }
    }
  };
  return self;
}());
<commit_msg>Add toggle functionality for users<commit_after>/**
 * Copyright 2009 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS-IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var padeditbar = (function(){

  var syncAnimation = (function() {
    var SYNCING = -100;
    var DONE = 100;
    var state = DONE;
    var fps = 25;
    var step = 1/fps;
    var T_START = -0.5;
    var T_FADE = 1.0;
    var T_GONE = 1.5;
    var animator = padutils.makeAnimationScheduler(function() {
      if (state == SYNCING || state == DONE) {
        return false;
      }
      else if (state >= T_GONE) {
        state = DONE;
        $("#syncstatussyncing").css('display', 'none');
        $("#syncstatusdone").css('display', 'none');
        return false;
      }
      else if (state < 0) {
        state += step;
        if (state >= 0) {
          $("#syncstatussyncing").css('display', 'none');
          $("#syncstatusdone").css('display', 'block').css('opacity', 1);
        }
        return true;
      }
      else {
        state += step;
        if (state >= T_FADE) {
          $("#syncstatusdone").css('opacity', (T_GONE - state) / (T_GONE - T_FADE));
        }
        return true;
      }
    }, step*1000);
    return {
      syncing: function() {
        state = SYNCING;
        $("#syncstatussyncing").css('display', 'block');
        $("#syncstatusdone").css('display', 'none');
      },
      done: function() {
        state = T_START;
        animator.scheduleAnimation();
      }
    };
  }());

  var self = {
    init: function() {
      $("#editbar .editbarbutton").attr("unselectable", "on"); // for IE
      $("#editbar").removeClass("disabledtoolbar").addClass("enabledtoolbar");
    },
    isEnabled: function() {
      return ! $("#editbar").hasClass('disabledtoolbar');
    },
    disable: function() {
      $("#editbar").addClass('disabledtoolbar').removeClass("enabledtoolbar");
    },
    toolbarClick: function(cmd) {
      if (self.isEnabled()) {
        if (cmd == 'showusers') {
        // get current height
        var editbarheight = $('#editbar').css('height');
          if (editbarheight == "36px"){
            // increase the size of the editbar
            $('#editbar').animate({height:'72px'});
            $('#editorcontainerbox').animate({top:'72px'});
          }
          else
          {
            // increase the size of the editbar
            $('#editbar').animate({height:'36px'});
            $('#editorcontainerbox').animate({top:'36px'});
          }
        }
        if (cmd == 'save') {
          padsavedrevs.saveNow();
        } else {
	  padeditor.ace.callWithAce(function (ace) {
	    if (cmd == 'bold' || cmd == 'italic' || cmd == 'underline' || cmd == 'strikethrough')
	      ace.ace_toggleAttributeOnSelection(cmd);
            else if (cmd == 'undo' || cmd == 'redo')
	      ace.ace_doUndoRedo(cmd);
            else if (cmd == 'insertunorderedlist')
	      ace.ace_doInsertUnorderedList();
            else if (cmd == 'indent') {
	      if (! ace.ace_doIndentOutdent(false)) {
	       ace.ace_doInsertUnorderedList();
	      }
	    } else if (cmd == 'outdent') {
              ace.ace_doIndentOutdent(true);
	    } else if (cmd == 'clearauthorship') {
	      if ((!(ace.ace_getRep().selStart && ace.ace_getRep().selEnd)) || ace.ace_isCaret()) {
		if (window.confirm("Clear authorship colors on entire document?")) {
		  ace.ace_performDocumentApplyAttributesToCharRange(0, ace.ace_getRep().alltext.length,
							    [['author', '']]);
		}
	      } else {
		ace.ace_setAttributeOnSelection('author', '');
	      }
	    }
	  }, cmd, true);
        }
      }
      padeditor.ace.focus();
    },
    setSyncStatus: function(status) {
      if (status == "syncing") {
        syncAnimation.syncing();
      }
      else if (status == "done") {
        syncAnimation.done();
      }
    }
  };
  return self;
}());
<|endoftext|>


<commit_before>var content;

var div_question_phraze;
var div_question_answer_1;
var div_question_answer_2;
var div_question_answer_3;
var div_question_answer_4;

function load() {
    content = document.getElementById("content");
    div_question_phraze = document.getElementById("question");
    div_question_answer_1 = document.getElementById("answer1Container").children[0].children[0];
    div_question_answer_2 = document.getElementById("answer2Container").children[0].children[0];
    div_question_answer_3 = document.getElementById("answer3Container").children[0].children[0];
    div_question_answer_4 = document.getElementById("answer4Container").children[0].children[0];

    resizeContent();

    initQuestions();
}

function resetPlayerPercentage() {
    setPlayer1Percentage(0);
    setPlayer2Percentage(0);
}

function setPlayer1Percentage(value) {
    var score = document.getElementById("score1");
    var valueTotal = (document.getElementById("scoreContainer").offsetWidth / 2);
    var valueAbsolute = Math.max(15, (valueTotal * value) / 100);
    score.style.left = (valueTotal - valueAbsolute) + "px";
}

function setPlayer2Percentage(value) {
    var score = document.getElementById("score2");
    var valueTotal = (document.getElementById("scoreContainer").offsetWidth / 2);
    var valueAbsolute = Math.max(15, (valueTotal * value) / 100);
    score.style.right = (valueTotal - valueAbsolute) + "px";
}

function resizeContent() {
    var screen_size = getScreenSize();
    content.style.width = screen_size[0] + "px";
    content.style.height = screen_size[1] + "px";
}

function getScreenSize() {
    var myWidth = 0,
        myHeight = 0;
    if (typeof(window.innerWidth) == 'number') {
        //Non-IE
        myWidth = window.innerWidth;
        myHeight = window.innerHeight;
    } else if (document.documentElement && (document.documentElement.clientWidth || document.documentElement.clientHeight)) {
        //IE 6+ in 'standards compliant mode'
        myWidth = document.documentElement.clientWidth;
        myHeight = document.documentElement.clientHeight;
    } else if (document.body && (document.body.clientWidth || document.body.clientHeight)) {
        //IE 4 compatible
        myWidth = document.body.clientWidth;
        myHeight = document.body.clientHeight;
    }
    return [myWidth, myHeight];
}

window.onresize = function(event) {
    resizeContent();
};
<commit_msg>Fixed typo<commit_after>var content;

var div_question_phraze;
var div_question_answer_1;
var div_question_answer_2;
var div_question_answer_3;
var div_question_answer_4;

function load() {
    content = document.getElementById("content");
    div_question_phrase = document.getElementById("question");
    div_question_answer_1 = document.getElementById("answer1Container").children[0].children[0];
    div_question_answer_2 = document.getElementById("answer2Container").children[0].children[0];
    div_question_answer_3 = document.getElementById("answer3Container").children[0].children[0];
    div_question_answer_4 = document.getElementById("answer4Container").children[0].children[0];

    resizeContent();

    initQuestions();
}

function resetPlayerPercentage() {
    setPlayer1Percentage(0);
    setPlayer2Percentage(0);
}

function setPlayer1Percentage(value) {
    var score = document.getElementById("score1");
    var valueTotal = (document.getElementById("scoreContainer").offsetWidth / 2);
    var valueAbsolute = Math.max(15, (valueTotal * value) / 100);
    score.style.left = (valueTotal - valueAbsolute) + "px";
}

function setPlayer2Percentage(value) {
    var score = document.getElementById("score2");
    var valueTotal = (document.getElementById("scoreContainer").offsetWidth / 2);
    var valueAbsolute = Math.max(15, (valueTotal * value) / 100);
    score.style.right = (valueTotal - valueAbsolute) + "px";
}

function resizeContent() {
    var screen_size = getScreenSize();
    content.style.width = screen_size[0] + "px";
    content.style.height = screen_size[1] + "px";
}

function getScreenSize() {
    var myWidth = 0,
        myHeight = 0;
    if (typeof(window.innerWidth) == 'number') {
        //Non-IE
        myWidth = window.innerWidth;
        myHeight = window.innerHeight;
    } else if (document.documentElement && (document.documentElement.clientWidth || document.documentElement.clientHeight)) {
        //IE 6+ in 'standards compliant mode'
        myWidth = document.documentElement.clientWidth;
        myHeight = document.documentElement.clientHeight;
    } else if (document.body && (document.body.clientWidth || document.body.clientHeight)) {
        //IE 4 compatible
        myWidth = document.body.clientWidth;
        myHeight = document.body.clientHeight;
    }
    return [myWidth, myHeight];
}

window.onresize = function(event) {
    resizeContent();
};
<|endoftext|>


<commit_before>(function () {
    "use strict";
    var updateInterval = 10 * 1000;  // 10s
    var status = null;

    // .templeture_text
    // .button.hot
    // .button.cold

    function getCurrentStatus(success, error) {
        var xhr = new XMLHttpRequest();
        xhr.open('GET', '/api/v1/status');
        xhr.responseType = 'json';
        xhr.onload = function () {
            if (xhr.status === 200 || xhr.status === 302) {
                status = xhr.response;
                success(status);
            } else {
                error();
            }
        };
        xhr.send();
    }

    function vote(hotOrCold, success, error) {
        var params = new FormData();
        params.append('vote', hotOrCold);

        var xhr = new XMLHttpRequest();
        xhr.open('POST', '/api/v1/status');
        xhr.responseType = 'json';
        xhr.onload = function () {
            if (xhr.status === 200 || xhr.status === 302) {
                status = xhr.response;
                success(status);
            } else {
                error();
            }
        };
        xhr.send(params);
    }

    function showErrorMessage() {
        alert('error');
    }

    function update() {
        document.querySelector('.temperature_text').innerText = status.templature;
        document.querySelector('.counter.hot').innerText = status.hot;
        document.querySelector('.counter.cold').innerText = status.cold;
    }

    getCurrentStatus(update, showErrorMessage);
    setInterval(function () {
        getCurrentStatus(update, showErrorMessage);
    }, updateInterval);

    document.querySelector('.button.hot').addEventListener('click', function () {
        vote('hot', update, showErrorMessage);
    });
    document.querySelector('.button.cold').addEventListener('click', function () {
        vote('cold', update, showErrorMessage);
    });
    for(var button of document.querySelectorAll('.button')) {
        button.onclick = function() {return false;};
    }
})();
<commit_msg>add comment<commit_after>/*
 * 温度と投票数を一定間隔で自動更新する。
 * 暑い・寒いボタンを押したときに、投票する。
 */

(function () {
    "use strict";
    var updateInterval = 10 * 1000;  // 10s
    var status = null;

    // .templeture_text
    // .button.hot
    // .button.cold

    function getCurrentStatus(success, error) {
        var xhr = new XMLHttpRequest();
        xhr.open('GET', '/api/v1/status');
        xhr.responseType = 'json';
        xhr.onload = function () {
            if (xhr.status === 200 || xhr.status === 302) {
                status = xhr.response;
                success(status);
            } else {
                error();
            }
        };
        xhr.send();
    }

    function vote(hotOrCold, success, error) {
        var params = new FormData();
        params.append('vote', hotOrCold);

        var xhr = new XMLHttpRequest();
        xhr.open('POST', '/api/v1/status');
        xhr.responseType = 'json';
        xhr.onload = function () {
            if (xhr.status === 200 || xhr.status === 302) {
                status = xhr.response;
                success(status);
            } else {
                error();
            }
        };
        xhr.send(params);
    }

    function showErrorMessage() {
        alert('error');
    }

    function update() {
        document.querySelector('.temperature_text').innerText = status.templature;
        document.querySelector('.counter.hot').innerText = status.hot;
        document.querySelector('.counter.cold').innerText = status.cold;
    }

    getCurrentStatus(update, showErrorMessage);
    setInterval(function () {
        getCurrentStatus(update, showErrorMessage);
    }, updateInterval);

    document.querySelector('.button.hot').addEventListener('click', function () {
        vote('hot', update, showErrorMessage);
    });
    document.querySelector('.button.cold').addEventListener('click', function () {
        vote('cold', update, showErrorMessage);
    });
    for(var button of document.querySelectorAll('.button')) {
        button.onclick = function() {return false;};
    }
})();
<|endoftext|>


<commit_before>(function($) {

    $(document).ready(function() {

        function setSelectOptions(data) {
            $('#tweet-msgs').html('<option></option>');
            for(var x=0; x<data.length; x++) {
                var msg = data[x].copy;
                var option = $('<option></option>').attr('value', msg).text(msg);
                $('#tweet-msgs').append(option);
            }
        }

        var tweet_pk;
        var handle;

        function checkTweetLength() {
            var length = $('#tweet-msg').val().length;
            if(length > 140) {
                $('#tweet-msg').css({'background-color': '#fcc'});
            } else {
                $('#tweet-msg').css({'background-color': '#cfc'});
            }
            $('#tweet-length').html('Length: ' + length);
        }

        $('.send_tweet').on('click', function(e) {

            // This is a bit horrible but will grab the account text so we can get
            //the particular id for this to filter messages against
            var account = $(this).parent().parent().parent().prev().prev().prev().prev().text();
            var account_id = account.match(/\((\d+)\)/)[1];
            tweet_pk = $(this).closest('td').prevAll(':last').find('.action-select').val();
            handle = $(this).closest('td').prevAll(':eq(4)').find('a').text();

            // reset modal form
            $('#tweet-msg').val('');
            $('#tweet-log').html('');
            $('.modal-tweet').val('Send');

            // TODO: you should be ashamed! pass as obj instead and undupe this!
            if($(this).data('msgtype') == 'tryagain') {
                $.getJSON('/api/messages/?type=f&account=' + account_id, setSelectOptions);
            } else {
                $.getJSON('/api/messages/?type=s&account=' + account_id, setSelectOptions);
            }

            $('#myModal').modal();
        });

        $('#tweet-msg').on('keyup', checkTweetLength);

        $('#tweet-msgs').on('change', function(e) {
            $('#tweet-msg').val('@' + handle + ' ' + $('#tweet-msgs').val());
            checkTweetLength();
        });

        $('.modal-tweet').on('click', function(e) {
            var msg = $('#tweet-msg').val();
            $(this).parentsUntil('#modal').find('#tweet-log').load('/send-tweet/?msg=' + escape(msg) + '&tweet_pk=' + tweet_pk);
        });

        var textareaPlaceholder = 'Add an internal note (not public). Remember to click save!';
        $('#result_list .vLargeTextField').attr('placeholder', textareaPlaceholder);

    });

})(django.jQuery);
<commit_msg>once tweet button is clicked hide it and show again on modal init<commit_after>(function($) {

    $(document).ready(function() {

        function setSelectOptions(data) {
            $('#tweet-msgs').html('<option></option>');
            for(var x=0; x<data.length; x++) {
                var msg = data[x].copy;
                var option = $('<option></option>').attr('value', msg).text(msg);
                $('#tweet-msgs').append(option);
            }
        }

        var tweet_pk;
        var handle;

        function checkTweetLength() {
            var length = $('#tweet-msg').val().length;
            if(length > 140) {
                $('#tweet-msg').css({'background-color': '#fcc'});
            } else {
                $('#tweet-msg').css({'background-color': '#cfc'});
            }
            $('#tweet-length').html('Length: ' + length);
        }

        $('.send_tweet').on('click', function(e) {

            // This is a bit horrible but will grab the account text so we can get
            //the particular id for this to filter messages against
            var account = $(this).parent().parent().parent().prev().prev().prev().prev().text();
            var account_id = account.match(/\((\d+)\)/)[1];
            tweet_pk = $(this).closest('td').prevAll(':last').find('.action-select').val();
            handle = $(this).closest('td').prevAll(':eq(4)').find('a').text();

            // reset modal form
            $('#tweet-msg').val('');
            $('#tweet-log').html('');
            $('.modal-tweet').val('Send').show();

            // TODO: you should be ashamed! pass as obj instead and undupe this!
            if($(this).data('msgtype') == 'tryagain') {
                $.getJSON('/api/messages/?type=f&account=' + account_id, setSelectOptions);
            } else {
                $.getJSON('/api/messages/?type=s&account=' + account_id, setSelectOptions);
            }

            $('#myModal').modal();
        });

        $('#tweet-msg').on('keyup', checkTweetLength);

        $('#tweet-msgs').on('change', function(e) {
            $('#tweet-msg').val('@' + handle + ' ' + $('#tweet-msgs').val());
            checkTweetLength();
        });

        $('.modal-tweet').on('click', function(e) {
            var msg = $('#tweet-msg').val();
            $(this).fadeOut();
            $(this).prev('a').text('Close');
            $(this).parentsUntil('#modal').find('#tweet-log').load('/send-tweet/?msg=' + escape(msg) + '&tweet_pk=' + tweet_pk);
        });

        var textareaPlaceholder = 'Add an internal note (not public). Remember to click save!';
        $('#result_list .vLargeTextField').attr('placeholder', textareaPlaceholder);

    });

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


<commit_before>// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE

// Define search commands. Depends on dialog.js or another
// implementation of the openDialog method.

// Replace works a little oddly -- it will do the replace on the next
// Ctrl-G (or whatever is bound to findNext) press. You prevent a
// replace by making sure the match is no longer selected when hitting
// Ctrl-G.

(function(mod) {
    if (typeof exports == "object" && typeof module == "object") // CommonJS
      mod(require("../../lib/codemirror"), require("./searchcursor"));
    else if (typeof define == "function" && define.amd) // AMD
      define(["../../lib/codemirror", "./searchcursor"], mod);
    else // Plain browser env
      mod(CodeMirror);
  })(function(CodeMirror) {
    "use strict";

    function searchOverlay(cm, state, caseInsensitive) {

      var query = state.query;
      var loopMatchPositionIndex = 0;
      state.initialFocusedMatchIndex = -1;

      if (typeof query == "string")
        query = new RegExp(query.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"), caseInsensitive ? "gi" : "g");
      else if (!query.global)
        query = new RegExp(query.source, query.ignoreCase ? "gi" : "g");

      return {token: function(stream) {
        query.lastIndex = stream.pos;
        var match = query.exec(stream.string);
        if (match && match.index == stream.pos) {
          stream.pos += match[0].length || 1;

          if (state.initialFocusedMatchIndex == -1) {
            var fromCursor = cm.getCursor('from')
            if (stream.lineOracle.line > fromCursor.line || (stream.lineOracle.line == fromCursor.line && stream.start >= fromCursor.ch)) {
              state.initialFocusedMatchIndex = loopMatchPositionIndex;
             }
             loopMatchPositionIndex++;
          }

          return "searching";
        } else if (match) {
          stream.pos = match.index;
        } else {
          stream.skipToEnd();
        }
      }};
    }

    function SearchState() {
      this.posFrom = this.posTo = this.lastQuery = this.query = null;
      this.overlay = null;
    }

    function getSearchState(cm) {
      return cm.state.search || (cm.state.search = new SearchState());
    }

    function queryCaseInsensitive(query) {
      //codemirror default is if the query string is all lowercase, do a case insensitive search.
      //commenting out here so it's case insensitive whether query is lowercase or not.
      return typeof query == "string" // && query == query.toLowerCase();
    }

    function getSearchCursor(cm, query, pos) {
      return cm.getSearchCursor(query, pos, {caseFold: queryCaseInsensitive(query), multiline: true});
    }

    function parseString(string) {
      return string.replace(/\\(.)/g, function(_, ch) {
        if (ch == "n") return "\n"
        if (ch == "r") return "\r"
        return ch
      })
    }

    function parseQuery(query) {
      var isRE = query.match(/^\/(.*)\/([a-z]*)$/);
      if (isRE) {
        try { query = new RegExp(isRE[1], isRE[2].indexOf("i") == -1 ? "" : "i"); }
        catch(e) {} // Not a regular expression after all, do a string search
      } else {
        query = parseString(query)
      }
      if (typeof query == "string" ? query == "" : query.test(""))
        query = /x^/;
      return query;
    }

    function startSearch(cm, state, query) {
      state.queryText = query;
      state.query = parseQuery(query);
      cm.removeOverlay(state.overlay, queryCaseInsensitive(state.query));
      state.overlay = searchOverlay(cm, state, queryCaseInsensitive(state.query));
      cm.addOverlay(state.overlay);
      if (cm.showMatchesOnScrollbar) {
        if (state.annotate) { state.annotate.clear(); state.annotate = null; }
        state.annotate = cm.showMatchesOnScrollbar(state.query, queryCaseInsensitive(state.query));
      }
    }

    function doSearch(cm, rev, focus) {
      var state = getSearchState(cm);
      if (state.query) return findNext(cm, rev, focus);
      var q = cm.getSelection() || state.lastQuery;
      if (q instanceof RegExp && q.source == "x^") q = null
      const query = cm.state.query;
      if (query && !state.query) cm.operation(function () {
        startSearch(cm, state, query);
        state.posFrom = state.posTo = cm.getCursor();
        findNext(cm, rev);
      });
      focusOnMatch(state, null, false)
    }

    function clearFocusedMatches(cm) {
      const focusClassName = "cm-searching-focus";
      const focusedElements = document.getElementsByClassName(focusClassName);
      const focusedMatchID = getSearchState(cm).focusedMatchID;

      while (focusedElements.length > 0) {
        var element = focusedElements[0];
        element.classList.remove(focusClassName);
        if (element.id === focusedMatchID) element.id = "";
      }
    }

    function markReplacedText(cm, cursor) {
      const state = getSearchState(cm);
      const marker = cm.markText(cursor.from(), cursor.to(), { className: 'cm-searching-replaced' })
      if (state.replacedMarkers) {
        state.replacedMarkers.push(marker);
      } else {
        state.replacedMarkers = [marker];
      }
    }

    function clearReplaced(state) {
      if (state.replacedMarkers) {
        state.replacedMarkers.forEach((marker) => { marker.clear() });
        state.replacedMarkers = null;
      }
    }

    function focusOnMatch(state, focus, forceIncrement) {
      const matches = document.getElementsByClassName("cm-searching");
      const matchesCount = matches.length;

      var focusedMatchIndex;
      //here we're using focus as a flag for whether they came from find next / prev or from replace.
      //if they came from find next/previous, we are okay with focusedMatchIndex being -1 because it will get decremented/incremented below
      //if they came from replace (where focus is null), we want to reset focusedMatchIndex to 0 but NOT increment
      if (state.focusedMatchIndex != undefined && state.focusedMatchIndex != null && ((state.focusedMatchIndex > -1 && !focus) || (state.focusedMatchIndex >= -1 && focus) || (state.focusedMatchIndex == -1 && !focus && forceIncrement))) {
        focusedMatchIndex = state.focusedMatchIndex;
      } else if (state.initialFocusedMatchIndex != undefined && state.initialFocusedMatchIndex != null && state.initialFocusedMatchIndex > -1) {
        focusedMatchIndex = state.initialFocusedMatchIndex;
      } else {
        focusedMatchIndex = 0;
      }

      if (forceIncrement || focus) {
        if (forceIncrement || focus.next) {
          if (focusedMatchIndex >= matchesCount - 1) {
            focusedMatchIndex = 0;
          } else {
            focusedMatchIndex++;
          }
        } else if (focus.prev) {
          if (focusedMatchIndex > 0) {
            focusedMatchIndex--;
          } else {
            focusedMatchIndex = matchesCount - 1;
          }
        }
      }

      const focusedMatchID = `cm-searching-focus-id-${focusedMatchIndex}`;
      const focusedMatch = focusOnMatchAtIndex(matches, focusedMatchIndex, focusedMatchID);

      state.matchesCount = matchesCount;
      state.focusedMatch = focusedMatch;

      if (state.focusedMatch) {
        state.focusedMatchIndex = focusedMatchIndex;
        state.focusedMatchID = focusedMatchID;
      } else {
        state.focusedMatchIndex = -1;
        state.focusedMatchID = null;
      }

      const message = {
        findInPageMatchesCount: state.matchesCount,
        findInPageFocusedMatchIndex: state.focusedMatchIndex,
        findInPageFocusedMatchID: state.focusedMatchID
      };

      window.webkit.messageHandlers.codeMirrorSearchMessage.postMessage(message);
      state.initialFocusedMatchIndex = -1;
    }

    function focusOnMatchAtIndex(matches, index, id) {
      if (matches.length == 0) return null;
      const focusClassName = "cm-searching-focus";
      const match = matches[index];
      if (!match) return null;
      match.classList.add(focusClassName);
      match.id = id;
      return match
    }

    function selectLastFocusedMatch(cm) {
      if (cm.hasFocus()) return;
      if (cm.getSelection() !== "") return focusWithoutScroll(cm);
      const scrollTop = document.body.scrollTop;
      var state = getSearchState(cm);
      var sel = window.getSelection()
      if (sel.rangeCount > 0) {
        sel.removeAllRanges();
      }
      const range = document.createRange();
      range.selectNode(state.focusedMatch)
      sel.addRange(range);
      document.body.scrollTop = scrollTop;
    }

    function findNext(cm, rev, focus) {cm.operation(function() {
      var state = getSearchState(cm);
      var cursor = getSearchCursor(cm, state.query, rev ? state.posFrom : state.posTo);
      if (!cursor.find(rev)) {
        cursor = getSearchCursor(cm, state.query, rev ? CodeMirror.Pos(cm.lastLine()) : CodeMirror.Pos(cm.firstLine(), 0));
        state.focusedMatchIndex = -1;
        state.initialFocusedMatchIndex = -1;
        if (!cursor.find(rev)) return;
      }
      state.posFrom = cursor.from(); state.posTo = cursor.to();
      if (focus) focusOnMatch(state, focus, false)
    });}

    function clearSearch(cm) {cm.operation(function() {
      var state = getSearchState(cm);
      state.lastQuery = state.query;
      if (!state.query) return;
      clearFocusedMatches(cm);
      clearReplaced(state);
      state.focusedMatchIndex = null
      state.initialFocusedMatchIndex = null;
      state.query = state.queryText = null;
      cm.removeOverlay(state.overlay);
      if (state.annotate) { state.annotate.clear(); state.annotate = null; }
    });}

    function replaceAll(cm, query, text) {
      var count = 0;
      cm.operation(function() {
        for (var cursor = getSearchCursor(cm, query); cursor.findNext();) {
          if (typeof query != "string") {
            var match = cm.getRange(cursor.from(), cursor.to()).match(query);
            cursor.replace(text.replace(/\$(\d)/g, function(_, i) {return match[i];}));
          } else {
            cursor.replace(text);
            markReplacedText(cm, cursor);
          }
          count++;
        }
      });
      cm.state.replaceAllCount = count;
    }

    //same as replace(cm, all) but bypasses CodeMirror dialogs. Split this up into all & single variants for simplicity
    function replaceAllWithoutDialogs(cm) {
      var replaceText = cm.state.replaceText;
      if (cm.getOption("readOnly")) return;
      if (!replaceText) return;

      var query = cm.state.query;
      query = parseQuery(query);
      replaceText = parseString(replaceText);
      cm.isReplacing = true;
      replaceAll(cm, query, replaceText);
      cm.isReplacing = false;

      //resets count to 0/0
      let state = getSearchState(cm);
      focusOnMatch(state, null, false);
    }

    function replaceSingleWithoutDialogs(cm) {
      if (cm.getOption("readOnly")) return;
      var replaceText = cm.state.replaceText;
      if (!replaceText) return;

      var state = getSearchState(cm);
      var query = state.query;
      query = parseQuery(query);
      replaceText = parseString(replaceText);
      var cursor = getSearchCursor(cm, query, state.posFrom);

      var advance = function(shouldReplace) {
        var start = cursor.from(), match;
        if (!(match = cursor.findNext())) {
          cursor = getSearchCursor(cm, query);
          state.focusedMatchIndex = 0;
          state.focusedMatchIndex = -1;
          state.initialFocusedMatchIndex = -1;
          if (!(match = cursor.findNext()) || (start && cursor.from().line == start.line && cursor.from().ch == start.ch)) {
            focusOnMatch(state, null, false); //resets count to 0/0
            return;
          }
        }

        state.posFrom = cursor.from(); state.posTo = cursor.to();
        if (shouldReplace) {
          cm.isReplacing = true;

          cm.setCursor(state.posFrom)

          doReplace(cm, state);
          cm.isReplacing = false;
        }
      }
      var doReplace = function(cm, state) {
        cursor.replace(replaceText);
        markReplacedText(cm, cursor);
        advance(false);
        var forceIncrement = replaceText.includes(query) || replaceText.toLowerCase() === query.toLowerCase();
        focusOnMatch(state, null, forceIncrement);
      };
      advance(true);
    }

    function replace(cm, all) {
      if (cm.getOption("readOnly")) return;
      var query = cm.getSelection() || getSearchState(cm).lastQuery;
      var dialogText = '' + (all ? cm.phrase("Replace all:") : cm.phrase("Replace:")) + '';
      dialog(cm, dialogText + getReplaceQueryDialog(cm), dialogText, query, function(query) {
        if (!query) return;
        query = parseQuery(query);
        dialog(cm, getReplacementQueryDialog(cm), cm.phrase("Replace with:"), "", function(text) {
          text = parseString(text)
          if (all) {
            replaceAll(cm, query, text)
          } else {
            clearSearch(cm);
            var cursor = getSearchCursor(cm, query, cm.getCursor("from"));
            var advance = function() {
              var start = cursor.from(), match;
              if (!(match = cursor.findNext())) {
                cursor = getSearchCursor(cm, query);
                if (!(match = cursor.findNext()) ||
                    (start && cursor.from().line == start.line && cursor.from().ch == start.ch)) return;
              }
              cm.setSelection(cursor.from(), cursor.to());
              cm.scrollIntoView({from: cursor.from(), to: cursor.to()});
              confirmDialog(cm, getDoReplaceConfirm(cm), cm.phrase("Replace?"),
                            [function() {doReplace(match);}, advance,
                             function() {replaceAll(cm, query, text)}]);
            };
            var doReplace = function(match) {
              cursor.replace(typeof query == "string" ? text :
                             text.replace(/\$(\d)/g, function(_, i) {return match[i];}));
              advance();
            };
            advance();
          }
        });
      });
    }

    CodeMirror.commands.find = function(cm) {clearSearch(cm); doSearch(cm);};
    CodeMirror.commands.findNext = function(cm) {clearFocusedMatches(cm); doSearch(cm, false, {next: true});};
    CodeMirror.commands.findPrev = function(cm) {clearFocusedMatches(cm); doSearch(cm, true, {prev: true});};
    CodeMirror.commands.clearSearch = clearSearch;
    CodeMirror.commands.replace = replace;
    CodeMirror.commands.replaceAll = function(cm) {replace(cm, true);};
    CodeMirror.commands.replaceAllWithoutDialogs = function(cm) { replaceAllWithoutDialogs(cm);};
    CodeMirror.commands.replaceSingleWithoutDialogs = function(cm) { replaceSingleWithoutDialogs(cm);};
  });
<commit_msg>Combine clear and search into one operation<commit_after>// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE

// Define search commands. Depends on dialog.js or another
// implementation of the openDialog method.

// Replace works a little oddly -- it will do the replace on the next
// Ctrl-G (or whatever is bound to findNext) press. You prevent a
// replace by making sure the match is no longer selected when hitting
// Ctrl-G.

(function(mod) {
    if (typeof exports == "object" && typeof module == "object") // CommonJS
      mod(require("../../lib/codemirror"), require("./searchcursor"));
    else if (typeof define == "function" && define.amd) // AMD
      define(["../../lib/codemirror", "./searchcursor"], mod);
    else // Plain browser env
      mod(CodeMirror);
  })(function(CodeMirror) {
    "use strict";

    function searchOverlay(cm, state, caseInsensitive) {

      var query = state.query;
      var loopMatchPositionIndex = 0;
      state.initialFocusedMatchIndex = -1;

      if (typeof query == "string")
        query = new RegExp(query.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"), caseInsensitive ? "gi" : "g");
      else if (!query.global)
        query = new RegExp(query.source, query.ignoreCase ? "gi" : "g");

      return {token: function(stream) {
        query.lastIndex = stream.pos;
        var match = query.exec(stream.string);
        if (match && match.index == stream.pos) {
          stream.pos += match[0].length || 1;

          if (state.initialFocusedMatchIndex == -1) {
            var fromCursor = cm.getCursor('from')
            if (stream.lineOracle.line > fromCursor.line || (stream.lineOracle.line == fromCursor.line && stream.start >= fromCursor.ch)) {
              state.initialFocusedMatchIndex = loopMatchPositionIndex;
             }
             loopMatchPositionIndex++;
          }

          return "searching";
        } else if (match) {
          stream.pos = match.index;
        } else {
          stream.skipToEnd();
        }
      }};
    }

    function SearchState() {
      this.posFrom = this.posTo = this.lastQuery = this.query = null;
      this.overlay = null;
    }

    function getSearchState(cm) {
      return cm.state.search || (cm.state.search = new SearchState());
    }

    function queryCaseInsensitive(query) {
      //codemirror default is if the query string is all lowercase, do a case insensitive search.
      //commenting out here so it's case insensitive whether query is lowercase or not.
      return typeof query == "string" // && query == query.toLowerCase();
    }

    function getSearchCursor(cm, query, pos) {
      return cm.getSearchCursor(query, pos, {caseFold: queryCaseInsensitive(query), multiline: true});
    }

    function parseString(string) {
      return string.replace(/\\(.)/g, function(_, ch) {
        if (ch == "n") return "\n"
        if (ch == "r") return "\r"
        return ch
      })
    }

    function parseQuery(query) {
      var isRE = query.match(/^\/(.*)\/([a-z]*)$/);
      if (isRE) {
        try { query = new RegExp(isRE[1], isRE[2].indexOf("i") == -1 ? "" : "i"); }
        catch(e) {} // Not a regular expression after all, do a string search
      } else {
        query = parseString(query)
      }
      if (typeof query == "string" ? query == "" : query.test(""))
        query = /x^/;
      return query;
    }

    function startSearch(cm, state, query) {
      state.queryText = query;
      state.query = parseQuery(query);
      cm.removeOverlay(state.overlay, queryCaseInsensitive(state.query));
      state.overlay = searchOverlay(cm, state, queryCaseInsensitive(state.query));
      cm.addOverlay(state.overlay);
      if (cm.showMatchesOnScrollbar) {
        if (state.annotate) { state.annotate.clear(); state.annotate = null; }
        state.annotate = cm.showMatchesOnScrollbar(state.query, queryCaseInsensitive(state.query));
      }
    }

    function doSearch(cm, rev, focus) {
      var state = getSearchState(cm);
      if (state.query) return findNext(cm, rev, focus);
      var q = cm.getSelection() || state.lastQuery;
      if (q instanceof RegExp && q.source == "x^") q = null
      const query = cm.state.query;
      if (query && !state.query) cm.operation(function () {
        startSearch(cm, state, query);
        state.posFrom = state.posTo = cm.getCursor();
        findNext(cm, rev);
      });
      focusOnMatch(state, null, false)
    }

    function clearFocusedMatches(cm) {
      const focusClassName = "cm-searching-focus";
      const focusedElements = document.getElementsByClassName(focusClassName);
      const focusedMatchID = getSearchState(cm).focusedMatchID;

      while (focusedElements.length > 0) {
        var element = focusedElements[0];
        element.classList.remove(focusClassName);
        if (element.id === focusedMatchID) element.id = "";
      }
    }

    function markReplacedText(cm, cursor) {
      const state = getSearchState(cm);
      const marker = cm.markText(cursor.from(), cursor.to(), { className: 'cm-searching-replaced' })
      if (state.replacedMarkers) {
        state.replacedMarkers.push(marker);
      } else {
        state.replacedMarkers = [marker];
      }
    }

    function clearReplaced(state) {
      if (state.replacedMarkers) {
        state.replacedMarkers.forEach((marker) => { marker.clear() });
        state.replacedMarkers = null;
      }
    }

    function focusOnMatch(state, focus, forceIncrement) {
      const matches = document.getElementsByClassName("cm-searching");
      const matchesCount = matches.length;

      var focusedMatchIndex;
      //here we're using focus as a flag for whether they came from find next / prev or from replace.
      //if they came from find next/previous, we are okay with focusedMatchIndex being -1 because it will get decremented/incremented below
      //if they came from replace (where focus is null), we want to reset focusedMatchIndex to 0 but NOT increment
      if (state.focusedMatchIndex != undefined && state.focusedMatchIndex != null && ((state.focusedMatchIndex > -1 && !focus) || (state.focusedMatchIndex >= -1 && focus) || (state.focusedMatchIndex == -1 && !focus && forceIncrement))) {
        focusedMatchIndex = state.focusedMatchIndex;
      } else if (state.initialFocusedMatchIndex != undefined && state.initialFocusedMatchIndex != null && state.initialFocusedMatchIndex > -1) {
        focusedMatchIndex = state.initialFocusedMatchIndex;
      } else {
        focusedMatchIndex = 0;
      }

      if (forceIncrement || focus) {
        if (forceIncrement || focus.next) {
          if (focusedMatchIndex >= matchesCount - 1) {
            focusedMatchIndex = 0;
          } else {
            focusedMatchIndex++;
          }
        } else if (focus.prev) {
          if (focusedMatchIndex > 0) {
            focusedMatchIndex--;
          } else {
            focusedMatchIndex = matchesCount - 1;
          }
        }
      }

      const focusedMatchID = `cm-searching-focus-id-${focusedMatchIndex}`;
      const focusedMatch = focusOnMatchAtIndex(matches, focusedMatchIndex, focusedMatchID);

      state.matchesCount = matchesCount;
      state.focusedMatch = focusedMatch;

      if (state.focusedMatch) {
        state.focusedMatchIndex = focusedMatchIndex;
        state.focusedMatchID = focusedMatchID;
      } else {
        state.focusedMatchIndex = -1;
        state.focusedMatchID = null;
      }

      const message = {
        findInPageMatchesCount: state.matchesCount,
        findInPageFocusedMatchIndex: state.focusedMatchIndex,
        findInPageFocusedMatchID: state.focusedMatchID
      };

      window.webkit.messageHandlers.codeMirrorSearchMessage.postMessage(message);
      state.initialFocusedMatchIndex = -1;
    }

    function focusOnMatchAtIndex(matches, index, id) {
      if (matches.length == 0) return null;
      const focusClassName = "cm-searching-focus";
      const match = matches[index];
      if (!match) return null;
      match.classList.add(focusClassName);
      match.id = id;
      return match
    }

    function selectLastFocusedMatch(cm) {
      if (cm.hasFocus()) return;
      if (cm.getSelection() !== "") return focusWithoutScroll(cm);
      const scrollTop = document.body.scrollTop;
      var state = getSearchState(cm);
      var sel = window.getSelection()
      if (sel.rangeCount > 0) {
        sel.removeAllRanges();
      }
      const range = document.createRange();
      range.selectNode(state.focusedMatch)
      sel.addRange(range);
      document.body.scrollTop = scrollTop;
    }

    function findNext(cm, rev, focus) {cm.operation(function() {
      var state = getSearchState(cm);
      var cursor = getSearchCursor(cm, state.query, rev ? state.posFrom : state.posTo);
      if (!cursor.find(rev)) {
        cursor = getSearchCursor(cm, state.query, rev ? CodeMirror.Pos(cm.lastLine()) : CodeMirror.Pos(cm.firstLine(), 0));
        state.focusedMatchIndex = -1;
        state.initialFocusedMatchIndex = -1;
        if (!cursor.find(rev)) return;
      }
      state.posFrom = cursor.from(); state.posTo = cursor.to();
      if (focus) focusOnMatch(state, focus, false)
    });}

    function clearSearch(cm) {cm.operation(function() {
      var state = getSearchState(cm);
      state.lastQuery = state.query;
      if (!state.query) return;
      clearFocusedMatches(cm);
      clearReplaced(state);
      state.focusedMatchIndex = null
      state.initialFocusedMatchIndex = null;
      state.query = state.queryText = null;
      cm.removeOverlay(state.overlay);
      if (state.annotate) { state.annotate.clear(); state.annotate = null; }
    });}

    function replaceAll(cm, query, text) {
      var count = 0;
      cm.operation(function() {
        for (var cursor = getSearchCursor(cm, query); cursor.findNext();) {
          if (typeof query != "string") {
            var match = cm.getRange(cursor.from(), cursor.to()).match(query);
            cursor.replace(text.replace(/\$(\d)/g, function(_, i) {return match[i];}));
          } else {
            cursor.replace(text);
            markReplacedText(cm, cursor);
          }
          count++;
        }
      });
      cm.state.replaceAllCount = count;
    }

    //same as replace(cm, all) but bypasses CodeMirror dialogs. Split this up into all & single variants for simplicity
    function replaceAllWithoutDialogs(cm) {
      var replaceText = cm.state.replaceText;
      if (cm.getOption("readOnly")) return;
      if (!replaceText) return;

      var query = cm.state.query;
      query = parseQuery(query);
      replaceText = parseString(replaceText);
      cm.isReplacing = true;
      replaceAll(cm, query, replaceText);
      cm.isReplacing = false;

      //resets count to 0/0
      let state = getSearchState(cm);
      focusOnMatch(state, null, false);
    }

    function replaceSingleWithoutDialogs(cm) {
      if (cm.getOption("readOnly")) return;
      var replaceText = cm.state.replaceText;
      if (!replaceText) return;

      var state = getSearchState(cm);
      var query = state.query;
      query = parseQuery(query);
      replaceText = parseString(replaceText);
      var cursor = getSearchCursor(cm, query, state.posFrom);

      var advance = function(shouldReplace) {
        var start = cursor.from(), match;
        if (!(match = cursor.findNext())) {
          cursor = getSearchCursor(cm, query);
          state.focusedMatchIndex = 0;
          state.focusedMatchIndex = -1;
          state.initialFocusedMatchIndex = -1;
          if (!(match = cursor.findNext()) || (start && cursor.from().line == start.line && cursor.from().ch == start.ch)) {
            focusOnMatch(state, null, false); //resets count to 0/0
            return;
          }
        }

        state.posFrom = cursor.from(); state.posTo = cursor.to();
        if (shouldReplace) {
          cm.isReplacing = true;

          cm.setCursor(state.posFrom)

          doReplace(cm, state);
          cm.isReplacing = false;
        }
      }
      var doReplace = function(cm, state) {
        cursor.replace(replaceText);
        markReplacedText(cm, cursor);
        advance(false);
        var forceIncrement = replaceText.includes(query) || replaceText.toLowerCase() === query.toLowerCase();
        focusOnMatch(state, null, forceIncrement);
      };
      advance(true);
    }

    function replace(cm, all) {
      if (cm.getOption("readOnly")) return;
      var query = cm.getSelection() || getSearchState(cm).lastQuery;
      var dialogText = '' + (all ? cm.phrase("Replace all:") : cm.phrase("Replace:")) + '';
      dialog(cm, dialogText + getReplaceQueryDialog(cm), dialogText, query, function(query) {
        if (!query) return;
        query = parseQuery(query);
        dialog(cm, getReplacementQueryDialog(cm), cm.phrase("Replace with:"), "", function(text) {
          text = parseString(text)
          if (all) {
            replaceAll(cm, query, text)
          } else {
            clearSearch(cm);
            var cursor = getSearchCursor(cm, query, cm.getCursor("from"));
            var advance = function() {
              var start = cursor.from(), match;
              if (!(match = cursor.findNext())) {
                cursor = getSearchCursor(cm, query);
                if (!(match = cursor.findNext()) ||
                    (start && cursor.from().line == start.line && cursor.from().ch == start.ch)) return;
              }
              cm.setSelection(cursor.from(), cursor.to());
              cm.scrollIntoView({from: cursor.from(), to: cursor.to()});
              confirmDialog(cm, getDoReplaceConfirm(cm), cm.phrase("Replace?"),
                            [function() {doReplace(match);}, advance,
                             function() {replaceAll(cm, query, text)}]);
            };
            var doReplace = function(match) {
              cursor.replace(typeof query == "string" ? text :
                             text.replace(/\$(\d)/g, function(_, i) {return match[i];}));
              advance();
            };
            advance();
          }
        });
      });
    }

    CodeMirror.commands.find = function(cm) {
      cm.operation(function () {
        clearSearch(cm);
        doSearch(cm);
      });
      focusOnMatch(getSearchState(cm), null, false);
    };
    CodeMirror.commands.findNext = function(cm) {
      cm.operation(function () {
        clearFocusedMatches(cm);
        doSearch(cm, false, {next: true});
      });
      focusOnMatch(getSearchState(cm), null, false);
    };
    CodeMirror.commands.findPrev = function(cm) {
      cm.operation(function () {
        clearFocusedMatches(cm);
        doSearch(cm, false, {prev: true});
      });
      focusOnMatch(getSearchState(cm), null, false);
    };
    CodeMirror.commands.clearSearch = clearSearch;
    CodeMirror.commands.replace = replace;
    CodeMirror.commands.replaceAll = function(cm) {replace(cm, true);};
    CodeMirror.commands.replaceAllWithoutDialogs = function(cm) { replaceAllWithoutDialogs(cm);};
    CodeMirror.commands.replaceSingleWithoutDialogs = function(cm) { replaceSingleWithoutDialogs(cm);};
  });
<|endoftext|>


<commit_before>(function(){

    xtag.register('widget-DAQ', {
        extends: 'div',
        lifecycle: {
            created: function() {
                var xString, option, title, deckWrap;

                this.width = this.offsetWidth;
                this.height = window.innerHeight*0.6;
                this.showing = 0;

                //get the DAQ structure
                XHR('http://' + this.MIDAS + '/?cmd=jcopy&odb=/DAQ&encoding=json-nokeys',
                    function(res){
                        this.buildDAQ(res);
                    }.bind(this),
                    'application/json');

                //build DOM
                this.navBlock = document.createElement('div');
                this.navBlock.setAttribute('class', 'DAQnav');
                this.appendChild(this.navBlock);

                title = document.createElement('h1');
                title.innerHTML = 'DAQ';
                this.navBlock.appendChild(title);

                this.cardNav = document.createElement('select');
                this.cardNav.setAttribute('id', 'DAQnav')
                this.cardNav.setAttribute('class', 'stdin');
                this.cardNav.onchange = function(){
                    var targetIndex = selected('DAQnav')
                    document.getElementById('DAQdeck').shuffleTo(targetIndex);
                    this.showing = targetIndex - 1;
                }.bind(this)
                this.navBlock.appendChild(this.cardNav);

                option = document.createElement('option');
                option.value = 0;
                option.innerHTML = 'Master'
                this.cardNav.appendChild(option);

                deckWrap = document.createElement('div');
                this.appendChild(deckWrap);

                xString = '<x-deck id="DAQdeck" selected-index=0>';
                xString += '<x-card id="DAQmasterCard"></x-card></x-deck>';
                xtag.innerHTML(deckWrap, xString);
                this.nCards = 1

                this.masterBlock = document.createElement('div');
                this.masterBlock.setAttribute('class', 'DAQheadNode');
                document.getElementById('DAQmasterCard').appendChild(this.masterBlock);

                this.collectorBlock = document.createElement('div');
                this.collectorBlock.setAttribute('id', 'collectorBlock');
                document.getElementById('DAQmasterCard').appendChild(this.collectorBlock);

                ////////////////////////////
                //Kinetic.js setup
                ////////////////////////////

                //indices for these arrays correspond to the x-card index on display
                this.stage = [];
                this.mainLayer = [];
                this.scaleLayer = [];
                this.tooltipLayer = [];
                this.TTbkg = [];
                this.text = [];
            },
            inserted: function() {},
            removed: function() {},
            attributeChanged: function() {}
        },
        events: {

        },
        accessors: {
            'MIDAS':{
                attribute: {} //this just needs to be declared
            }
        },
        methods: {
            'buildDAQ' : function(response){
                var data = JSON.parse(response),
                    i, j, k, option,
                    collectorGutter = this.width*0.02,
                    collectorWidth = (this.width - collectorGutter*16) / 16,
                    xLength = collectorGutter/2,
                    xLeft, xRight;

                this.collectors = [];
                this.digitizers = [];
                this.collectorCells = [];

                //determine what collectors are present and instantiate x-cards for each one
                for(i=0; i<16; i++){
                    this.collectors[i] = data.hosts['collector0x' + i.toString(16)];

                    if(this.collectors[i]){
                        document.getElementById('DAQdeck').innerHTML += '<x-card id="collector'+i+'">

</x-card>';
                        option = document.createElement('option');
                        option.value = this.nCards;
                        option.innerHTML = 'Collector 0x' + i.toString(16).toUpperCase();
                        this.cardNav.appendChild(option);
                        this.nCards++;

                    }
                }

                //now that the xdeck is built, paint master canvas:
                //collectors:
                this.setupKinetic('collectorBlock');
                for(i=0; i<16; i++){
                    if(this.collectors[i]){
                        this.collectorCells[i] = new Kinetic.Rect({
                            x:collectorGutter/2 + i*this.width/16,
                            y:this.height*0.6,
                            width: collectorWidth,
                            height:this.height*0.2,
                            fill:'#555555',
                            stroke: '#000000',
                            strokeWidth: 4
                        });
                        this.collectorCells[i].on('click', this.clickCollector.bind(this, i));
                        this.collectorCells[i].on('mousemove', this.moveTooltip.bind(this) );
                        this.mainLayer[0].add(this.collectorCells[i]);
                    } else{
                        //terminate loose cord with red x
                        xLeft = new Kinetic.Line({
                            points: [(collectorGutter + collectorWidth)/2 + i*(collectorGutter+collectorWidth) - xLength, 0.6*this.height - xLength, (collectorGutter + collectorWidth)/2 + i*(collectorGutter+collectorWidth) + xLength, 0.6*this.height + xLength],
                            stroke: '#FF0000',
                            strokeWidth: 8
                        });
                        xRight = new Kinetic.Line({
                            points: [(collectorGutter + collectorWidth)/2 + i*(collectorGutter+collectorWidth) + xLength, 0.6*this.height - xLength, (collectorGutter + collectorWidth)/2 + i*(collectorGutter+collectorWidth) - xLength, 0.6*this.height + xLength],
                            stroke: '#FF0000',
                            strokeWidth: 8
                        });
                        this.mainLayer[0].add(xLeft);
                        this.mainLayer[0].add(xRight);
                    }
                }

                //cabling:
                this.masterCables = [[],[],[],[]]; //1-to-4 cables: outer index counts master port, inner index counts collector
                for(i=0; i<4; i++){
                    this.masterCables[i][0] = new Kinetic.Line({
                        points: [collectorWidth*2 + collectorGutter*1.75 + i*(collectorWidth + collectorGutter)*4,0, collectorWidth*2 + collectorGutter*1.75 + i*(collectorWidth + collectorGutter)*4, 0.3*this.height],
                        stroke: '#000000',
                        strokeWidth: 4
                    });
                    this.mainLayer[0].add(this.masterCables[i][0]);
                    this.masterCables[i][0].moveToBottom();
                    for(j=1; j<5; j++){
                        this.masterCables[i][j] = new Kinetic.Line({
                            points: [collectorWidth*2 + collectorGutter*1.75 + i*(collectorWidth + collectorGutter)*4, 0.3*this.height, (collectorGutter + collectorWidth)/2 + (4*i+j-1)*(collectorGutter+collectorWidth), 0.6*this.height],
                            stroke: '#000000',
                            strokeWidth: 4
                        });
                        this.mainLayer[0].add(this.masterCables[i][j]);
                        this.masterCables[i][j].moveToBottom();
                    }
                }
                this.mainLayer[0].draw();

                //and again for each collector card
                this.digitizerCells = [];
                this.collectorCables = [];
                for(i=0; i<16; i++){
                    this.digitizerCells[i] = [];

                    if(!this.collectors[i]) continue;

                    this.setupKinetic('digitizerBlock'+i);
                    for(j=0; j<16; j++){
                        if(data.hosts['collector0x' + i.toString(16)].digitizers[j]){
                            this.digitizerCells[i][j] = new Kinetic.Rect({
                                x:collectorGutter/2 + j*this.width/16,
                                y:this.height*0.6,
                                width: collectorWidth,
                                height:this.height*0.2,
                                fill:'#555555',
                                stroke: '#000000',
                                strokeWidth: 4
                            });
                            this.mainLayer[i+1].add(this.digitizerCells[i][j]);
                        } else{
                            //terminate loose cord with red x
                            xLeft = new Kinetic.Line({
                                points: [(collectorGutter + collectorWidth)/2 + j*(collectorGutter+collectorWidth) - xLength, 0.6*this.height - xLength, (collectorGutter + collectorWidth)/2 + j*(collectorGutter+collectorWidth) + xLength, 0.6*this.height + xLength],
                                stroke: '#FF0000',
                                strokeWidth: 8
                            });
                            xRight = new Kinetic.Line({
                                points: [(collectorGutter + collectorWidth)/2 + j*(collectorGutter+collectorWidth) + xLength, 0.6*this.height - xLength, (collectorGutter + collectorWidth)/2 + j*(collectorGutter+collectorWidth) - xLength, 0.6*this.height + xLength],
                                stroke: '#FF0000',
                                strokeWidth: 8
                            });
                            this.mainLayer[i+1].add(xLeft);
                            this.mainLayer[i+1].add(xRight);
                        }

                    }

                    //cabling:
                    this.collectorCables[i] = [];
                    for(j=0; j<4; j++){
                        this.collectorCables[i][j] = [];
                        this.collectorCables[i][j][0] = new Kinetic.Line({
                            points: [collectorWidth*2 + collectorGutter*1.75 + j*(collectorWidth + collectorGutter)*4,0, collectorWidth*2 + collectorGutter*1.75 + j*(collectorWidth + collectorGutter)*4, 0.3*this.height],
                            stroke: '#000000',
                            strokeWidth: 4
                        });
                        this.mainLayer[i+1].add(this.collectorCables[i][j][0]);
                        this.collectorCables[i][j][0].moveToBottom();
                        for(k=1; k<5; k++){
                            this.collectorCables[i][j][k] = new Kinetic.Line({
                                points: [collectorWidth*2 + collectorGutter*1.75 + j*(collectorWidth + collectorGutter)*4, 0.3*this.height, (collectorGutter + collectorWidth)/2 + (4*j+k-1)*(collectorGutter+collectorWidth), 0.6*this.height],
                                stroke: '#000000',
                                strokeWidth: 4
                            });
                            this.mainLayer[i+1].add(this.collectorCables[i][j][k]);
                            this.collectorCables[i][j][k].moveToBottom();
                        }
                    }
                    this.mainLayer[i+1].draw();
                }

            },

            'setupKinetic' : function(targetID){
                var i = this.stage.length;
                //point kinetic at the div and set up the staging and layers:
                this.stage[i] = new Kinetic.Stage({
                    container: targetID,
                    width: this.width,
                    height: this.height
                });
                this.mainLayer[i] = new Kinetic.Layer();       //main rendering layer
                this.scaleLayer[i] = new Kinetic.Layer();      //layer for scales / legends
                this.tooltipLayer[i] = new Kinetic.Layer();    //layer for tooltip info

                //tooltip background:
                this.TTbkg[i] = new Kinetic.Rect({
                    x:-1000,
                    y:-1000,
                    width:100,
                    height:100,
                    fill:'rgba(0,0,0,0.8)',
                    stroke: 'rgba(0,0,0,0)',
                    listening: false
                });
                this.tooltipLayer[i].add(this.TTbkg[i]);

                //tooltip text:
                this.text[i] = new Kinetic.Text({
                    x: -1000,
                    y: -1000,
                    fontFamily: 'Arial',
                    fontSize: 16,
                    text: '',
                    lineHeight: 1.2,
                    fill: '#EEEEEE',
                    listening: false
                });
                this.tooltipLayer[i].add(this.text[i]);

                this.stage[i].add(this.mainLayer[i]);
                this.stage[i].add(this.scaleLayer[i]);
                this.stage[i].add(this.tooltipLayer[i]);
            },

            'clickCollector' : function(index){
                //document.getElementById('DAQdeck').shuffleTo(index+1);
                document.getElementById('DAQnav').value = index+1;
                document.getElementById('DAQnav').onchange();
            },

            'moveTooltip': function(){
                var mousePos = this.stage[this.showing].getPointerPosition(),
                    TTwidth = this.TTbkg[this.showing].getAttr('width'),
                    TTheight = this.TTbkg[this.showing].getAttr('height');

                //adjust the background size & position
                this.TTbkg[this.showing].setAttr( 'x', Math.min(mousePos.x + 10, this.width - TTwidth) );
                this.TTbkg[this.showing].setAttr( 'y', Math.min(mousePos.y + 10, this.height - TTheight) );
                //make text follow the mouse too
                this.text[this.showing].setAttr( 'x', Math.min(mousePos.x + 20, this.width - TTwidth + 10) );
                this.text[this.showing].setAttr( 'y', Math.min(mousePos.y + 20, this.height - TTheight) );

                this.tooltipLayer[this.showing].draw();
            }
        }
    });

})();<commit_msg>setting up tooltip for DAQ<commit_after>(function(){

    xtag.register('widget-DAQ', {
        extends: 'div',
        lifecycle: {
            created: function() {
                var xString, option, title, deckWrap;

                this.width = this.offsetWidth;
                this.height = window.innerHeight*0.6;
                this.showing = 0;

                //get the DAQ structure
                XHR('http://' + this.MIDAS + '/?cmd=jcopy&odb=/DAQ&encoding=json-nokeys',
                    function(res){
                        this.buildDAQ(res);
                    }.bind(this),
                    'application/json');

                //build DOM
                this.navBlock = document.createElement('div');
                this.navBlock.setAttribute('class', 'DAQnav');
                this.appendChild(this.navBlock);

                title = document.createElement('h1');
                title.innerHTML = 'DAQ';
                this.navBlock.appendChild(title);

                this.cardNav = document.createElement('select');
                this.cardNav.setAttribute('id', 'DAQnav')
                this.cardNav.setAttribute('class', 'stdin');
                this.cardNav.onchange = function(){
                    var targetIndex = selected('DAQnav')
                    document.getElementById('DAQdeck').shuffleTo(targetIndex);
                    this.showing = targetIndex - 1;
                }.bind(this)
                this.navBlock.appendChild(this.cardNav);

                option = document.createElement('option');
                option.value = 0;
                option.innerHTML = 'Master'
                this.cardNav.appendChild(option);

                deckWrap = document.createElement('div');
                this.appendChild(deckWrap);

                xString = '<x-deck id="DAQdeck" selected-index=0>';
                xString += '<x-card id="DAQmasterCard"></x-card></x-deck>';
                xtag.innerHTML(deckWrap, xString);
                this.nCards = 1

                this.masterBlock = document.createElement('div');
                this.masterBlock.setAttribute('class', 'DAQheadNode');
                document.getElementById('DAQmasterCard').appendChild(this.masterBlock);

                this.collectorBlock = document.createElement('div');
                this.collectorBlock.setAttribute('id', 'collectorBlock');
                document.getElementById('DAQmasterCard').appendChild(this.collectorBlock);

                ////////////////////////////
                //Kinetic.js setup
                ////////////////////////////

                //indices for these arrays correspond to the x-card index on display
                this.stage = [];
                this.mainLayer = [];
                this.scaleLayer = [];
                this.tooltipLayer = [];
                this.TTbkg = [];
                this.text = [];
            },
            inserted: function() {},
            removed: function() {},
            attributeChanged: function() {}
        },
        events: {

        },
        accessors: {
            'MIDAS':{
                attribute: {} //this just needs to be declared
            }
        },
        methods: {
            'buildDAQ' : function(response){
                var data = JSON.parse(response),
                    i, j, k, option,
                    collectorGutter = this.width*0.02,
                    collectorWidth = (this.width - collectorGutter*16) / 16,
                    xLength = collectorGutter/2,
                    xLeft, xRight;

                this.collectors = [];
                this.digitizers = [];
                this.collectorCells = [];

                //determine what collectors are present and instantiate x-cards for each one
                for(i=0; i<16; i++){
                    this.collectors[i] = data.hosts['collector0x' + i.toString(16)];

                    if(this.collectors[i]){
                        document.getElementById('DAQdeck').innerHTML += '<x-card id="collector'+i+'">

</x-card>';
                        option = document.createElement('option');
                        option.value = this.nCards;
                        option.innerHTML = 'Collector 0x' + i.toString(16).toUpperCase();
                        this.cardNav.appendChild(option);
                        this.nCards++;

                    }
                }

                //now that the xdeck is built, paint master canvas:
                //collectors:
                this.setupKinetic('collectorBlock');
                for(i=0; i<16; i++){
                    if(this.collectors[i]){
                        this.collectorCells[i] = new Kinetic.Rect({
                            x:collectorGutter/2 + i*this.width/16,
                            y:this.height*0.6,
                            width: collectorWidth,
                            height:this.height*0.2,
                            fill:'#555555',
                            stroke: '#000000',
                            strokeWidth: 4
                        });
                        this.collectorCells[i].on('click', this.clickCollector.bind(this, i));
                        this.collectorCells[i].on('mousemove', this.moveTooltip.bind(this) );
                        this.collectorCells[i].on('mouseover', this.writeCollectorTooltip.bind(this, i) );
                        this.collectorCells[i].on('mouseout', this.writeCollectorTooltip.bind(this, -1));
                        this.mainLayer[0].add(this.collectorCells[i]);
                    } else{
                        //terminate loose cord with red x
                        xLeft = new Kinetic.Line({
                            points: [(collectorGutter + collectorWidth)/2 + i*(collectorGutter+collectorWidth) - xLength, 0.6*this.height - xLength, (collectorGutter + collectorWidth)/2 + i*(collectorGutter+collectorWidth) + xLength, 0.6*this.height + xLength],
                            stroke: '#FF0000',
                            strokeWidth: 8
                        });
                        xRight = new Kinetic.Line({
                            points: [(collectorGutter + collectorWidth)/2 + i*(collectorGutter+collectorWidth) + xLength, 0.6*this.height - xLength, (collectorGutter + collectorWidth)/2 + i*(collectorGutter+collectorWidth) - xLength, 0.6*this.height + xLength],
                            stroke: '#FF0000',
                            strokeWidth: 8
                        });
                        this.mainLayer[0].add(xLeft);
                        this.mainLayer[0].add(xRight);
                    }
                }

                //cabling:
                this.masterCables = [[],[],[],[]]; //1-to-4 cables: outer index counts master port, inner index counts collector
                for(i=0; i<4; i++){
                    this.masterCables[i][0] = new Kinetic.Line({
                        points: [collectorWidth*2 + collectorGutter*1.75 + i*(collectorWidth + collectorGutter)*4,0, collectorWidth*2 + collectorGutter*1.75 + i*(collectorWidth + collectorGutter)*4, 0.3*this.height],
                        stroke: '#000000',
                        strokeWidth: 4
                    });
                    this.mainLayer[0].add(this.masterCables[i][0]);
                    this.masterCables[i][0].moveToBottom();
                    for(j=1; j<5; j++){
                        this.masterCables[i][j] = new Kinetic.Line({
                            points: [collectorWidth*2 + collectorGutter*1.75 + i*(collectorWidth + collectorGutter)*4, 0.3*this.height, (collectorGutter + collectorWidth)/2 + (4*i+j-1)*(collectorGutter+collectorWidth), 0.6*this.height],
                            stroke: '#000000',
                            strokeWidth: 4
                        });
                        this.mainLayer[0].add(this.masterCables[i][j]);
                        this.masterCables[i][j].moveToBottom();
                    }
                }
                this.mainLayer[0].draw();

                //and again for each collector card
                this.digitizerCells = [];
                this.collectorCables = [];
                for(i=0; i<16; i++){
                    this.digitizerCells[i] = [];

                    if(!this.collectors[i]) continue;

                    this.setupKinetic('digitizerBlock'+i);
                    for(j=0; j<16; j++){
                        if(data.hosts['collector0x' + i.toString(16)].digitizers[j]){
                            this.digitizerCells[i][j] = new Kinetic.Rect({
                                x:collectorGutter/2 + j*this.width/16,
                                y:this.height*0.6,
                                width: collectorWidth,
                                height:this.height*0.2,
                                fill:'#555555',
                                stroke: '#000000',
                                strokeWidth: 4
                            });
                            this.mainLayer[i+1].add(this.digitizerCells[i][j]);
                        } else{
                            //terminate loose cord with red x
                            xLeft = new Kinetic.Line({
                                points: [(collectorGutter + collectorWidth)/2 + j*(collectorGutter+collectorWidth) - xLength, 0.6*this.height - xLength, (collectorGutter + collectorWidth)/2 + j*(collectorGutter+collectorWidth) + xLength, 0.6*this.height + xLength],
                                stroke: '#FF0000',
                                strokeWidth: 8
                            });
                            xRight = new Kinetic.Line({
                                points: [(collectorGutter + collectorWidth)/2 + j*(collectorGutter+collectorWidth) + xLength, 0.6*this.height - xLength, (collectorGutter + collectorWidth)/2 + j*(collectorGutter+collectorWidth) - xLength, 0.6*this.height + xLength],
                                stroke: '#FF0000',
                                strokeWidth: 8
                            });
                            this.mainLayer[i+1].add(xLeft);
                            this.mainLayer[i+1].add(xRight);
                        }

                    }

                    //cabling:
                    this.collectorCables[i] = [];
                    for(j=0; j<4; j++){
                        this.collectorCables[i][j] = [];
                        this.collectorCables[i][j][0] = new Kinetic.Line({
                            points: [collectorWidth*2 + collectorGutter*1.75 + j*(collectorWidth + collectorGutter)*4,0, collectorWidth*2 + collectorGutter*1.75 + j*(collectorWidth + collectorGutter)*4, 0.3*this.height],
                            stroke: '#000000',
                            strokeWidth: 4
                        });
                        this.mainLayer[i+1].add(this.collectorCables[i][j][0]);
                        this.collectorCables[i][j][0].moveToBottom();
                        for(k=1; k<5; k++){
                            this.collectorCables[i][j][k] = new Kinetic.Line({
                                points: [collectorWidth*2 + collectorGutter*1.75 + j*(collectorWidth + collectorGutter)*4, 0.3*this.height, (collectorGutter + collectorWidth)/2 + (4*j+k-1)*(collectorGutter+collectorWidth), 0.6*this.height],
                                stroke: '#000000',
                                strokeWidth: 4
                            });
                            this.mainLayer[i+1].add(this.collectorCables[i][j][k]);
                            this.collectorCables[i][j][k].moveToBottom();
                        }
                    }
                    this.mainLayer[i+1].draw();
                }

            },

            'setupKinetic' : function(targetID){
                var i = this.stage.length;
                //point kinetic at the div and set up the staging and layers:
                this.stage[i] = new Kinetic.Stage({
                    container: targetID,
                    width: this.width,
                    height: this.height
                });
                this.mainLayer[i] = new Kinetic.Layer();       //main rendering layer
                this.scaleLayer[i] = new Kinetic.Layer();      //layer for scales / legends
                this.tooltipLayer[i] = new Kinetic.Layer();    //layer for tooltip info

                //tooltip background:
                this.TTbkg[i] = new Kinetic.Rect({
                    x:-1000,
                    y:-1000,
                    width:100,
                    height:100,
                    fill:'rgba(0,0,0,0.8)',
                    stroke: 'rgba(0,0,0,0)',
                    listening: false
                });
                this.tooltipLayer[i].add(this.TTbkg[i]);

                //tooltip text:
                this.text[i] = new Kinetic.Text({
                    x: -1000,
                    y: -1000,
                    fontFamily: 'Arial',
                    fontSize: 16,
                    text: '',
                    lineHeight: 1.2,
                    fill: '#EEEEEE',
                    listening: false
                });
                this.tooltipLayer[i].add(this.text[i]);

                this.stage[i].add(this.mainLayer[i]);
                this.stage[i].add(this.scaleLayer[i]);
                this.stage[i].add(this.tooltipLayer[i]);
            },

            'clickCollector' : function(index){
                //document.getElementById('DAQdeck').shuffleTo(index+1);
                document.getElementById('DAQnav').value = index+1;
                document.getElementById('DAQnav').onchange();
            },

            'moveTooltip': function(){
                var mousePos = this.stage[this.showing].getPointerPosition(),
                    TTwidth = this.TTbkg[this.showing].getAttr('width'),
                    TTheight = this.TTbkg[this.showing].getAttr('height');

                //adjust the background size & position
                this.TTbkg[this.showing].setAttr( 'x', Math.min(mousePos.x + 10, this.width - TTwidth) );
                this.TTbkg[this.showing].setAttr( 'y', Math.min(mousePos.y + 10, this.height - TTheight) );
                //make text follow the mouse too
                this.text[this.showing].setAttr( 'x', Math.min(mousePos.x + 20, this.width - TTwidth + 10) );
                this.text[this.showing].setAttr( 'y', Math.min(mousePos.y + 20, this.height - TTheight) );

                this.tooltipLayer[this.showing].draw();
            },

            'writeCollectorTooltip' : function(i){
                var text, value, j;

                if(i!=-1){
                    text = 'Collector 0x' + i.toString(16);
                } else {
                    text = '';
                }
                this.lastTTindex = i;
                this.text[this.showing].setText(text);
                if(text != ''){
                    //adjust the background size
                    this.TTbkg[this.showing].setAttr( 'width', this.text[this.showing].getAttr('width') + 20 );
                    this.TTbkg[this.showing].setAttr( 'height', this.text[this.showing].getAttr('height') + 20 );
                } else {
                    this.TTbkg[this.showing].setAttr('width', 0);
                    this.TTbkg[this.showing].setAttr('height', 0);
                }
                this.tooltipLayer[this.showing].draw();
            }
        }
    });

})();<|endoftext|>