<commit_before>/*
Gordon Williams (gw@pur3.co.uk)

If we're running in an iframe, this gets enabled and allows the IDE
to work by passing messages using window.postMessage.

Use embed.js on the client side to link this in.
*/

var DEVICE = 21; // USB
var BTN1 = 24;
var BTN2 = 22;
var BTN3 = 23;
var BTN4 = 11;
var BTN5 = 16;
var jsRXCallback;
var jsIdleTimeout;
// used to interface to Espruino emscripten...
var hwPinValue = new Uint8Array(32);
var flashMemory = new Uint8Array(4096*1024);
flashMemory.fill(255);
function hwSetPinValue(pin,v) { hwPinValue[pin] = v; }
function hwGetPinValue(pin) { return hwPinValue[pin]; }
function hwFlashWrite(addr,v) { flashMemory[addr] = v; }
function hwFlashRead(addr) { return flashMemory[addr]; }

function jsHandleIO() {
  var device;
  var l = "";
  do {
    device = Module.ccall('jshGetDeviceToTransmit', 'number', [], []);
    if (device) {
      var ch = Module.ccall('jshGetCharToTransmit', 'number', ['number'], [device]);
      if (jsRXCallback) jsRXCallback(ch);
      l += String.fromCharCode(ch);
      var ll = l.split("\n");
      if (ll.length>1) {
        console.log("EMSCRIPTEN:",ll[0]);
        l = ll[1];
      }
    }
  } while (device);
}
function jsTransmitChar(c) {
  //console.log("TX -> ",c);
  Module.ccall('jshPushIOCharEvent', 'number', ['number','number'], [DEVICE,c]);
  jsIdle();
}
function jsTransmitPinEvent(pin) {
  //console.log("TX -> ",c);
  Module.ccall('jsSendPinWatchEvent', 'number', ['number'], [pin]);
  jsIdle();
}
function jsIdle() {
  if (jsIdleTimeout) {
    clearTimeout(jsIdleTimeout);
    jsIdleTimeout = undefined;
  }
  var tries = 5;
  var msToNext = -1;
  while (tries-- && msToNext<0) {
    msToNext = Module.ccall('jsIdle', 'number', [], []);
    jsHandleIO();
  }
  if (msToNext<10) msToNext=10;
  jsIdleTimeout = setTimeout(jsIdle,msToNext);
  jsUpdateGfx();
}
function jsUpdateGfx() {
  var changed = Module.ccall('jsGfxChanged', 'number', [], []);
  if (changed) {
    var canvas = document.getElementById('gfxcanvas');
    var ctx = canvas.getContext('2d');
    var imgData = ctx.createImageData(240, 240);
    var rgba = imgData.data;
    var i = 0;
    for (var y=0;y<240;y++) {
      var p = Module.ccall('jsGfxGetPtr', 'number', ['number'], [y])>>1;
      for (var x=0;x<240;x++) {
        var c = p ? Module.HEAP16[p+x] : 0;
        rgba[i++]=(c>>8)&0xF8;
        rgba[i++]=(c>>3)&0xFC;
        rgba[i++]=(c<<3)&0xF8;
        rgba[i++]=255;
      }
    }
    ctx.putImageData(imgData, 0, 0);

  }
  jsHandleIO();
}
function jsInit() {
  var div = document.createElement("div");
  div.id = "gfxdiv";
  div.style = "position:absolute;top:0px;right:0px;z-index:100;border: 2px solid white;width:264px;height:244px;";
  div.style = "position:absolute;top:0px;right:0px;z-index:100;border: 2px solid white;width:264px;height:244px;";
  div.innerHTML = `<canvas id="gfxcanvas" width="240" height="240"></canvas>
<button id="BTN1" style="width:20px;height:73px;position:absolute;right:0px;top:0px;">1</button>
<button id="BTN2" style="width:20px;height:73px;position:absolute;right:0px;top:73px;">2</button>
<button id="BTN3" style="width:20px;height:73px;position:absolute;right:0px;top:146px;">3</button>
📷

`;
  var terminal = document.getElementsByClassName("editor__canvas__terminal")[0];
  terminal.appendChild(div);
  function handleButton(n, pin) {
    hwPinValue[pin]=1; // inverted
    var btn = document.getElementById("BTN"+n);
    btn.addEventListener('mousedown', e => {
      e.preventDefault();
      hwPinValue[pin]=0; // inverted
      jsTransmitPinEvent(pin);
    });
    btn.addEventListener('mouseup', e => {
      hwPinValue[pin]=1; // inverted
      jsTransmitPinEvent(pin);
    });
    btn.addEventListener('mouseenter', e => {
      if (e.buttons) {
        hwPinValue[pin]=0; // inverted
        jsTransmitPinEvent(pin);
      }
    });
    btn.addEventListener('mouseleave', e => {
      // mouseleave comes *before* mouseenter usually - so delay it
      // in order to get overlap when swiping to make Bangle.js screen swipes work
      setTimeout(function() {
        if (!hwPinValue[pin]) {
          hwPinValue[pin]=1; // inverted
          jsTransmitPinEvent(pin);
        }
      },10);
    });
  }
  handleButton(1,BTN1);
  handleButton(2,BTN2);
  handleButton(3,BTN3);
  handleButton(4,BTN4);
  handleButton(5,BTN5);
  document.getElementById("screenshot").addEventListener('click', e => {
    document.getElementById("screenshot").href = document.getElementById("gfxcanvas").toDataURL();
    document.getElementById("screenshot").download = "screenshot.png";
  });

  Module.ccall('jsInit', 'number', [], []);
  jsHandleIO();
}
function jsKill() {
  var d = document.getElementById("gfxdiv");
  if (d) d.remove();
  Module.ccall('jsKill', 'number', [], []);
}

(function() {
  var callbacks = {};
  var device = {
    "name" : "Emulator",
    "init" : function() {
    },
    "getPorts": function(callback) {
      callback([{path:'Emulator',description:'Emulator', type:"emulator", autoconnect : true}], true/*instantPorts*/);
    },
    "open": function(path, openCallback, receiveCallback, disconnectCallback) {
      jsRXCallback = function(c) {
        var a = new Uint8Array([c]);
        receiveCallback(a.buffer);
      }
      callbacks.disconnected = disconnectCallback;
      setTimeout(function() {
        jsInit();
        jsIdle();
        openCallback("Hello");
      },500);
    },
    "write": function(d, callback) {
      for (var i=0;i<d.length;i++) {
        jsTransmitChar(d.charCodeAt(i));
      }
      setTimeout(callback,10);
    },
    "close": function() {
      jsKill();
      callbacks.disconnected();
    },
  };
  Espruino.Core.Serial.devices.push(device);
})();
<commit_msg>minor emulator tweak<commit_after>/*
Gordon Williams (gw@pur3.co.uk)

If we're running in an iframe, this gets enabled and allows the IDE
to work by passing messages using window.postMessage.

Use embed.js on the client side to link this in.
*/

var DEVICE = 21; // USB
var BTN1 = 24;
var BTN2 = 22;
var BTN3 = 23;
var BTN4 = 11;
var BTN5 = 16;
var jsRXCallback;
var jsIdleTimeout;
// used to interface to Espruino emscripten...
var hwPinValue = new Uint8Array(32);
var flashMemory = new Uint8Array(4096*1024);
flashMemory.fill(255);
function hwSetPinValue(pin,v) { hwPinValue[pin] = v; }
function hwGetPinValue(pin) { return hwPinValue[pin]; }
function hwFlashWrite(addr,v) { flashMemory[addr] = v; }
function hwFlashRead(addr) { return flashMemory[addr]; }

function jsHandleIO() {
  var device;
  var l = "";
  do {
    device = Module.ccall('jshGetDeviceToTransmit', 'number', [], []);
    if (device) {
      var ch = Module.ccall('jshGetCharToTransmit', 'number', ['number'], [device]);
      if (jsRXCallback) jsRXCallback(ch);
      l += String.fromCharCode(ch);
      var ll = l.split("\n");
      if (ll.length>1) {
        console.log("EMSCRIPTEN:",ll[0]);
        l = ll[1];
      }
    }
  } while (device);
}
function jsTransmitChar(c) {
  //console.log("TX -> ",c);
  Module.ccall('jshPushIOCharEvent', 'number', ['number','number'], [DEVICE,c]);
  jsIdle();
}
function jsTransmitPinEvent(pin) {
  //console.log("TX -> ",c);
  Module.ccall('jsSendPinWatchEvent', 'number', ['number'], [pin]);
  jsIdle();
}
function jsIdle() {
  if (jsIdleTimeout) {
    clearTimeout(jsIdleTimeout);
    jsIdleTimeout = undefined;
  }
  var tries = 5;
  var msToNext = -1;
  while (tries-- && msToNext<0) {
    msToNext = Module.ccall('jsIdle', 'number', [], []);
    jsHandleIO();
  }
  if (msToNext<10) msToNext=10;
  jsIdleTimeout = setTimeout(jsIdle,msToNext);
  jsUpdateGfx();
}
function jsUpdateGfx() {
  var changed = Module.ccall('jsGfxChanged', 'number', [], []);
  if (changed) {
    var canvas = document.getElementById('gfxcanvas');
    var ctx = canvas.getContext('2d');
    var imgData = ctx.createImageData(240, 240);
    var rgba = imgData.data;
    var i = 0;
    for (var y=0;y<240;y++) {
      var p = Module.ccall('jsGfxGetPtr', 'number', ['number'], [y])>>1;
      for (var x=0;x<240;x++) {
        var c = p ? Module.HEAP16[p+x] : 0;
        rgba[i++]=(c>>8)&0xF8;
        rgba[i++]=(c>>3)&0xFC;
        rgba[i++]=(c<<3)&0xF8;
        rgba[i++]=255;
      }
    }
    ctx.putImageData(imgData, 0, 0);

  }
  jsHandleIO();
}
function jsInit() {
  var div = document.createElement("div");
  div.id = "gfxdiv";
  div.style = "position:absolute;top:0px;right:0px;z-index:100;border: 2px solid white;width:264px;height:244px;";
  div.innerHTML = `<canvas id="gfxcanvas" width="240" height="240"></canvas>
<button id="BTN1" style="width:20px;height:73px;position:absolute;right:0px;top:0px;">1</button>
<button id="BTN2" style="width:20px;height:73px;position:absolute;right:0px;top:73px;">2</button>
<button id="BTN3" style="width:20px;height:73px;position:absolute;right:0px;top:146px;">3</button>
📷

`;
  var terminal = document.getElementsByClassName("editor__canvas__terminal")[0];
  terminal.appendChild(div);
  function handleButton(n, pin) {
    hwPinValue[pin]=1; // inverted
    var btn = document.getElementById("BTN"+n);
    btn.addEventListener('mousedown', e => {
      e.preventDefault();
      hwPinValue[pin]=0; // inverted
      jsTransmitPinEvent(pin);
    });
    btn.addEventListener('mouseup', e => {
      hwPinValue[pin]=1; // inverted
      jsTransmitPinEvent(pin);
    });
    btn.addEventListener('mouseenter', e => {
      if (e.buttons) {
        hwPinValue[pin]=0; // inverted
        jsTransmitPinEvent(pin);
      }
    });
    btn.addEventListener('mouseleave', e => {
      // mouseleave comes *before* mouseenter usually - so delay it
      // in order to get overlap when swiping to make Bangle.js screen swipes work
      setTimeout(function() {
        if (!hwPinValue[pin]) {
          hwPinValue[pin]=1; // inverted
          jsTransmitPinEvent(pin);
        }
      },10);
    });
  }
  handleButton(1,BTN1);
  handleButton(2,BTN2);
  handleButton(3,BTN3);
  handleButton(4,BTN4);
  handleButton(5,BTN5);
  document.getElementById("screenshot").addEventListener('click', e => {
    document.getElementById("screenshot").href = document.getElementById("gfxcanvas").toDataURL();
    document.getElementById("screenshot").download = "screenshot.png";
  });

  Module.ccall('jsInit', 'number', [], []);
  jsHandleIO();
}
function jsKill() {
  var d = document.getElementById("gfxdiv");
  if (d) d.remove();
  Module.ccall('jsKill', 'number', [], []);
}

(function() {
  var callbacks = {};
  var device = {
    "name" : "Emulator",
    "init" : function() {
    },
    "getPorts": function(callback) {
      callback([{path:'Emulator',description:'Emulator', type:"emulator", autoconnect : true}], true/*instantPorts*/);
    },
    "open": function(path, openCallback, receiveCallback, disconnectCallback) {
      jsRXCallback = function(c) {
        var a = new Uint8Array([c]);
        receiveCallback(a.buffer);
      }
      callbacks.disconnected = disconnectCallback;
      setTimeout(function() {
        jsInit();
        jsIdle();
        openCallback("Hello");
      },500);
    },
    "write": function(d, callback) {
      for (var i=0;i<d.length;i++) {
        jsTransmitChar(d.charCodeAt(i));
      }
      setTimeout(callback,10);
    },
    "close": function() {
      jsKill();
      callbacks.disconnected();
    },
  };
  Espruino.Core.Serial.devices.push(device);
})();
<|endoftext|>


<commit_before>// View model for the courses page
function pageViewModel(gvm) {
    // projecttitle
    gvm.projecttitle = ko.observable("");
    gvm.competences = 0;
    gvm.subcomp = 0;

    // Page specific i18n bindings
    gvm.title = ko.computed(function (){i18n.setLocale(gvm.lang()); return gvm.app() + ' - ' + i18n.__("ProjectTitle") + ": " + gvm.projecttitle();}, gvm);
    gvm.pageHeader = ko.observable("Project");
    gvm.projectname = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("ProjectName");}, gvm);

    gvm.getProjectInfo = function() {
        $.getJSON('/api/project/' + $("#projectHeader").data('value'), function(data) {
            gvm.pageHeader(data[0].code + ' - ' + data[0].name);
        });
    };
}

function addCompetence() {
    var competencePanelWrapper = document.createElement('div');
    var competencePanel = document.createElement('div');
    var competencePanelHeading = document.createElement('div');
    var competencePanelBody = document.createElement('div');
    var competencePanelFooter = document.createElement('div');
    var competenceCode = document.createElement('input');
    var competenceName = document.createElement('input');
    var subcompetenceButton = document.createElement('button');
    var removeCompetenceButton = document.createElement('button');

    competenceCode.type = 'text';
    competenceCode.placeholder = "Competence-Code";
    $(competenceCode).addClass("form-control");

    competenceName.type = 'text';
    competenceName.placeholder = "Name of the competence";
    $(competenceName).addClass("form-control");

    $(subcompetenceButton).addClass("btn");
    $(subcompetenceButton).text("Add a subcompetence");
    $(subcompetenceButton).val(viewModel.competences);
    $(subcompetenceButton).on('click', function() {
        addSubCompetence($(subcompetenceButton).val());
    });

    $(removeCompetenceButton).addClass("btn pull-right");
    $(removeCompetenceButton).text("Remove this competence");
    $(removeCompetenceButton).val(viewModel.competences);
    $(removeCompetenceButton).on('click', function() {
        $(this).parent().parent().remove();
    });

    $(competencePanelWrapper).addClass("col-md-9 compPanel panel-" + $(subcompetenceButton).val());
    $(competencePanel).addClass("panel panel-default");
    $(competencePanelHeading).addClass("panel-heading comp-" + $(subcompetenceButton).val());
    $(competencePanelBody).addClass("panel-body comp-"  + $(subcompetenceButton).val());
    $(competencePanelFooter).addClass("panel-footer");

    if(!$(".compPanel")[0]) {
        $("#top-col").after(competencePanelWrapper);
    } else {
        $(".compPanel:last").after(competencePanelWrapper);
    }
    ++viewModel.competences;
    $(competencePanelWrapper).append(competencePanel);
    $(competencePanel).append(competencePanelHeading);
    $(competencePanelHeading).append(competenceCode);
    $(competenceCode).after(competenceName);
    $(competencePanelHeading).after(competencePanelBody);
    $(competencePanelBody).after(competencePanelFooter);
    $(competencePanelFooter).append(subcompetenceButton);
    $(subcompetenceButton).after(removeCompetenceButton);
}

function addSubCompetence(competence) {
    var subcompPanelWrapper = document.createElement('div');
    var subcompPanel = document.createElement('div');
    var subcompPanelHeading = document.createElement('div');
    var subcompPanelBody = document.createElement('div');
    var subcompPanelFooter = document.createElement('div');
    var subcompCode = document.createElement('input');
    var subcompName = document.createElement('input');
    var indicatorButton = document.createElement('button');
    var removeSubcompButton = document.createElement('button');

    subcompCode.type = 'text';
    subcompCode.placeholder = "Competence-Code";
    $(subcompCode).addClass("form-control");

    subcompName.type = 'text';
    subcompName.placeholder = "Name of the competence";
    $(subcompName).addClass("form-control");

    $(indicatorButton).addClass("btn");
    $(indicatorButton).text("Add an indicator");
    $(indicatorButton).val(competence + "-" + viewModel.subcomp);
    $(indicatorButton).on('click', function() {
        addIndicator($(indicatorButton).val());
    });

    $(removeSubcompButton).addClass("btn pull-right");
    $(removeSubcompButton).text("Remove this subcompetence");
    $(removeSubcompButton).val();
    $(removeSubcompButton).on('click', function() {
        $(this).parent().parent().remove();
    });

    $(subcompPanelWrapper).addClass("subcompPanel panel-" + competence + "-" + viewModel.subcomp);
    $(subcompPanel).addClass("panel panel-default");
    $(subcompPanelHeading).addClass("panel-heading");
    $(subcompPanelBody).addClass("panel-body");
    $(subcompPanelFooter).addClass("panel-footer");

    $(".panel-body.comp-" + competence).append(subcompPanelWrapper);
    $(subcompPanelWrapper).append(subcompPanel);
    $(subcompPanel).append(subcompPanelHeading);
    $(subcompPanelHeading).append(subcompCode);
    $(subcompCode).after(subcompName);
    $(subcompPanelHeading).after(subcompPanelBody);
    $(subcompPanelBody).after(subcompPanelFooter);
    $(subcompPanelFooter).append(indicatorButton);
    $(indicatorButton).after(removeSubcompButton);
    ++viewModel.subcomp;
}

function addIndicator(compandsubcomp) {

}

function initPage() {
    viewModel.getProjectInfo();
    $("#addCompetenceBtn").click(function() {
        addCompetence();
    })
}<commit_msg>projectpage<commit_after>// View model for the courses page
function pageViewModel(gvm) {
    // projecttitle
    gvm.projecttitle = ko.observable("");
    gvm.competences = 0;
    gvm.subcomp = 0;

    // Page specific i18n bindings
    gvm.title = ko.computed(function (){i18n.setLocale(gvm.lang()); return gvm.app() + ' - ' + i18n.__("ProjectTitle") + ": " + gvm.projecttitle();}, gvm);
    gvm.pageHeader = ko.observable("Project");
    gvm.projectname = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("ProjectName");}, gvm);

    gvm.getProjectInfo = function() {
        $.getJSON('/api/project/' + $("#projectHeader").data('value'), function(data) {
            gvm.pageHeader(data[0].code + ' - ' + data[0].name);
        });
    };
}

function addCompetence() {
    var competencePanelWrapper = document.createElement('div');
    var competencePanel = document.createElement('div');
    var competencePanelHeading = document.createElement('div');
    var competencePanelBody = document.createElement('div');
    var competencePanelFooter = document.createElement('div');
    var competenceCode = document.createElement('input');
    var competenceName = document.createElement('input');
    var subcompetenceButton = document.createElement('button');
    var removeCompetenceButton = document.createElement('button');

    competenceCode.type = 'text';
    competenceCode.placeholder = "Competence-Code";
    $(competenceCode).addClass("form-control");

    competenceName.type = 'text';
    competenceName.placeholder = "Name of the competence";
    $(competenceName).addClass("form-control");

    $(subcompetenceButton).addClass("btn");
    $(subcompetenceButton).text("Add a subcompetence");
    $(subcompetenceButton).val(viewModel.competences);
    $(subcompetenceButton).on('click', function() {
        addSubCompetence($(subcompetenceButton).val());
    });

    $(removeCompetenceButton).addClass("btn pull-right");
    $(removeCompetenceButton).text("Remove this competence");
    $(removeCompetenceButton).val(viewModel.competences);
    $(removeCompetenceButton).on('click', function() {
        $(this).parent().parent().remove();
    });

    $(competencePanelWrapper).addClass("col-md-9 compPanel panel-" + $(subcompetenceButton).val());
    $(competencePanel).addClass("panel panel-default");
    $(competencePanelHeading).addClass("panel-heading comp-" + $(subcompetenceButton).val());
    $(competencePanelBody).addClass("panel-body comp-"  + $(subcompetenceButton).val());
    $(competencePanelFooter).addClass("panel-footer");

    if(!$(".compPanel")[0]) {
        $("#top-col").after(competencePanelWrapper);
    } else {
        $(".compPanel:last").after(competencePanelWrapper);
    }
    ++viewModel.competences;
    $(competencePanelWrapper).append(competencePanel);
    $(competencePanel).append(competencePanelHeading);
    $(competencePanelHeading).append(competenceCode);
    $(competenceCode).after(competenceName);
    $(competencePanelHeading).after(competencePanelBody);
    $(competencePanelBody).after(competencePanelFooter);
    $(competencePanelFooter).append(subcompetenceButton);
    $(subcompetenceButton).after(removeCompetenceButton);
}

function addSubCompetence(competence) {
    var subcompPanelWrapper = document.createElement('div');
    var subcompPanel = document.createElement('div');
    var subcompPanelHeading = document.createElement('div');
    var subcompPanelBody = document.createElement('div');
    var subcompPanelFooter = document.createElement('div');
    var subcompCode = document.createElement('input');
    var subcompName = document.createElement('input');
    var indicatorButton = document.createElement('button');
    var removeSubcompButton = document.createElement('button');
    var listgroup = document.createElement('ul');

    listgroup.addClass('list-group');

    subcompCode.type = 'text';
    subcompCode.placeholder = "Competence-Code";
    $(subcompCode).addClass("form-control");

    subcompName.type = 'text';
    subcompName.placeholder = "Name of the competence";
    $(subcompName).addClass("form-control");

    $(indicatorButton).addClass("btn");
    $(indicatorButton).text("Add an indicator");
    $(indicatorButton).val(competence + "-" + viewModel.subcomp);
    $(indicatorButton).on('click', function() {
        addIndicator($(indicatorButton).val());
    });

    $(removeSubcompButton).addClass("btn pull-right");
    $(removeSubcompButton).text("Remove this subcompetence");
    $(removeSubcompButton).val();
    $(removeSubcompButton).on('click', function() {
        $(this).parent().parent().remove();
    });

    $(subcompPanelWrapper).addClass("subcompPanel panel-" + competence + "-" + viewModel.subcomp);
    $(subcompPanel).addClass("panel panel-default");
    $(subcompPanelHeading).addClass("panel-heading");
    $(subcompPanelBody).addClass("panel-body");
    $(subcompPanelFooter).addClass("panel-footer");

    $(".panel-body.comp-" + competence).append(subcompPanelWrapper);
    $(subcompPanelWrapper).append(subcompPanel);
    $(subcompPanel).append(subcompPanelHeading);
    $(subcompPanelHeading).append(subcompCode);
    $(subcompCode).after(subcompName);
    $(subcompPanelHeading).after(subcompPanelBody);
    $(subcompPanelBody).append(listgroup);
    $(subcompPanelBody).after(subcompPanelFooter);
    $(subcompPanelFooter).append(indicatorButton);
    $(indicatorButton).after(removeSubcompButton);
    ++viewModel.subcomp;
}

function addIndicator(compandsubcomp) {

}

function initPage() {
    viewModel.getProjectInfo();
    $("#addCompetenceBtn").click(function() {
        addCompetence();
    })
}<|endoftext|>


<commit_before>/*
 * To relocate elements with existent attribute data-parent-selector as children of this
 * attribute value.
 */
$(document).ready(function(){
    $("[data-parent-selector]").each(function(){
        var parent = this.dataset.parentSelector;
        var element = $(this).detach();
        $(parent).append(element);
    });
});

/*
 * Captura les tecles fletxa-esq i fletxa-dreta per simular un click al botó
 * prevArrow o nextArrow respectivament.
 */
$(document).keydown(function(e){
    switch(e.which){
        case 39:
             $("#nextArrow").click();
             break;
         case 37:
             $("#prevArrow").click();
             break;
    }
    return true;
});

//jQuery to collapse the navbar on scroll
$(window).scroll(function() {
    if ($(".navbar").offset().top > 50) {
        $(".navbar-fixed-top").addClass("top-nav-collapse");
    } else {
        $(".navbar-fixed-top").removeClass("top-nav-collapse");
    }
});

/* ----------------------------------------------------------- */
/*  MOBILE MENU CLOSE
/* ----------------------------------------------------------- */

$('.navbar-nav').on('click', 'li a', function() {
  $('.navbar-collapse').collapse('hide');
});

/* ----------------------------------------------------------- */
/*  Toggle Menu
/* ----------------------------------------------------------- */
// Closes the sidebar menu
$("#menu-close").click(function(e) {
    e.preventDefault();
    $("#sidebar-wrapper").toggleClass("active");
});

// Opens the sidebar menu
$("#menu-toggle").click(function(e) {
    e.preventDefault();
    $("#sidebar-wrapper").toggleClass("active");
});

/*-----------------------------------*/
/*  INFO PANEL
 *-----------------------------------*/
//Set function to close the info-panel on click button panel-close
$(".panel-close").click(function(e) {
    e.preventDefault();
    var parent = $(this).parent();
    $(parent).removeClass("active");
    $(parent).children("div").each(function() {
    //$("#emptypanel-wrapper > div" ).each(function() {
        $(this).addClass("hidden");
    });
});

//Set an extended function to jquery
$.fn.extend({
    //Opens the info-panel
    togglePanelOnClick: function () {
        this.toggleClass("hidden");
        $("#sidepanel-wrapper").toggleClass("active");
        $("#sidebar-wrapper").toggleClass("active");
        return false;
    }
});

/*Object to manage the slider actions
 */
IocSlider = function(){
    this.hindx=-1;
    this.vindx=-1;
    this.watchers={"onSetCurrentSlide":[function(e){
        var hCurrentId, vCurrentId;
        if(e.newValues.hindx>=0){
            hCurrentId = $(e.newValues.hslides[e.newValues.hindx]).attr("id");
            var pathname = location.pathname;
            if(location.search){
                pathname += location.search;
            }
            if(e.newValues.vindx<0){
                history.pushState({hash:pathname+"#"+hCurrentId},
                                    document.title,
                                    pathname+"#"+hCurrentId);
            }else{
                vCurrentId = $(e.newValues.vslides[e.newValues.vindx]).attr("id");
                if(vCurrentId){
                    history.pushState(
                                //{hash:location.pathname+"#"+hCurrentId+"__"+vCurrentId},
                                {hash:pathname+"#"+hCurrentId+"__"+vCurrentId},
                                document.title,
                                pathname+"#"+hCurrentId+"__"+vCurrentId);
                }else{
                    history.pushState({hash:pathname+"#"+hCurrentId},
                                        document.title,
                                        pathname+"#"+hCurrentId);
                }
            }
            if(e.oldValues.hindx!=e.newValues.hindx){
                $(".navbar-fixed-top a").each(function(){
                    var idInRef = this.href.split("#")[1];
                    if (hCurrentId == idInRef) {
                        $(".navbar-fixed-top").find(".active").removeClass("active");
                        $(this).parent().addClass("active");
                    }
                });
            }
        }
    }]};

    var slider = $("#mainSlider").get(0);

    this.watch = function(target, observer){
        if(!this.watchers[target]){
            this.watchers[target]=[];
        }
        this.watchers[target].push(observer);
    }

    this._fireEvent=function(event, dataEvent){
        for(var i=0; this.watchers[event]
                    && i<this.watchers[event].length; i++){
            this.watchers[event][i].call(this, dataEvent);
        }
    }

    this._setVerticalSlides = function(last){
        var vSlides, cssClass, indx;

        if(this.hindx>=0){
            vSlides = $(this.hslides[this.hindx]).children(".section");
            if(vSlides.length){
                this.vslides = vSlides;
                if(last){
                    cssClass = {add:"rear", remove:"front"};
                    indx = vSlides.length-1;
                }else{
                    cssClass = {add:"front", remove:"rear"};
                    indx = 0;
                }
                for(var i=0; i<this.vslides.length; i++){
                   var $vslides = $(this.vslides[i]);
                    $vslides.addClass(cssClass.add).removeClass(cssClass.remove);
                }
                this._setVIndx(indx);
            }else{
                this._setVIndx(-1);
                this.vslides = undefined;
            }
        }else{
            this.vslides = undefined;
                this._setVIndx(-1);
        }
    };

    this.hasVerticalSlides = function(){
        return this.vindx>=0;
    };

    this.next = function(){
        var hor = !this.hasVerticalSlides();
        if(!hor){
            if(this.vslides.length>(this.vindx+1)){
                this.incVIndx(1);
            }else{
                this.setVIndx(-1);
                hor = true;
            }
        }
        if(hor){
            if(this.hslides.length>(this.hindx+1)){
                this.incHIndx(1);
            }
        }
    };

    this.previous = function(){
        var hor = !this.hasVerticalSlides();
        if(!hor){
            if((this.vindx-1)>=0){
                this.incVIndx(-1, true);
            }else{
                this.setVIndx(-1, true);
                hor = true;
            }
        }
        if(hor){
            if((this.hindx-1)>=0){
                this.incHIndx(-1, true);
            }
        }
    };

    this.setHIndx = function(hindx, toBack, vToBack){
        var e = {oldValues:{
                        hslides: this.hslides, hindx:this.hindx,
                        vslides: this.vslides, vindx:this.vindx},
                 newValues:{
                        hslides: this.hslides, hindx:hindx,
                        vslides: this.vslides, vindx:this.vindx}};
        this._setHIndx(hindx, toBack, vToBack);
        e.newValues.vindx = this.vindx;
        e.newValues.vslides= this.vslides;
        this._fireEvent('onSetCurrentSlide', e);
    }

    this._setHIndx = function(hindx, toBack, vToBack){
        if(this.hindx>=0){
            if(toBack){
                $(this.hslides[this.hindx]).addClass("front").removeClass("current");
            }else{
                $(this.hslides[this.hindx]).addClass("rear").removeClass("current");

            }
        }
        this.hindx=hindx;

        if(this.hindx>=0){
            $(this.hslides[this.hindx]).addClass("current").removeClass("rear").removeClass("front");
            $(this.hslides[this.hindx]).scrollLeft( 0 );
        }

        if(vToBack===undefined){
            vToBack = toBack;
        }
        this._setVerticalSlides(vToBack);
    };

    this.incHIndx = function(hindx, toBack){
        this.setHIndx(this.hindx+hindx, toBack)
    };

    this.setVIndx = function(vindx, toBack){
        var e = {oldValues:{
                        hslides: this.hslides, hindx:this.hindx,
                        vslides: this.vslides, vindx:this.vindx},
                newValues:{hslides: this.hslides, hindx:this.hindx,
                        vslides: this.vslides, vindx:vindx}};
        this._setVIndx(vindx, toBack);
        this._fireEvent('onSetCurrentSlide', e);
    }

    this._setVIndx = function(vindx, toBack){
        if(this.vindx>=0){
            if(toBack){
                $(this.vslides[this.vindx]).addClass("front").removeClass("current");
            }else{
                $(this.vslides[this.vindx]).addClass("rear").removeClass("current");
            }
        }

        this.vindx=vindx;

        if(this.vindx>=0){
            $(this.vslides[this.vindx]).addClass("current").removeClass("rear").removeClass("front");
            $(this.vslides[this.vindx]).scrollTop( 0 );
        }
    };

    this.incVIndx = function(vindx, toBack){
        this.setVIndx(this.vindx+vindx, toBack);
    };

    this.setTargetIndx = function(hTarget, vTarget){
        var i=0;
        while(i<this.hslides.length && this.hslides[i]!==hTarget){
            i++;
        }
        if(i<this.hslides.length){
            if(this.hindx!=i){
                //this.setVIndx(-1);
                this.setHIndx(i, i<this.hindx, false);
                if(vTarget){
                    _setVerticalTargetIndx(vTarget);
                }
            }
        }else{
            console.error("error slide not fount (" + hTarget.id +")");
        }
    };

    this.addJssorSlider = function(jssorSliderId){
        if(!this.aSliders){
            this.aSliders = {};
        }
        this.aSliders[jssorSliderId] = jssor_slider1_starter(jssorSliderId);
        this.watch('onSetCurrentSlide', function(e){
            var slide,
            jssorSlider,
            oldSlide =e.oldValues.hindx!=-1
                                ?e.oldValues.hslides[e.oldValues.hindx]
                                :e.oldValues.vslides[e.oldValues.vindx];

            jssorSlider = $(oldSlide).find("[data-u='slider']");
            if(jssorSlider.length){
                this.aSliders[jssorSlider.attr('id')].$Pause();
            }

            slide = this.hasVerticalSlides()
                                ?this.vslides[this.vindx]
                                :this.hslides[this.hindx];
            jssorSlider = $(slide).find("[data-u='slider']");
            if(jssorSlider.length){
                this.aSliders[jssorSlider.attr('id')].$Play();
                this.aSliders[jssorSlider.attr('id')].$PlayTo(0);
            }
        });
    };

    this.hslides = $(slider).children(".slides").children("section");

    var vWidth = $(window).width();
    var vHeight = $(window).height();

    for(var i=0; i<this.hslides.length; i++){
        var $hslides = $(this.hslides[i]);
        $hslides.addClass("front");
    }

    var self = this;

    var _setVerticalTargetIndx = function(vTarget){
        var i=0;
        while(i<self.vslides.length && self.vslides[i]!==vTarget){
            i++;
        }
        if(i<self.vslides.length){
            if(self.vindx!=i){
                self.setVIndx(i);
            }
        }else{
            console.error("error slide not fount (" + vTarget.id +")");
        }
    };

    if(location.hash){
        var target = location.hash.split("__");
        self.setTargetIndx($(target[0]).get(0), $("#" + target[1]).get(0));
    }else{
        this.setHIndx(this.hslides?0:-1);
    }

    $("#nextArrow").click(function(){
        self.next();
    });

    $("#prevArrow").click(function(){
        self.previous();
    });

    $(function() {
//        $('a[href*=#]:not([href=#])').click(function() {
        $('a[href|="#slc"]').click(function() {
            if (location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') || location.hostname == this.hostname) {
                var targeth;
                var targetv;
                var aTarget = this.hash.split("__");
                if(aTarget.length>0){
                    targeth = $(aTarget[0]);
                    if(aTarget.length>1){
                        targetv = $("#" + aTarget[1]);
                    }
                    if (targeth.length && targetv) {
                        self.setTargetIndx(targeth.get(0), targetv.get(0));
                        return false;
                    }else if (targeth.length) {
                        self.setTargetIndx(targeth.get(0));
                        return false;
                    }
                }
            }
        });
    });

//    $(window).unload(function(e){
//        e.preventDefault();
//        if(location.hash){
//            location=location.hash;
//        }
//    });
};
<commit_msg>correccio de l'error per accedir a un vincle intern<commit_after>/*
 * To relocate elements with existent attribute data-parent-selector as children of this
 * attribute value.
 */
$(document).ready(function(){
    $("[data-parent-selector]").each(function(){
        var parent = this.dataset.parentSelector;
        var element = $(this).detach();
        $(parent).append(element);
    });
});

/*
 * Captura les tecles fletxa-esq i fletxa-dreta per simular un click al botó
 * prevArrow o nextArrow respectivament.
 */
$(document).keydown(function(e){
    switch(e.which){
        case 39:
             $("#nextArrow").click();
             break;
         case 37:
             $("#prevArrow").click();
             break;
    }
    return true;
});

//jQuery to collapse the navbar on scroll
$(window).scroll(function() {
    if ($(".navbar").offset().top > 50) {
        $(".navbar-fixed-top").addClass("top-nav-collapse");
    } else {
        $(".navbar-fixed-top").removeClass("top-nav-collapse");
    }
});

/* ----------------------------------------------------------- */
/*  MOBILE MENU CLOSE
/* ----------------------------------------------------------- */

$('.navbar-nav').on('click', 'li a', function() {
  $('.navbar-collapse').collapse('hide');
});

/* ----------------------------------------------------------- */
/*  Toggle Menu
/* ----------------------------------------------------------- */
// Closes the sidebar menu
$("#menu-close").click(function(e) {
    e.preventDefault();
    $("#sidebar-wrapper").toggleClass("active");
});

// Opens the sidebar menu
$("#menu-toggle").click(function(e) {
    e.preventDefault();
    $("#sidebar-wrapper").toggleClass("active");
});

/*-----------------------------------*/
/*  INFO PANEL
 *-----------------------------------*/
//Set function to close the info-panel on click button panel-close
$(".panel-close").click(function(e) {
    e.preventDefault();
    var parent = $(this).parent();
    $(parent).removeClass("active");
    $(parent).children("div").each(function() {
    //$("#emptypanel-wrapper > div" ).each(function() {
        $(this).addClass("hidden");
    });
});

//Set an extended function to jquery
$.fn.extend({
    //Opens the info-panel
    togglePanelOnClick: function () {
        this.toggleClass("hidden");
        $("#sidepanel-wrapper").toggleClass("active");
        $("#sidebar-wrapper").toggleClass("active");
        return false;
    }
});

/*Object to manage the slider actions
 */
IocSlider = function(){
    this.hindx=-1;
    this.vindx=-1;
    this.watchers={"onSetCurrentSlide":[function(e){
        var hCurrentId, vCurrentId;
        if(e.newValues.hindx>=0){
            hCurrentId = $(e.newValues.hslides[e.newValues.hindx]).attr("id");
            var pathname = location.pathname;
            if(location.search){
                pathname += location.search;
            }
            if(e.newValues.vindx<0){
                history.pushState({hash:pathname+"#"+hCurrentId},
                                    document.title,
                                    pathname+"#"+hCurrentId);
            }else{
                vCurrentId = $(e.newValues.vslides[e.newValues.vindx]).attr("id");
                if(vCurrentId){
                    history.pushState(
                                //{hash:location.pathname+"#"+hCurrentId+"__"+vCurrentId},
                                {hash:pathname+"#"+hCurrentId+"__"+vCurrentId},
                                document.title,
                                pathname+"#"+hCurrentId+"__"+vCurrentId);
                }else{
                    history.pushState({hash:pathname+"#"+hCurrentId},
                                        document.title,
                                        pathname+"#"+hCurrentId);
                }
            }
            if(e.oldValues.hindx!=e.newValues.hindx){
                $(".navbar-fixed-top a").each(function(){
                    var idInRef = this.href.split("#")[1];
                    if (hCurrentId == idInRef) {
                        $(".navbar-fixed-top").find(".active").removeClass("active");
                        $(this).parent().addClass("active");
                    }
                });
            }
        }
    }]};

    var slider = $("#mainSlider").get(0);

    this.watch = function(target, observer){
        if(!this.watchers[target]){
            this.watchers[target]=[];
        }
        this.watchers[target].push(observer);
    }

    this._fireEvent=function(event, dataEvent){
        for(var i=0; this.watchers[event]
                    && i<this.watchers[event].length; i++){
            this.watchers[event][i].call(this, dataEvent);
        }
    }

    this._setVerticalSlides = function(last){
        var vSlides, cssClass, indx;

        if(this.hindx>=0){
            vSlides = $(this.hslides[this.hindx]).children(".section");
            if(vSlides.length){
                this.vslides = vSlides;
                if(last){
                    cssClass = {add:"rear", remove:"front"};
                    indx = vSlides.length-1;
                }else{
                    cssClass = {add:"front", remove:"rear"};
                    indx = 0;
                }
                for(var i=0; i<this.vslides.length; i++){
                   var $vslides = $(this.vslides[i]);
                    $vslides.addClass(cssClass.add).removeClass(cssClass.remove);
                }
                this._setVIndx(indx);
            }else{
                this._setVIndx(-1);
                this.vslides = undefined;
            }
        }else{
            this.vslides = undefined;
                this._setVIndx(-1);
        }
    };

    this.hasVerticalSlides = function(){
        return this.vindx>=0;
    };

    this.next = function(){
        var hor = !this.hasVerticalSlides();
        if(!hor){
            if(this.vslides.length>(this.vindx+1)){
                this.incVIndx(1);
            }else{
                this.setVIndx(-1);
                hor = true;
            }
        }
        if(hor){
            if(this.hslides.length>(this.hindx+1)){
                this.incHIndx(1);
            }
        }
    };

    this.previous = function(){
        var hor = !this.hasVerticalSlides();
        if(!hor){
            if((this.vindx-1)>=0){
                this.incVIndx(-1, true);
            }else{
                this.setVIndx(-1, true);
                hor = true;
            }
        }
        if(hor){
            if((this.hindx-1)>=0){
                this.incHIndx(-1, true);
            }
        }
    };

    this.setHIndx = function(hindx, toBack, vToBack){
        var e = {oldValues:{
                        hslides: this.hslides, hindx:this.hindx,
                        vslides: this.vslides, vindx:this.vindx},
                 newValues:{
                        hslides: this.hslides, hindx:hindx,
                        vslides: this.vslides, vindx:this.vindx}};
        this._setHIndx(hindx, toBack, vToBack);
        e.newValues.vindx = this.vindx;
        e.newValues.vslides= this.vslides;
        this._fireEvent('onSetCurrentSlide', e);
    }

    this._setHIndx = function(hindx, toBack, vToBack){
        if(this.hindx>=0){
            if(toBack){
                $(this.hslides[this.hindx]).addClass("front").removeClass("current");
            }else{
                $(this.hslides[this.hindx]).addClass("rear").removeClass("current");

            }
        }
        this.hindx=hindx;

        if(this.hindx>=0){
            $(this.hslides[this.hindx]).addClass("current").removeClass("rear").removeClass("front");
            $(this.hslides[this.hindx]).scrollLeft( 0 );
        }

        if(vToBack===undefined){
            vToBack = toBack;
        }
        this._setVerticalSlides(vToBack);
    };

    this.incHIndx = function(hindx, toBack){
        this.setHIndx(this.hindx+hindx, toBack)
    };

    this.setVIndx = function(vindx, toBack){
        var e = {oldValues:{
                        hslides: this.hslides, hindx:this.hindx,
                        vslides: this.vslides, vindx:this.vindx},
                newValues:{hslides: this.hslides, hindx:this.hindx,
                        vslides: this.vslides, vindx:vindx}};
        this._setVIndx(vindx, toBack);
        this._fireEvent('onSetCurrentSlide', e);
    }

    this._setVIndx = function(vindx, toBack){
        if(this.vindx>=0){
            if(toBack){
                $(this.vslides[this.vindx]).addClass("front").removeClass("current");
            }else{
                $(this.vslides[this.vindx]).addClass("rear").removeClass("current");
            }
        }

        this.vindx=vindx;

        if(this.vindx>=0){
            $(this.vslides[this.vindx]).addClass("current").removeClass("rear").removeClass("front");
            $(this.vslides[this.vindx]).scrollTop( 0 );
        }
    };

    this.incVIndx = function(vindx, toBack){
        this.setVIndx(this.vindx+vindx, toBack);
    };

    this.setTargetIndx = function(hTarget, vTarget){
        var i=0;
        while(i<this.hslides.length && this.hslides[i]!==hTarget){
            i++;
        }
        if(i<this.hslides.length){
            if(this.hindx!=i){
                //this.setVIndx(-1);
                this.setHIndx(i, i<this.hindx, false);
            }
            if(vTarget){
                _setVerticalTargetIndx(vTarget);
            }
        }else{
            console.error("error slide not fount (" + hTarget.id +")");
        }
    };

    this.addJssorSlider = function(jssorSliderId){
        if(!this.aSliders){
            this.aSliders = {};
        }
        this.aSliders[jssorSliderId] = jssor_slider1_starter(jssorSliderId);
        this.watch('onSetCurrentSlide', function(e){
            var slide,
            jssorSlider,
            oldSlide =e.oldValues.hindx!=-1
                                ?e.oldValues.hslides[e.oldValues.hindx]
                                :e.oldValues.vslides[e.oldValues.vindx];

            jssorSlider = $(oldSlide).find("[data-u='slider']");
            if(jssorSlider.length){
                this.aSliders[jssorSlider.attr('id')].$Pause();
            }

            slide = this.hasVerticalSlides()
                                ?this.vslides[this.vindx]
                                :this.hslides[this.hindx];
            jssorSlider = $(slide).find("[data-u='slider']");
            if(jssorSlider.length){
                this.aSliders[jssorSlider.attr('id')].$Play();
                this.aSliders[jssorSlider.attr('id')].$PlayTo(0);
            }
        });
    };

    this.hslides = $(slider).children(".slides").children("section");

    var vWidth = $(window).width();
    var vHeight = $(window).height();

    for(var i=0; i<this.hslides.length; i++){
        var $hslides = $(this.hslides[i]);
        $hslides.addClass("front");
    }

    var self = this;

    var _setVerticalTargetIndx = function(vTarget){
        var i=0;
        while(i<self.vslides.length && self.vslides[i]!==vTarget){
            i++;
        }
        if(i<self.vslides.length){
            if(self.vindx!=i){
                self.setVIndx(i);
            }
        }else{
            console.error("error slide not fount (" + vTarget.id +")");
        }
    };

    if(location.hash){
        var target = location.hash.split("__");
        self.setTargetIndx($(target[0]).get(0), $("#" + target[1]).get(0));
    }else{
        this.setHIndx(this.hslides?0:-1);
    }

    $("#nextArrow").click(function(){
        self.next();
    });

    $("#prevArrow").click(function(){
        self.previous();
    });

    $(function() {
//        $('a[href*=#]:not([href=#])').click(function() {
        $('a[href|="#slc"]').click(function() {
            if (location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') || location.hostname == this.hostname) {
                var targeth;
                var targetv;
                var aTarget = this.hash.split("__");
                if(aTarget.length>0){
                    targeth = $(aTarget[0]);
                    if(aTarget.length>1){
                        targetv = $("#" + aTarget[1]);
                    }
                    if (targeth.length && targetv) {
                        self.setTargetIndx(targeth.get(0), targetv.get(0));
                        return false;
                    }else if (targeth.length) {
                        self.setTargetIndx(targeth.get(0));
                        return false;
                    }
                }
            }
        });
    });

//    $(window).unload(function(e){
//        e.preventDefault();
//        if(location.hash){
//            location=location.hash;
//        }
//    });
};
<|endoftext|>


<commit_before>/**
 * Dependencies.
 */

let React = require('react');
let moment = require('moment');
let Product = require('./product.react');
let getDay = require('../util/get-day');
let groupByDay = require('../util/group-by-day');

/**
 * Product Group component.
 *
 * Renders the products grouped by date.
 *
 * Usage:
 *
 * ```js
 * <ProductGroup />
 * ```
 *
 * Properties:
 *
 * - `products`: Products to be grouped and rendered.
 * - `onClick`:  On product click cb
 *
 * @class
 */

let ProductGroup = React.createClass({

  /**
   * Render the view.
   */

  render() {
    let groups = groupByDay(this.props.products);
    let onClick = this.props.onClick;
    let out = [];

    Object.keys(groups).map(function(day) {
      let date = moment(day);
      let humanDay = getDay(date);
      let monthDay = date.format('MMMM Do');
      let products = groups[day].map(function(product) {
        return <Product product={product} onClick={onClick} />
      });

      out.push(

{humanDay} {monthDay}

          {{products}}

      );
    });

    return
{{out}}

  }
});

/**
 * Export `ProductGroup`.
 */

module.exports = ProductGroup;
<commit_msg>Leverage map<commit_after>/**
 * Dependencies.
 */

let React = require('react');
let moment = require('moment');
let Product = require('./product.react');
let getDay = require('../util/get-day');
let groupByDay = require('../util/group-by-day');

/**
 * Product Group component.
 *
 * Renders the products grouped by date.
 *
 * Usage:
 *
 * ```js
 * <ProductGroup />
 * ```
 *
 * Properties:
 *
 * - `products`: Products to be grouped and rendered.
 * - `onClick`:  On product click cb
 *
 * @class
 */

let ProductGroup = React.createClass({

  /**
   * Render the view.
   */

  render() {
    let groups = groupByDay(this.props.products);
    let onClick = this.props.onClick;
    let out = Object.keys(groups).map(function(day) {
      let date = moment(day);
      let humanDay = getDay(date);
      let monthDay = date.format('MMMM Do');
      let products = groups[day].map(function(product) {
        return <Product product={product} onClick={onClick} />
      });

      return (

{humanDay} {monthDay}

          {{products}}

      );
    });

    return
{{out}}

  }
});

/**
 * Export `ProductGroup`.
 */

module.exports = ProductGroup;
<|endoftext|>


<commit_before>const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Lang = imports.lang;
const Mainloop = imports.mainloop;

/**
 * Class: AsyncTask
 *
 * A convenience class for writing Gio style asynchronous functions. Basically
 * like a GTask, but can be used in javascript with lots of goodies for easy
 * javascript error checking.
 *
 * At a high level, a task will have two functions <return_value> and
 * <return_error>, which will set our task result and then call into a callback
 * function, signaling that the task has run. Then the <finish> function can be
 * run to retrieve the result or error.
 *
 * Parameters:
 *   source - The source object, i.e. the object with the asynchronous function
 *   cancellable - A Gio.Cancellable, can be null
 *   callback - The function to call on task completion
 */
const AsyncTask = Lang.Class({
    Name: 'AsyncTask',
    GTypeName: 'EknAsyncTask',
    Extends: GObject.Object,

    _init: function (source, cancellable, callback) {
        this.parent();

        this._source = source;
        this._callback = callback;
        this._done = false;

        if (cancellable) {
            let handle_cancel = () => {
                let error = GLib.Error.new_literal(Gio.io_error_quark(),
                                                   Gio.IOErrorEnum.CANCELLED,
                                                   'Async call cancelled');
                this.return_error(error);
            };
            if (cancellable.cancelled) {
                handle_cancel();
            } else {
                cancellable.connect(handle_cancel);
            }
        }
    },

    /**
     * Function: catch_errors
     *
     * Takes in a function and runs it inside of a try catch, calling
     * <return_error> on any error. Any parameters after the *fn* will be
     * applied as arguments to the *fn*.
     *
     * Parameters:
     *   fn - The function to call with error handling
     */
    catch_errors: function (fn) {
        if (this._done)
            return;
        try {
            fn.apply(this._source, Array.slice(arguments, 1));
        } catch (error) {
            this.return_error(error);
        }
    },

    /**
     * Function: catch_callback_errors
     *
     * Wraps a callback function inside of a second function, which will catch
     * all errors and call <return_error>.
     *
     * Parameters:
     *   fn - The callback to be wrapped inside an error handling function
     */
    catch_callback_errors: function (fn) {
        if (this._done)
            return () => {};
        let caller_stack = new Error().stack;
        // Remove this current stack frame
        caller_stack = caller_stack.split('\n').slice(1).join('\n');
        return () => {
            try {
                fn.apply(this._source, arguments);
            } catch (error) {
                error.stack += '--- Called from: ---\n' + caller_stack;
                this.return_error(error);
            }
        };
    },

    /**
     * Function: return_value
     *
     * Sets an object to be returned by the <finish> function. Will call into
     * the task callback function, signaling the task is complete.
     *
     * Parameters:
     *   object - The value to return in <finish>
     */
    return_value: function (object) {
        if (this._done)
            return;
        this._object = object;
        this._callback_in_idle();
    },

    /**
     * Function: return_error
     *
     * Sets an error to be thrown by the <finish> function. Will call into the
     * task callback function, signaling the task is complete.
     *
     * You probably want need to call this directly see <catch_errors> and
     * <catch_callback_errors>.
     *
     * Parameters:
     *   error - The error to throw in <finish>
     */
    return_error: function (error) {
        if (this._done)
            return;
        this._error = error;
        this._callback_in_idle();
    },

    _callback_in_idle: function () {
        this._done = true;
        Mainloop.idle_add(() => {
            this._callback(this._source, this);
            return GLib.SOURCE_REMOVE;
        });
    },

    /**
     * Function: finish
     *
     * Returns the object set by <return_value>, or throws the error set by
     * <return_error>.
     */
    finish: function () {
        if (!this._done)
            throw new Error('Finish called, but async task not yet complete.');
        if (this._error)
            throw this._error;
        return this._object;
    },
});

// A perhaps silly way to emulate Promise.all using AsyncTask.
function all (source, func, cancellable, callback) {
    let task = new AsyncTask(source, cancellable, callback);

    let results = [];
    let waiting = 0;

    let subfuncs = [];

    func((add_task_func, finish) => {
        let task_idx = results.length;
        results.push(null);
        ++waiting;

        function task_callback(source, subtask) {
            let value = finish(subtask);
            results[task_idx] = value;
            if (--waiting === 0)
                task.return_value(results);
        }

        // Delay calling add_task_func until after we return from the main function
        // just in case one subtask resolves immediately...
        subfuncs.push(add_task_func.bind(null, cancellable, task.catch_callback_errors(task_callback)));
    });

    // Now go ahead and call the add_task_funcs.
    subfuncs.forEach((func) => func());

    // If we don't have any subfunctions, return immediately.
    if (subfuncs.length === 0)
        task.return_value([]);

    return task;
}

function all_finish (task) {
    return task.finish();
}
<commit_msg>Allow clients of AsyncTask to provide custom priority value<commit_after>const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GObject = imports.gi.GObject;
const Lang = imports.lang;

/**
 * Class: AsyncTask
 *
 * A convenience class for writing Gio style asynchronous functions. Basically
 * like a GTask, but can be used in javascript with lots of goodies for easy
 * javascript error checking.
 *
 * At a high level, a task will have two functions <return_value> and
 * <return_error>, which will set our task result and then call into a callback
 * function, signaling that the task has run. Then the <finish> function can be
 * run to retrieve the result or error.
 *
 * Parameters:
 *   source - The source object, i.e. the object with the asynchronous function
 *   cancellable - A Gio.Cancellable, can be null
 *   callback - The function to call on task completion
 */
const AsyncTask = Lang.Class({
    Name: 'AsyncTask',
    GTypeName: 'EknAsyncTask',
    Extends: GObject.Object,

    _init: function (source, cancellable, callback, priority=GLib.PRIORITY_DEFAULT) {
        this.parent();

        this._source = source;
        this._callback = callback;
        this._done = false;
        this._priority = priority;

        if (cancellable) {
            let handle_cancel = () => {
                let error = GLib.Error.new_literal(Gio.io_error_quark(),
                                                   Gio.IOErrorEnum.CANCELLED,
                                                   'Async call cancelled');
                this.return_error(error);
            };
            if (cancellable.cancelled) {
                handle_cancel();
            } else {
                cancellable.connect(handle_cancel);
            }
        }
    },

    /**
     * Function: catch_errors
     *
     * Takes in a function and runs it inside of a try catch, calling
     * <return_error> on any error. Any parameters after the *fn* will be
     * applied as arguments to the *fn*.
     *
     * Parameters:
     *   fn - The function to call with error handling
     */
    catch_errors: function (fn) {
        if (this._done)
            return;
        try {
            fn.apply(this._source, Array.slice(arguments, 1));
        } catch (error) {
            this.return_error(error);
        }
    },

    /**
     * Function: catch_callback_errors
     *
     * Wraps a callback function inside of a second function, which will catch
     * all errors and call <return_error>.
     *
     * Parameters:
     *   fn - The callback to be wrapped inside an error handling function
     */
    catch_callback_errors: function (fn) {
        if (this._done)
            return () => {};
        let caller_stack = new Error().stack;
        // Remove this current stack frame
        caller_stack = caller_stack.split('\n').slice(1).join('\n');
        return () => {
            try {
                fn.apply(this._source, arguments);
            } catch (error) {
                error.stack += '--- Called from: ---\n' + caller_stack;
                this.return_error(error);
            }
        };
    },

    /**
     * Function: return_value
     *
     * Sets an object to be returned by the <finish> function. Will call into
     * the task callback function, signaling the task is complete.
     *
     * Parameters:
     *   object - The value to return in <finish>
     */
    return_value: function (object) {
        if (this._done)
            return;
        this._object = object;
        this._callback_in_idle();
    },

    /**
     * Function: return_error
     *
     * Sets an error to be thrown by the <finish> function. Will call into the
     * task callback function, signaling the task is complete.
     *
     * You probably want need to call this directly see <catch_errors> and
     * <catch_callback_errors>.
     *
     * Parameters:
     *   error - The error to throw in <finish>
     */
    return_error: function (error) {
        if (this._done)
            return;
        this._error = error;
        this._callback_in_idle();
    },

    _callback_in_idle: function () {
        this._done = true;
        GLib.idle_add(this._priority, () => {
            this._callback(this._source, this);
            return GLib.SOURCE_REMOVE;
        });
    },

    /**
     * Function: finish
     *
     * Returns the object set by <return_value>, or throws the error set by
     * <return_error>.
     */
    finish: function () {
        if (!this._done)
            throw new Error('Finish called, but async task not yet complete.');
        if (this._error)
            throw this._error;
        return this._object;
    },
});

// A perhaps silly way to emulate Promise.all using AsyncTask.
function all (source, func, cancellable, callback) {
    let task = new AsyncTask(source, cancellable, callback);

    let results = [];
    let waiting = 0;

    let subfuncs = [];

    func((add_task_func, finish) => {
        let task_idx = results.length;
        results.push(null);
        ++waiting;

        function task_callback(source, subtask) {
            let value = finish(subtask);
            results[task_idx] = value;
            if (--waiting === 0)
                task.return_value(results);
        }

        // Delay calling add_task_func until after we return from the main function
        // just in case one subtask resolves immediately...
        subfuncs.push(add_task_func.bind(null, cancellable, task.catch_callback_errors(task_callback)));
    });

    // Now go ahead and call the add_task_funcs.
    subfuncs.forEach((func) => func());

    // If we don't have any subfunctions, return immediately.
    if (subfuncs.length === 0)
        task.return_value([]);

    return task;
}

function all_finish (task) {
    return task.finish();
}
<|endoftext|>


<commit_before>document.getElementById("idLogicV").innerHTML = "Logic level version: 2017.11.15.0"

var circleR = document.getElementById("circleRed");
var circleG = document.getElementById("circleGreen");

circleR.addEventListener("touchmove", onTouchMove);
circleG.addEventListener("touchmove", onTouchMove);

var svg = document.getElementById("svg");
var rect = svg.getBoundingClientRect();

function onTouchMove(e){
	var touches = e.changedTouches;

	for (var i = 0; i < touches.length; i++){
		var circle = touches[i].target;

		circle.setAttribute("cx", touches[i].pageX - rect.left);
		circle.setAttribute("cy", touches[i].pageY - rect.top);
	}

}

<commit_msg>circle inside box<commit_after>document.getElementById("idLogicV").innerHTML = "Logic level version: 2017.11.15.0"

var circleR = document.getElementById("circleRed");
var circleG = document.getElementById("circleGreen");

circleR.addEventListener("touchmove", onTouchMove);
circleG.addEventListener("touchmove", onTouchMove);

var svg = document.getElementById("svg");
var rect = svg.getBoundingClientRect();

function onTouchMove(e){
	e.preventDefault();
	var touches = e.changedTouches;

	for (var i = 0; i < touches.length; i++){
		var circle = touches[i].target;
		if( touches[i].pageX - rect.left <= rect.width  &&
			touches[i].pageY - rect.top <= rect.height  &&
			touches[i].pageX - rect.left >= 0  &&
			touches[i].pageY - rect.top >= 0 ){
			circle.setAttribute("cx", touches[i].pageX - rect.left);
			circle.setAttribute("cy", touches[i].pageY - rect.top);
		}
	}

}

<|endoftext|>


<commit_before>// Copyright 2016, University of Colorado Boulder

/**
 *
 * @author Sam Reid (PhET Interactive Simulations)
 * @author Andrew Adare (PhET Interactive Simulations)
 */
define( function( require ) {
  'use strict';

  // modules
  var assertInstanceOf = require( 'PHET_IO/assertions/assertInstanceOf' );
  var phetio = require( 'PHET_IO/phetio' );
  var phetioInherit = require( 'PHET_IO/phetioInherit' );
  var phetioNamespace = require( 'PHET_IO/phetioNamespace' );
  var SimIFrameAPI = require( 'PHET_IO/SimIFrameAPI' );
  var TFunctionWrapper = require( 'PHET_IO/types/TFunctionWrapper' );
  var TObject = require( 'PHET_IO/types/TObject' );
  var toEventOnEmit = require( 'PHET_IO/events/toEventOnEmit' );
  var TString = require( 'PHET_IO/types/TString' );
  var TVoid = require( 'PHET_IO/types/TVoid' );

  /**
   * Wrapper type for phet/joist's Sim class.
   * @param sim
   * @param phetioID
   * @constructor
   */
  function TSim( sim, phetioID ) {
    assertInstanceOf( sim, phet.joist.Sim );
    TObject.call( this, sim, phetioID );

    // startedSimConstructorEmitter is called in the constructor of the sim, and endedSimConstructionEmitter is called
    // once all of the screens have been fully initialized, hence construction not constructor.
    toEventOnEmit( sim.startedSimConstructorEmitter, sim.endedSimConstructionEmitter, 'model', phetioID, TSim, 'simStarted',
      function( value ) {
        return {
          sessionID: value.sessionID,
          repoName: value.repoName,
          simName: value.simName,
          simVersion: value.simVersion,
          simURL: value.url,
          userAgent: window.navigator.userAgent,
          randomSeed: value.randomSeed,
          extraMetadata: window.simStartedMetadata,
          provider: 'PhET Interactive Simulations, University of Colorado Boulder' // See #137
        };
      } );

    // Store a reference to the sim so that subsequent calls will be simpler.  PhET-iO only works with a single sim.
    phetio.sim = sim;
    sim.endedSimConstructionEmitter.addListener( function() {

      // TODO: Can these be coalesced?
      SimIFrameAPI.triggerSimInitialized();
      phetio.simulationStarted();
    } );
  }

  phetioInherit( TObject, 'TSim', TSim, {

    disableRequestAnimationFrame: {
      returnType: TVoid,
      parameterTypes: [],
      implementation: function() {
        this.instance.disableRequestAnimationFrame();
      },
      documentation: 'Prevents the simulation from animating/updating'
    },

    addEventListener: {
      returnType: TVoid,
      parameterTypes: [ TString, TFunctionWrapper( TVoid, [ TString, TFunctionWrapper( TVoid, [] ) ] ) ],
      implementation: function( eventName, listener ) {
        this.instance.onStatic( eventName, listener );
      },
      documentation: 'Add an event listener to the sim instance'
    },

    getScreenshotDataURL: {
      returnType: TString,
      parameterTypes: [],
      implementation: function() {
        return window.phet.joist.ScreenshotGenerator.generateScreenshot( this.instance );
      },
      documentation: 'Gets a base64 representation of a screenshot of the simulation as a data url'
    }
  }, {
    documentation: 'The type for the simulation instance',
    events: [
      'simStarted'
    ]
  } );

  phetioNamespace.register( 'TSim', TSim );

  return TSim;
} );
<commit_msg>Commented on usage of simStarted event as top level, and updated some formatting, see https://github.com/phetsims/phet-io/issues/44<commit_after>// Copyright 2016, University of Colorado Boulder

/**
 *
 * @author Sam Reid (PhET Interactive Simulations)
 * @author Andrew Adare (PhET Interactive Simulations)
 */
define( function( require ) {
  'use strict';

  // modules
  var assertInstanceOf = require( 'PHET_IO/assertions/assertInstanceOf' );
  var phetio = require( 'PHET_IO/phetio' );
  var phetioInherit = require( 'PHET_IO/phetioInherit' );
  var phetioNamespace = require( 'PHET_IO/phetioNamespace' );
  var SimIFrameAPI = require( 'PHET_IO/SimIFrameAPI' );
  var TFunctionWrapper = require( 'PHET_IO/types/TFunctionWrapper' );
  var TObject = require( 'PHET_IO/types/TObject' );
  var toEventOnEmit = require( 'PHET_IO/events/toEventOnEmit' );
  var TString = require( 'PHET_IO/types/TString' );
  var TVoid = require( 'PHET_IO/types/TVoid' );

  // constants
  // The token for the event that occurs when the simulation constructor completes. This is hard-coded in many places
  // such as th playback wrapper, so should not be changed lightly!
  var SIM_STARTED = 'simStarted';

  /**
   * Wrapper type for phet/joist's Sim class.
   * @param sim
   * @param phetioID
   * @constructor
   */
  function TSim( sim, phetioID ) {
    assertInstanceOf( sim, phet.joist.Sim );
    TObject.call( this, sim, phetioID );

    // startedSimConstructorEmitter is called in the constructor of the sim, and endedSimConstructionEmitter is called
    // once all of the screens have been fully initialized, hence construction not constructor.
    // The simStarted event is guaranteed to be a top-level event, not nested under other events.
    toEventOnEmit( sim.startedSimConstructorEmitter, sim.endedSimConstructionEmitter, 'model', phetioID, TSim, SIM_STARTED,
      function( value ) {
        return {
          sessionID: value.sessionID,
          repoName: value.repoName,
          simName: value.simName,
          simVersion: value.simVersion,
          simURL: value.url,
          userAgent: window.navigator.userAgent,
          randomSeed: value.randomSeed,
          extraMetadata: window.simStartedMetadata,
          provider: 'PhET Interactive Simulations, University of Colorado Boulder' // See #137
        };
      } );

    // Store a reference to the sim so that subsequent calls will be simpler.  PhET-iO only works with a single sim.
    phetio.sim = sim;
    sim.endedSimConstructionEmitter.addListener( function() {

      // TODO: Can these be coalesced?
      SimIFrameAPI.triggerSimInitialized();
      phetio.simulationStarted();
    } );
  }

  phetioInherit( TObject, 'TSim', TSim, {

    disableRequestAnimationFrame: {
      returnType: TVoid,
      parameterTypes: [],
      implementation: function() {
        this.instance.disableRequestAnimationFrame();
      },
      documentation: 'Prevents the simulation from animating/updating'
    },

    addEventListener: {
      returnType: TVoid,
      parameterTypes: [ TString, TFunctionWrapper( TVoid, [ TString, TFunctionWrapper( TVoid, [] ) ] ) ],
      implementation: function( eventName, listener ) {
        this.instance.onStatic( eventName, listener );
      },
      documentation: 'Add an event listener to the sim instance'
    },

    getScreenshotDataURL: {
      returnType: TString,
      parameterTypes: [],
      implementation: function() {
        return window.phet.joist.ScreenshotGenerator.generateScreenshot( this.instance );
      },
      documentation: 'Gets a base64 representation of a screenshot of the simulation as a data url'
    }
  }, {
    documentation: 'The type for the simulation instance',
    events: [
      SIM_STARTED
    ]
  } );

  phetioNamespace.register( 'TSim', TSim );

  return TSim;
} );
<|endoftext|>


<commit_before>define(['js/ui/VirtualItemsView'], function (VirtualItemsView) {

    var AUTO = "auto";

    return VirtualItemsView.inherit('js.ui.TileListClass', {

        defaults: {
            heightUpdatePolicy: 'both',
            widthUpdatePolicy: 'both',
            width: null,
            scrollContainerClass: "",

            minItemSize: 100,
            maxItemSize: 150,

            itemWidth: AUTO,
            itemHeight: AUTO,

            rows: AUTO,
            cols: AUTO,

            // calculates itemHeight, itemWidth if set to AUTO depending on the scrollDirection
            aspectRatio: 1,

            horizontalGap: 10,
            verticalGap: 10

        },

        _commitChangedAttributes: function ($) {

            if (this._hasSome($, ["itemWidth", "itemHeight", "aspectRation", "width", "height", "verticalGap", "horizontalGap"])) {

                var cols = this.$.cols,
                    rows = this.$.rows,
                    width = this.$.width,
                    height = this.$.height,
                    horizontalGap = this.$.horizontalGap,
                    verticalGap = this.$.verticalGap,
                    itemWidth = this.$.itemWidth,
                    itemHeight = this.$.itemHeight,
                    aspectRatio = this.$.aspectRatio,
                    setValues = true;

                if (this.$.scrollDirection === VirtualItemsView.SCROLL_DIRECTION_VERTICAL) {

                    if (cols === AUTO) {

                        if (itemWidth === AUTO) {
                            var minCols = (width - horizontalGap ) / (this.$.minItemSize + horizontalGap);
                            var maxCols = (width - horizontalGap ) / (this.$.maxItemSize + horizontalGap);
                            cols = Math.round((minCols + maxCols) / 2);
                        } else {
                            cols = Math.floor((width - horizontalGap) / (itemWidth + horizontalGap));
                        }
                    }

                    if (itemWidth === AUTO) {
                        itemWidth = Math.floor((width - (cols - 1) * horizontalGap) / cols);
                    }

                    if (itemHeight === AUTO) {
                        itemHeight = itemWidth * aspectRatio;
                    }
                } else if (this.$.scrollDirection === VirtualItemsView.SCROLL_DIRECTION_HORIZONTAL) {
                    if (rows === AUTO) {
                        if (itemHeight === AUTO) {
                            var minRows = (height - verticalGap ) / (this.$.minItemSize + verticalGap);
                            var maxRows = (height - verticalGap ) / (this.$.maxItemSize + verticalGap);
                            rows = Math.round((minRows + maxRows) / 2);
                        } else {
                            rows = Math.floor((height - horizontalGap) / (itemHeight + verticalGap));
                        }
                    }

                    if (itemHeight === AUTO) {
                        itemHeight = Math.floor((height - (rows - 1) * verticalGap) / rows);
                    }

                    if (itemWidth === AUTO) {
                        itemWidth = itemHeight * aspectRatio;
                    }
                } else {
                    setValues = false;
                }

                setValues && this.set({
                    _itemHeight: itemHeight,
                    _itemWidth: itemWidth,
                    _cols: cols,
                    _rows: rows
                });
            }

            this.callBase();
        },

        _createRenderer: function (attributes) {
            attributes = attributes || {};
            attributes.$dataItem = null;

            var ret,
                container = this._createRenderContainer(attributes, this),
                children = this.$templates['renderer'].createComponents({
                    $dataItem: null,
                    item: "{$dataItem.data}"
                });

            if (container) {
                // add all children to it
                for (var i = 0; i < children.length; i++) {
                    children[i].$classAttributes.push("item");
                    container.addChild(children[i]);

                }
                container.bind('change', function (e) {
                    var attributes = e.$,
                        child;
                    for (var i = 0; i < children.length; i++) {
                        child = children[i];
                        child.set({
                            $dataItem: attributes.$dataItem || child.$.$dataItem
                        });
                    }
                });
                ret = container;
            } else {
                ret = children[0];
            }

            ret && ret.set("position", "absolute");

            return ret;
        },

        _createRenderContainer: function (attributes, parentScope) {
            var template = this.$templates['rendererContainer'];

            if (template) {
                var container = (template.createComponents(attributes, parentScope)[0]);
                container.$classAttributes.push('item');
                return container;
            }

            return null;
        }
    });

});<commit_msg>fixed $classAttributes setting in TileList<commit_after>define(['js/ui/VirtualItemsView'], function (VirtualItemsView) {

    var AUTO = "auto";

    return VirtualItemsView.inherit('js.ui.TileListClass', {

        defaults: {
            heightUpdatePolicy: 'both',
            widthUpdatePolicy: 'both',
            width: null,
            scrollContainerClass: "",

            minItemSize: 100,
            maxItemSize: 150,

            itemWidth: AUTO,
            itemHeight: AUTO,

            rows: AUTO,
            cols: AUTO,

            // calculates itemHeight, itemWidth if set to AUTO depending on the scrollDirection
            aspectRatio: 1,

            horizontalGap: 10,
            verticalGap: 10

        },

        _commitChangedAttributes: function ($) {

            if (this._hasSome($, ["itemWidth", "itemHeight", "aspectRation", "width", "height", "verticalGap", "horizontalGap"])) {

                var cols = this.$.cols,
                    rows = this.$.rows,
                    width = this.$.width,
                    height = this.$.height,
                    horizontalGap = this.$.horizontalGap,
                    verticalGap = this.$.verticalGap,
                    itemWidth = this.$.itemWidth,
                    itemHeight = this.$.itemHeight,
                    aspectRatio = this.$.aspectRatio,
                    setValues = true;

                if (this.$.scrollDirection === VirtualItemsView.SCROLL_DIRECTION_VERTICAL) {

                    if (cols === AUTO) {

                        if (itemWidth === AUTO) {
                            var minCols = (width - horizontalGap ) / (this.$.minItemSize + horizontalGap);
                            var maxCols = (width - horizontalGap ) / (this.$.maxItemSize + horizontalGap);
                            cols = Math.round((minCols + maxCols) / 2);
                        } else {
                            cols = Math.floor((width - horizontalGap) / (itemWidth + horizontalGap));
                        }
                    }

                    if (itemWidth === AUTO) {
                        itemWidth = Math.floor((width - (cols - 1) * horizontalGap) / cols);
                    }

                    if (itemHeight === AUTO) {
                        itemHeight = itemWidth * aspectRatio;
                    }
                } else if (this.$.scrollDirection === VirtualItemsView.SCROLL_DIRECTION_HORIZONTAL) {
                    if (rows === AUTO) {
                        if (itemHeight === AUTO) {
                            var minRows = (height - verticalGap ) / (this.$.minItemSize + verticalGap);
                            var maxRows = (height - verticalGap ) / (this.$.maxItemSize + verticalGap);
                            rows = Math.round((minRows + maxRows) / 2);
                        } else {
                            rows = Math.floor((height - horizontalGap) / (itemHeight + verticalGap));
                        }
                    }

                    if (itemHeight === AUTO) {
                        itemHeight = Math.floor((height - (rows - 1) * verticalGap) / rows);
                    }

                    if (itemWidth === AUTO) {
                        itemWidth = itemHeight * aspectRatio;
                    }
                } else {
                    setValues = false;
                }

                setValues && this.set({
                    _itemHeight: itemHeight,
                    _itemWidth: itemWidth,
                    _cols: cols,
                    _rows: rows
                });
            }

            this.callBase();
        },

        _createRenderer: function (attributes) {
            attributes = attributes || {};
            attributes.$dataItem = null;

            var ret,
                container = this._createRenderContainer(attributes, this),
                children = this.$templates['renderer'].createComponents({
                    $dataItem: null,
                    item: "{$dataItem.data}"
                });

            if (container) {
                // add all children to it
                var child;
                for (var i = 0; i < children.length; i++) {
                    child = children[i];
                    child.$classAttributes = child.$classAttributes || [];
                    child.$classAttributes.push("item");
                    container.addChild(child);

                }
                container.bind('change', function (e) {
                    var attributes = e.$,
                        child;
                    for (var i = 0; i < children.length; i++) {
                        child = children[i];
                        child.set({
                            $dataItem: attributes.$dataItem || child.$.$dataItem
                        });
                    }
                });
                ret = container;
            } else {
                ret = children[0];
            }

            ret && ret.set("position", "absolute");

            return ret;
        },

        _createRenderContainer: function (attributes, parentScope) {
            var template = this.$templates['rendererContainer'];

            if (template) {
                var container = (template.createComponents(attributes, parentScope)[0]);
                container.$classAttributes.push('item');
                return container;
            }

            return null;
        }
    });

});<|endoftext|>


<commit_before>define([
  'jquery',
  'underscore',
  'backbone',
  'text!templates/style/page.html',
  'less',
  'config',
  'pagedown',
  'libs/marked/marked',
  'libs/highlight/highlight',
  'libs/parseuri/parseuri',
  'libs/waypoints/waypoints'
], function($, _, Backbone, stylePageTemplate, less, config, Pagedown, marked, hljs, parseuri, waypoints){
  var StylePage = Backbone.View.extend({
    el: '.kalei-style-page',
    render: function () {
      var that = this, $sheet;

      // update menu to indicate what's being viewed
        $('a.kalei-styleguide-menu-link').removeClass('active');
        $('[href="' + window.location.hash + '"]').addClass('active');
        if(window.location.hash === '') {
          $('.js-kalei-home').addClass('active');
        }

      // determine the URL to the style we're currently viewing
      var styleUrl, isLess;
      if(this.options.style === null) {
        this.options.style = config.css_path.substr(config.css_path.lastIndexOf('/')+1);
      }
      if(this.options.style.substr(0,1) === '/') {
        // non relative
        var configDir = config.css_path.substr(0, config.css_path.lastIndexOf('/'));
        var pUrl = parseuri(configDir);
        styleUrl = pUrl.protocol + '://' + pUrl.host + (pUrl.port === '' ? '' : ':'+ pUrl) + this.options.style;
      } else {
        var configDir = config.css_path.substr(0, config.css_path.lastIndexOf('/'));
        styleUrl = configDir + '/' + this.options.style;
      }

      isLess = this.options.style.match(/\.less$/i) !== null;

      // init the LESS parser
      var parser = new(less.Parser)({
			paths: [configDir + '/', './'], 		// Specify search paths for @import directives
			filename: config.css_path.substr(config.css_path.lastIndexOf('/')+1)
		});

      // render all the CSS we need to deal with

      if (isLess) {
      	$sheet = $('<link rel="stylesheet/less" href="' + config.css_path + '" />')
		$('head').append($sheet);
		less.sheets.push($sheet[0]);
		less.refresh(true);
      } else {
      	$sheet = $('<link rel="stylesheet" href="' + config.css_path + '" />')
		$('head').append($sheet);
      }

      // parse it for demo markup and render to the page
	   require(['text!'+ styleUrl], function (stylesheet){

        marked.setOptions({ sanitize: false, gfm: true });

		var blocks = [],
	        currentBlock = {
	          comments: [],
	          css: ''
	        },
        	headings = [];

	 	parser.parse(stylesheet, function(err, tree) {
			if (err) { return console.error(err); }

			// parse comments with MarkDown
			_.each(tree.rules, function(rule) {
				if (rule.value !== undefined && rule.rules === undefined && !rule.variable) {
					var comment = rule.value;

					// skip single-line comments
					if (comment.substr(0, 2) == '//') {
						return;
					}

		            comment = comment.replace('/*', '');
		            comment = comment.replace('*/', '');

		            var comments = marked.lexer(comment);
		            _.each(comments, function (comment) {

		              if(comment.type === 'heading' && comment.depth <= 2) {
		                headings.push(comment.text);
		                currentBlock.css = css_beautify(currentBlock.css);
		                if(currentBlock.comments.length !== 0 || currentBlock.css !== '') {
		                  currentBlock.comments = marked.parser(currentBlock.comments);
		                  blocks.push(_.extend({}, currentBlock));
		                  currentBlock.comments = [];
		                  currentBlock.css = '';
		                }
		              }
		              if(comment.type === 'code'){
		                currentBlock.comments.push({
		                  type: 'html',
		                  text: '
' + comment.text + '

'
		                })
		              };
		              currentBlock.comments.push(comment);

		            });
				}
			});

			currentBlock.css += tree.toCSS();	// append all CSS to the input
		});

		// draw menu
      	$('.sheet-submenu').slideUp(200);

        var submenu = $('
');
        _.each(headings, function (heading) {
          submenu.append($('
').text(heading));
        });
        $('li:first-child', submenu).addClass('active');
        $('.sheet-submenu', $('[data-sheet="' + that.options.style + '"]')).html(submenu).slideDown(200);

        currentBlock.css = css_beautify(currentBlock.css);
        currentBlock.comments = marked.parser(currentBlock.comments);
        blocks.push(currentBlock);

        // draw page
        $(that.el).html(_.template(stylePageTemplate, {_:_, blocks: blocks, config: config}));

        // syntax highlighting
        $(' code').each(function(i, e) {hljs.highlightBlock(e); });

        $('.kalei-comments-container > .kalei-comments > h2, .kalei-comments-container > .kalei-comments  > h1').waypoint(function(ev) {
          console.log(arguments);
         $('.sheet-submenu li').removeClass('active');
           $('.sheet-submenu li:contains('+$(ev.currentTarget).text()+')').addClass('active');
        }, {
   offset: 20  // middle of the page
});

        $("body").on('click', '.sheet-submenu li', function(ev) {

             $('html, body').animate({
                 scrollTop: $(".kalei-comments h2:contains('"+$(ev.currentTarget).text()+"'),.kalei-comments h1:contains('"+$(ev.currentTarget).text()+"')").offset().top - 20
             }, 200);
         });

         fixie.init();

      });

    }
  });
  return StylePage;
});
<commit_msg>do not render the parsed CSS back to blocks. unnecessary, and not possible in parsed CSS languages since each sheet is loaded separately, without any imports<commit_after>define([
  'jquery',
  'underscore',
  'backbone',
  'text!templates/style/page.html',
  'less',
  'config',
  'pagedown',
  'libs/marked/marked',
  'libs/highlight/highlight',
  'libs/parseuri/parseuri',
  'libs/waypoints/waypoints'
], function($, _, Backbone, stylePageTemplate, less, config, Pagedown, marked, hljs, parseuri, waypoints){
  var StylePage = Backbone.View.extend({
    el: '.kalei-style-page',
    render: function () {
      var that = this, $sheet;

      // update menu to indicate what's being viewed
        $('a.kalei-styleguide-menu-link').removeClass('active');
        $('[href="' + window.location.hash + '"]').addClass('active');
        if(window.location.hash === '') {
          $('.js-kalei-home').addClass('active');
        }

      // determine the URL to the style we're currently viewing
      var styleUrl, isLess;
      if(this.options.style === null) {
        this.options.style = config.css_path.substr(config.css_path.lastIndexOf('/')+1);
      }
      if(this.options.style.substr(0,1) === '/') {
        // non relative
        var configDir = config.css_path.substr(0, config.css_path.lastIndexOf('/'));
        var pUrl = parseuri(configDir);
        styleUrl = pUrl.protocol + '://' + pUrl.host + (pUrl.port === '' ? '' : ':'+ pUrl) + this.options.style;
      } else {
        var configDir = config.css_path.substr(0, config.css_path.lastIndexOf('/'));
        styleUrl = configDir + '/' + this.options.style;
      }

      isLess = this.options.style.match(/\.less$/i) !== null;

      // init the LESS parser
      var parser = new(less.Parser)({
			paths: [configDir + '/', './'], 		// Specify search paths for @import directives
			filename: config.css_path.substr(config.css_path.lastIndexOf('/')+1)
		});

      // render all the CSS we need to deal with

      if (isLess) {
      	$sheet = $('<link rel="stylesheet/less" href="' + config.css_path + '" />')
		$('head').append($sheet);
		less.sheets.push($sheet[0]);
		less.refresh(true);
      } else {
      	$sheet = $('<link rel="stylesheet" href="' + config.css_path + '" />')
		$('head').append($sheet);
      }

      // parse it for demo markup and render to the page
	   require(['text!'+ styleUrl], function (stylesheet){

        marked.setOptions({ sanitize: false, gfm: true });

		var blocks = [],
	        currentBlock = {
	          comments: [],
	          css: ''
	        },
        	headings = [];

	 	parser.parse(stylesheet, function(err, tree) {
			if (err) { return console.error(err); }

			// parse comments with MarkDown
			_.each(tree.rules, function(rule) {
				if (rule.value !== undefined && rule.rules === undefined && !rule.variable) {
					var comment = rule.value;

					// skip single-line comments
					if (comment.substr(0, 2) == '//') {
						return;
					}

		            comment = comment.replace('/*', '');
		            comment = comment.replace('*/', '');

		            var comments = marked.lexer(comment);
		            _.each(comments, function (comment) {

		              if(comment.type === 'heading' && comment.depth <= 2) {
		                headings.push(comment.text);
		                currentBlock.css = css_beautify(currentBlock.css);
		                if(currentBlock.comments.length !== 0 || currentBlock.css !== '') {
		                  currentBlock.comments = marked.parser(currentBlock.comments);
		                  blocks.push(_.extend({}, currentBlock));
		                  currentBlock.comments = [];
		                  currentBlock.css = '';
		                }
		              }
		              if(comment.type === 'code'){
		                currentBlock.comments.push({
		                  type: 'html',
		                  text: '
' + comment.text + '

'
		                })
		              };
		              currentBlock.comments.push(comment);

		            });
				}
			});
		});

		// draw menu
      	$('.sheet-submenu').slideUp(200);

        var submenu = $('
');
        _.each(headings, function (heading) {
          submenu.append($('
').text(heading));
        });
        $('li:first-child', submenu).addClass('active');
        $('.sheet-submenu', $('[data-sheet="' + that.options.style + '"]')).html(submenu).slideDown(200);

        currentBlock.css = css_beautify(currentBlock.css);
        currentBlock.comments = marked.parser(currentBlock.comments);
        blocks.push(currentBlock);

        // draw page
        $(that.el).html(_.template(stylePageTemplate, {_:_, blocks: blocks, config: config}));

        // syntax highlighting
        $(' code').each(function(i, e) {hljs.highlightBlock(e); });

        $('.kalei-comments-container > .kalei-comments > h2, .kalei-comments-container > .kalei-comments  > h1').waypoint(function(ev) {
          console.log(arguments);
         $('.sheet-submenu li').removeClass('active');
           $('.sheet-submenu li:contains('+$(ev.currentTarget).text()+')').addClass('active');
        }, {
   offset: 20  // middle of the page
});

        $("body").on('click', '.sheet-submenu li', function(ev) {

             $('html, body').animate({
                 scrollTop: $(".kalei-comments h2:contains('"+$(ev.currentTarget).text()+"'),.kalei-comments h1:contains('"+$(ev.currentTarget).text()+"')").offset().top - 20
             }, 200);
         });

         fixie.init();

      });

    }
  });
  return StylePage;
});
<|endoftext|>