<commit_before>function showTaskOverview(groupNum){

	var task_id = getEventJSONIndex(groupNum);
	var eventObj = flashTeamsJSON["events"][task_id];
	var title = eventObj["title"];

	//uniq_u is null for author, we use this to decide whether to show the edit link next to project overview
	var uniq_u=getParameterByName('uniq');

	//modal label
	var label = title;
	$('#task_modal_Label').html(label);

	//modal content
	//var taskOverviewContent = '

' + description + '

';
	var taskOverviewContent = getTaskOverviewContent(groupNum);
	//$('#taskOverview').html(taskOverviewContent);
	$('#task-text').html(taskOverviewContent);

	if(in_progress != true && (uniq_u == "" || memberType == "pc" || memberType == "client") ) {
		$("#edit-save-task").css('display', '');
		$("#edit-save-task").attr('onclick', 'editTaskOverview(true,'+groupNum+')');
		$("#edit-save-task").html('Edit');

	}
	else{
		$("#edit-save-task").css('display', 'none');
		$("#hire-task").css('display','none');
		$("#delete").css('display','none');
	}
}

function editTaskOverview(popover,groupNum){

	var task_id = getEventJSONIndex(groupNum);
	var eventObj = flashTeamsJSON["events"][task_id];
	var title = eventObj["title"];

	if(popover==true){
		$('#task-edit-link').hide();

		//label
		label = '<input type ="text" name="eventName" id="eventName' + '" placeholder="'+title+'" >'
		$('#task_modal_Label').html(label);

        //content
        var taskOverviewForm = getTaskOverviewForm(groupNum);
		/*var taskOverviewForm = '<form name="taskOverviewForm" id="taskOverviewForm" style="margin-bottom: 5px;">'
					+'<textarea type="text"" id="descriptionInput" rows="6" placeholder="Task description ...">'+description+'</textarea>'
					+ 'Cancel'
					+'</form>';*/
		$('#task-text').html(taskOverviewForm);

		$("#edit-save-task").attr('onclick', 'saveTaskOverview('+groupNum+')');
		$("#edit-save-task").html('Save');
	}

}

function getTaskOverviewForm(groupNum){

var task_id = getEventJSONIndex(groupNum);
	var eventObj = flashTeamsJSON["events"][task_id];

	 var totalMinutes = eventObj["duration"];
    var groupNum = eventObj["id"];
    var title = eventObj["title"];
    var startHr = eventObj["startHr"];
    var startMin = eventObj["startMin"];
    var notes = eventObj["notes"];
    var inputs = eventObj["inputs"];
    if(!inputs) inputs = "";
    var outputs = eventObj["outputs"];
    if(!outputs) outputs = "";
    var numHours = Math.floor(totalMinutes/60);
    var minutesLeft = totalMinutes%60;
    var dri_id = eventObj.dri;
    var PC_id = eventObj.pc;
/*'<form name="taskOverviewForm" id="taskOverviewForm" style="margin-bottom: 5px;">'
					+'<textarea type="text"" id="descriptionInput" rows="6" placeholder="Task description ...">'+description+'</textarea>'
					+ 'Cancel'
					+'</form>';*/

var form ='<form name="taskOverviewForm" id="taskOverviewForm" style="margin-bottom: 5px;">'
        + '
'
        + 'Event Start:
'
        + 'Hours: <input type="number" id="startHr" placeholder="' + startHr
            + '" min="0" style="width:35px">         '
        + 'Minutes: <input type="number" id="startMin" placeholder="' + startMin
            + '" min="0" step="15" max="45" style="width:35px">
'
        + 'Total Runtime:
'
        + 'Hours: <input type = "number" id="hours" placeholder="'
            +numHours+'" min="0" style="width:35px"/>         '
        + 'Minutes: <input type = "number" id = "minutes" placeholder="'+minutesLeft
            +'" style="width:35px" min="0" step="15" max="45"/>
'
        + 'Members

'
            + writeEventMembers(eventObj)  +'
'

        + '
Project Coordinator
<select class="pcInput"'
            +' name="pcName" id="pcEvent"'
			+ 'onchange="getPC('+groupNum + ')">'+ writePCMembers(groupNum,PC_id) +'</select>'

        + '
Directly-Responsible Individual
<select class="driInput"'
            +' name="driName" id="driEvent"'
			+ 'onchange="getDRI('+groupNum + ')">'+ writeDRIMembers(groupNum,dri_id) +'</select>'

        + '
Notes:
<textarea rows="3" id="notes">' + notes + '</textarea>'
        + '
<input type="text" value="' + inputs + '" placeholder="Add input" id="inputs" />
'
        + '
<input type="text" value="' + outputs + '" placeholder="Add output" id="outputs" />

'
        + 'Cancel'
        + '</form>';

        return form;

}

function getTaskOverviewContent(groupNum){
	var task_id = getEventJSONIndex(groupNum);
	var ev = flashTeamsJSON["events"][task_id];

    var hrs = Math.floor(ev.duration/60);
    var mins = ev.duration % 60;

    var content = 'Event Start:
'
        + ev.startHr + ':'
        + ev.startMin.toFixed(0) + '
'
        +'Total Runtime:
'
        + hrs + ' hrs ' + mins + ' mins
';

    if(ev.inputs) {
        content += 'Inputs:
';
        var inputs = ev.inputs.split(",");
        for(var i=0;i<inputs.length;i++){
            content += inputs[i];
            content += "
";
        }
    }

    if(ev.outputs) {
        content += 'Outputs:
';
        var outputs = ev.outputs.split(",");
        for(var i=0;i<outputs.length;i++){
            content += outputs[i];
            content += "
";
        }
    }

    var num_members = ev.members.length;
    if(num_members > 0){
        content += 'Members:
';
        for (var j=0;j<num_members;j++){
            var member = getMemberById(ev.members[j]);
            content += member.role;
            content += '
';
        }
    }

    if (ev.pc != "" && ev.pc != undefined){
        var pc_id = parseInt (ev.pc);
        var mem = null;

        for (var i = 0; i<flashTeamsJSON["members"].length; i++){

            if(flashTeamsJSON["members"][i].id == pc_id){
                mem = flashTeamsJSON["members"][i].role;
                break;
            }
        }
          if(mem && mem != undefined){
            content += 'Project Coordinator:
';
            content += mem;
            content += '
';
        }
    }

     if (ev.dri != "" && ev.dri != undefined){
        var dri_id = parseInt (ev.dri);
        var mem = null;

        for (var i = 0; i<flashTeamsJSON["members"].length; i++){

            if(flashTeamsJSON["members"][i].id == dri_id){
                mem = flashTeamsJSON["members"][i].role;
                break;
            }
        }

        if(mem && mem != undefined){
            content += 'Directly-Responsible Individual:
';
            content += mem;
            content += '
';
        }
    }

    if (ev.content != ""){
        content += 'Notes:
';
        content += ev.notes;
        content += '
';
    }

    return content;
}

function saveTaskOverview(groupNum){
	var task_id = getEventJSONIndex(groupNum);
	var ev = flashTeamsJSON["events"][task_id];

    if($("#eventName").val() !="")
        ev.title = $("#eventName").val();

    //Get Start Time
    var startHour = $("#startHr").val();
    if (startHour == "") startHour = parseInt($("#startHr").attr("placeholder"));
    var startMin = $("#startMin").val();

    if (startMin == "") startMin = parseInt($("#startMin").attr("placeholder"));
    //newX
    startHour = parseInt(startHour);
    startMin = parseInt(startMin);
    var newX = (startHour * 100) + (startMin/15*25);
    newX = newX - (newX%(STEP_WIDTH)) - DRAGBAR_WIDTH/2;

    var eventNotes = $("#notes").val();
    var driId = getDRI(groupNum);
    var pcId = getPC(groupNum);

    var indexOfJSON = getEventJSONIndex(groupNum);
    var ev = flashTeamsJSON["events"][indexOfJSON];

    removeAllMemberCircles(ev);

    //Update members of event
    flashTeamsJSON["events"][indexOfJSON].members = [];
    for (var i = 0; i<flashTeamsJSON["members"].length; i++) {
        var member = flashTeamsJSON["members"][i];
        var memberId = member.id;
        var checkbox = $("#event" + groupNum + "member" + i + "checkbox")[0];
        if (checkbox == undefined) continue;
        if (checkbox.checked == true) {
            ev.members.push(memberId); //Update JSON
        }
    }

    //Update width
    var newHours = $("#hours").val();
    var newMin = $("#minutes").val();
    if (newHours == "") newHours = parseInt($("#hours")[0].placeholder);
    if (newMin == "") newMin = parseInt($("#minutes" )[0].placeholder);
    newMin = Math.round(parseInt(newMin)/15) * 15;

    //cannot have events shorter than 30 minutes
    if (newHours == 0 && newMin == 15){
        newMin = 30;
    }
    var newWidth = (newHours * 100) + (newMin/15*25);

    //Update JSON
    var indexOfJSON = getEventJSONIndex(groupNum);

    ev.notes = eventNotes;
    ev.dri = driId;
    ev.pc = pcId;
    ev.startHr = parseInt(startHour);
    ev.startMin = Math.round(parseInt(startMin)/15) * 15;
    ev.startTime = ev.startHr*60 + ev.startMin;
    ev.duration = durationForWidth(newWidth);
    ev.x = newX;
    ev.inputs = $('#inputs').val();
    ev.outputs = $('#outputs' ).val();

    drawEvent(ev, 0);

    updateStatus();
    //showTaskOverview(groupNum);
      $('#task_modal').modal('hide');
}
<commit_msg>fixed input/output pills<commit_after>function showTaskOverview(groupNum){

	var task_id = getEventJSONIndex(groupNum);
	var eventObj = flashTeamsJSON["events"][task_id];
	var title = eventObj["title"];

	//uniq_u is null for author, we use this to decide whether to show the edit link next to project overview
	var uniq_u=getParameterByName('uniq');

	//modal label
	var label = title;
	$('#task_modal_Label').html(label);

	//modal content
	//var taskOverviewContent = '

' + description + '

';
	var taskOverviewContent = getTaskOverviewContent(groupNum);
	//$('#taskOverview').html(taskOverviewContent);
	$('#task-text').html(taskOverviewContent);

	if(in_progress != true && (uniq_u == "" || memberType == "pc" || memberType == "client") ) {
		$("#edit-save-task").css('display', '');
		$("#edit-save-task").attr('onclick', 'editTaskOverview(true,'+groupNum+')');
		$("#edit-save-task").html('Edit');

	}
	else{
		$("#edit-save-task").css('display', 'none');
		$("#hire-task").css('display','none');
		$("#delete").css('display','none');
	}

}

function editTaskOverview(popover,groupNum){

	var task_id = getEventJSONIndex(groupNum);
	var eventObj = flashTeamsJSON["events"][task_id];
	var title = eventObj["title"];

	if(popover==true){
		$('#task-edit-link').hide();

		//label
		label = '<input type ="text" name="eventName" id="eventName' + '" placeholder="'+title+'" >'
		$('#task_modal_Label').html(label);

        //content
        var taskOverviewForm = getTaskOverviewForm(groupNum);
		/*var taskOverviewForm = '<form name="taskOverviewForm" id="taskOverviewForm" style="margin-bottom: 5px;">'
					+'<textarea type="text"" id="descriptionInput" rows="6" placeholder="Task description ...">'+description+'</textarea>'
					+ 'Cancel'
					+'</form>';*/
		$('#task-text').html(taskOverviewForm);

		$("#edit-save-task").attr('onclick', 'saveTaskOverview('+groupNum+')');
		$("#edit-save-task").html('Save');

        $("#inputs").tagsinput();
        $("#outputs").tagsinput();
	}

}

function getTaskOverviewForm(groupNum){

var task_id = getEventJSONIndex(groupNum);
	var eventObj = flashTeamsJSON["events"][task_id];

	 var totalMinutes = eventObj["duration"];
    var groupNum = eventObj["id"];
    var title = eventObj["title"];
    var startHr = eventObj["startHr"];
    var startMin = eventObj["startMin"];
    var notes = eventObj["notes"];
    var inputs = eventObj["inputs"];
    if(!inputs) inputs = "";
    var outputs = eventObj["outputs"];
    if(!outputs) outputs = "";
    var numHours = Math.floor(totalMinutes/60);
    var minutesLeft = totalMinutes%60;
    var dri_id = eventObj.dri;
    var PC_id = eventObj.pc;
/*'<form name="taskOverviewForm" id="taskOverviewForm" style="margin-bottom: 5px;">'
					+'<textarea type="text"" id="descriptionInput" rows="6" placeholder="Task description ...">'+description+'</textarea>'
					+ 'Cancel'
					+'</form>';*/

var form ='<form name="taskOverviewForm" id="taskOverviewForm" style="margin-bottom: 5px;">'
        + '
'
        + 'Event Start:
'
        + 'Hours: <input type="number" id="startHr" placeholder="' + startHr
            + '" min="0" style="width:35px">         '
        + 'Minutes: <input type="number" id="startMin" placeholder="' + startMin
            + '" min="0" step="15" max="45" style="width:35px">
'
        + 'Total Runtime:
'
        + 'Hours: <input type = "number" id="hours" placeholder="'
            +numHours+'" min="0" style="width:35px"/>         '
        + 'Minutes: <input type = "number" id = "minutes" placeholder="'+minutesLeft
            +'" style="width:35px" min="0" step="15" max="45"/>
'
        + 'Members

'
            + writeEventMembers(eventObj)  +'
'

        + '
Project Coordinator
<select class="pcInput"'
            +' name="pcName" id="pcEvent"'
			+ 'onchange="getPC('+groupNum + ')">'+ writePCMembers(groupNum,PC_id) +'</select>'

        + '
Directly-Responsible Individual
<select class="driInput"'
            +' name="driName" id="driEvent"'
			+ 'onchange="getDRI('+groupNum + ')">'+ writeDRIMembers(groupNum,dri_id) +'</select>'

        + '
Notes:
<textarea rows="3" id="notes">' + notes + '</textarea>'
        + '
<input type="text" value="' + inputs + '" placeholder="Add input" id="inputs" />
'
        + '
<input type="text" value="' + outputs + '" placeholder="Add output" id="outputs" />

'
        + 'Cancel'
        + '</form>';

        return form;

}

function getTaskOverviewContent(groupNum){
	var task_id = getEventJSONIndex(groupNum);
	var ev = flashTeamsJSON["events"][task_id];

    var hrs = Math.floor(ev.duration/60);
    var mins = ev.duration % 60;

    var content = 'Event Start:
'
        + ev.startHr + ':'
        + ev.startMin.toFixed(0) + '
'
        +'Total Runtime:
'
        + hrs + ' hrs ' + mins + ' mins
';

    if(ev.inputs) {
        content += 'Inputs:
';
        var inputs = ev.inputs.split(",");
        for(var i=0;i<inputs.length;i++){
            content += inputs[i];
            content += "
";
        }
    }

    if(ev.outputs) {
        content += 'Outputs:
';
        var outputs = ev.outputs.split(",");
        for(var i=0;i<outputs.length;i++){
            content += outputs[i];
            content += "
";
        }
    }

    var num_members = ev.members.length;
    if(num_members > 0){
        content += 'Members:
';
        for (var j=0;j<num_members;j++){
            var member = getMemberById(ev.members[j]);
            content += member.role;
            content += '
';
        }
    }

    if (ev.pc != "" && ev.pc != undefined){
        var pc_id = parseInt (ev.pc);
        var mem = null;

        for (var i = 0; i<flashTeamsJSON["members"].length; i++){

            if(flashTeamsJSON["members"][i].id == pc_id){
                mem = flashTeamsJSON["members"][i].role;
                break;
            }
        }
          if(mem && mem != undefined){
            content += 'Project Coordinator:
';
            content += mem;
            content += '
';
        }
    }

     if (ev.dri != "" && ev.dri != undefined){
        var dri_id = parseInt (ev.dri);
        var mem = null;

        for (var i = 0; i<flashTeamsJSON["members"].length; i++){

            if(flashTeamsJSON["members"][i].id == dri_id){
                mem = flashTeamsJSON["members"][i].role;
                break;
            }
        }

        if(mem && mem != undefined){
            content += 'Directly-Responsible Individual:
';
            content += mem;
            content += '
';
        }
    }

    if (ev.content != ""){
        content += 'Notes:
';
        content += ev.notes;
        content += '
';
    }

    return content;
}

function saveTaskOverview(groupNum){
	var task_id = getEventJSONIndex(groupNum);
	var ev = flashTeamsJSON["events"][task_id];

    if($("#eventName").val() !="")
        ev.title = $("#eventName").val();

    //Get Start Time
    var startHour = $("#startHr").val();
    if (startHour == "") startHour = parseInt($("#startHr").attr("placeholder"));
    var startMin = $("#startMin").val();

    if (startMin == "") startMin = parseInt($("#startMin").attr("placeholder"));
    //newX
    startHour = parseInt(startHour);
    startMin = parseInt(startMin);
    var newX = (startHour * 100) + (startMin/15*25);
    newX = newX - (newX%(STEP_WIDTH)) - DRAGBAR_WIDTH/2;

    var eventNotes = $("#notes").val();
    var driId = getDRI(groupNum);
    var pcId = getPC(groupNum);

    var indexOfJSON = getEventJSONIndex(groupNum);
    var ev = flashTeamsJSON["events"][indexOfJSON];

    removeAllMemberCircles(ev);

    //Update members of event
    flashTeamsJSON["events"][indexOfJSON].members = [];
    for (var i = 0; i<flashTeamsJSON["members"].length; i++) {
        var member = flashTeamsJSON["members"][i];
        var memberId = member.id;
        var checkbox = $("#event" + groupNum + "member" + i + "checkbox")[0];
        if (checkbox == undefined) continue;
        if (checkbox.checked == true) {
            ev.members.push(memberId); //Update JSON
        }
    }

    //Update width
    var newHours = $("#hours").val();
    var newMin = $("#minutes").val();
    if (newHours == "") newHours = parseInt($("#hours")[0].placeholder);
    if (newMin == "") newMin = parseInt($("#minutes" )[0].placeholder);
    newMin = Math.round(parseInt(newMin)/15) * 15;

    //cannot have events shorter than 30 minutes
    if (newHours == 0 && newMin == 15){
        newMin = 30;
    }
    var newWidth = (newHours * 100) + (newMin/15*25);

    //Update JSON
    var indexOfJSON = getEventJSONIndex(groupNum);

    ev.notes = eventNotes;
    ev.dri = driId;
    ev.pc = pcId;
    ev.startHr = parseInt(startHour);
    ev.startMin = Math.round(parseInt(startMin)/15) * 15;
    ev.startTime = ev.startHr*60 + ev.startMin;
    ev.duration = durationForWidth(newWidth);
    ev.x = newX;
    ev.inputs = $('#inputs').val();
    ev.outputs = $('#outputs' ).val();

    drawEvent(ev, 0);

    updateStatus();
    //showTaskOverview(groupNum);
      $('#task_modal').modal('hide');
}
<|endoftext|>


<commit_before>asynctest(
  'Browser Test: ui.ButtonsTest',

  [
    'ephox.agar.api.GeneralSteps',
    'ephox.agar.api.Logger',
    'ephox.agar.api.Mouse',
    'ephox.agar.api.Pipeline',
    'ephox.agar.api.Step',
    'ephox.alloy.api.component.Memento',
    'ephox.alloy.api.system.Attachment',
    'ephox.alloy.test.GuiSetup',
    'ephox.sugar.api.node.Body',
    'ephox.sugar.api.properties.Class',
    'ephox.sugar.api.search.Traverse',
    'tinymce.themes.mobile.channels.TinyChannels',
    'tinymce.themes.mobile.test.ui.TestEditor',
    'tinymce.themes.mobile.test.ui.TestStyles',
    'tinymce.themes.mobile.test.ui.TestUi',
    'tinymce.themes.mobile.ui.Buttons',
    'tinymce.themes.mobile.ui.IosRealm'
  ],

  function (
    GeneralSteps, Logger, Mouse, Pipeline, Step, Memento, Attachment, GuiSetup, Body, Class, Traverse, TinyChannels, TestEditor, TestStyles, TestUi, Buttons,
    IosRealm
  ) {
    var success = arguments[arguments.length - 2];
    var failure = arguments[arguments.length - 1];

    var realm = IosRealm();

    var body = Body.body();
    Attachment.attachSystem(body, realm.system());

    // Make toolbar appear
    Class.add(realm.system().element(), 'tinymce-mobile-fullscreen-maximized');

    var doc = Traverse.owner(body);

    TestStyles.addStyles();

    var unload = function () {
      TestStyles.removeStyles();
      Attachment.detachSystem(realm.system());
    };

    var tEditor = TestEditor();

    var memAlpha = Memento.record(
      Buttons.forToolbarCommand(tEditor.editor(), 'alpha')
    );

    var memBeta = Memento.record(
      Buttons.forToolbarStateCommand(tEditor.editor(), 'beta')
    );

    var memGamma = Memento.record(
      Buttons.forToolbarStateAction(tEditor.editor(), 'gamma-class', 'gamma-query', function () {
        tEditor.adder('gamma-action')();
      })
    );

    realm.setToolbarGroups([
      {
        label: 'group1',
        items: [
          memAlpha.asSpec(),
          memBeta.asSpec(),
          memGamma.asSpec()
        ]
      }
    ]);

    var sTestAlpha = GeneralSteps.sequence([
      tEditor.sAssertEq('Initially empty', [ ]),
      TestUi.sClickComponent(realm, memAlpha),
      tEditor.sAssertEq('After clicking on alpha', [
        {
          method: 'execCommand',
          data: {
            'alpha': undefined
          }
        }
      ]),
      tEditor.sClear
    ]);

    var sTestBeta = GeneralSteps.sequence([
      tEditor.sAssertEq('before beta, store is empty', [ ]),
      TestUi.sClickComponent(realm, memBeta),
      tEditor.sAssertEq('After clicking on beta', [
        {
          method: 'execCommand',
          data: {
            'beta': undefined
          }
        }
      ]),
      tEditor.sClear,
      TestUi.sTogglingIs(realm.system(), '.tinymce-mobile-icon-beta', false),
      // Fire a format change
      Step.sync(function () {
        realm.system().broadcastOn([ TinyChannels.formatChanged() ], {
          command: 'beta',
          state: true
        });
      }),
      Logger.t(
        'Checking toggle after broadcasting event for beta',
        TestUi.sTogglingIs(realm.system(), '.tinymce-mobile-icon-beta', true)
      ),
      tEditor.sClear
    ]);

    var sTestGamma = GeneralSteps.sequence([
      tEditor.sAssertEq('before gamma, store is empty', [ ]),
      Mouse.sClickOn(realm.system().element(), '.tinymce-mobile-icon-gamma-class'),
      tEditor.sAssertEq('After clicking on gamma', [ 'gamma-action' ]),
      tEditor.sClear,
      TestUi.sTogglingIs(realm.system(), '.tinymce-mobile-icon-gamma-class', false),
      // Fire a format change
      Step.sync(function () {
        realm.system().broadcastOn([ TinyChannels.formatChanged() ], {
          command: 'gamma-query',
          state: true
        });
      }),
      Logger.t(
        'Checking toggle after broadcasting event for gamma',
        TestUi.sTogglingIs(realm.system(), '.tinymce-mobile-icon-gamma-class', true)
      )
    ]);

    Pipeline.async({}, [
      GuiSetup.mAddStyles(doc, [
        '.tinymce-mobile-icon-alpha:before { content: "ALPHA"; }',
        '.tinymce-mobile-icon-beta:before { content: "BETA"; }',
        '.tinymce-mobile-icon-gamma-class:before { content: "GAMMA"; }'
      ]),
      TestStyles.sWaitForToolstrip(realm),
      sTestAlpha,
      sTestBeta,
      sTestGamma
    ], function () {
      unload(); success();
    }, failure);
  }
);
<commit_msg>TM-93: click component for gamma also<commit_after>asynctest(
  'Browser Test: ui.ButtonsTest',

  [
    'ephox.agar.api.GeneralSteps',
    'ephox.agar.api.Logger',
    'ephox.agar.api.Mouse',
    'ephox.agar.api.Pipeline',
    'ephox.agar.api.Step',
    'ephox.alloy.api.component.Memento',
    'ephox.alloy.api.system.Attachment',
    'ephox.alloy.test.GuiSetup',
    'ephox.sugar.api.node.Body',
    'ephox.sugar.api.properties.Class',
    'ephox.sugar.api.search.Traverse',
    'tinymce.themes.mobile.channels.TinyChannels',
    'tinymce.themes.mobile.test.ui.TestEditor',
    'tinymce.themes.mobile.test.ui.TestStyles',
    'tinymce.themes.mobile.test.ui.TestUi',
    'tinymce.themes.mobile.ui.Buttons',
    'tinymce.themes.mobile.ui.IosRealm'
  ],

  function (
    GeneralSteps, Logger, Mouse, Pipeline, Step, Memento, Attachment, GuiSetup, Body, Class, Traverse, TinyChannels, TestEditor, TestStyles, TestUi, Buttons,
    IosRealm
  ) {
    var success = arguments[arguments.length - 2];
    var failure = arguments[arguments.length - 1];

    var realm = IosRealm();

    var body = Body.body();
    Attachment.attachSystem(body, realm.system());

    // Make toolbar appear
    Class.add(realm.system().element(), 'tinymce-mobile-fullscreen-maximized');

    var doc = Traverse.owner(body);

    TestStyles.addStyles();

    var unload = function () {
      TestStyles.removeStyles();
      Attachment.detachSystem(realm.system());
    };

    var tEditor = TestEditor();

    var memAlpha = Memento.record(
      Buttons.forToolbarCommand(tEditor.editor(), 'alpha')
    );

    var memBeta = Memento.record(
      Buttons.forToolbarStateCommand(tEditor.editor(), 'beta')
    );

    var memGamma = Memento.record(
      Buttons.forToolbarStateAction(tEditor.editor(), 'gamma-class', 'gamma-query', function () {
        tEditor.adder('gamma-action')();
      })
    );

    var sClickAlpha = TestUi.sClickComponent(realm, memAlpha);
    var sClickBeta = TestUi.sClickComponent(realm, memBeta);
    var sClickGamma = TestUi.sClickComponent(realm, memGamma);

    realm.setToolbarGroups([
      {
        label: 'group1',
        items: [
          memAlpha.asSpec(),
          memBeta.asSpec(),
          memGamma.asSpec()
        ]
      }
    ]);

    var sTestAlpha = GeneralSteps.sequence([
      tEditor.sAssertEq('Initially empty', [ ]),
      sClickAlpha,
      tEditor.sAssertEq('After clicking on alpha', [
        {
          method: 'execCommand',
          data: {
            'alpha': undefined
          }
        }
      ]),
      tEditor.sClear
    ]);

    var sTestBeta = GeneralSteps.sequence([
      tEditor.sAssertEq('before beta, store is empty', [ ]),
      sClickBeta,
      tEditor.sAssertEq('After clicking on beta', [
        {
          method: 'execCommand',
          data: {
            'beta': undefined
          }
        }
      ]),
      tEditor.sClear,
      TestUi.sTogglingIs(realm.system(), '.tinymce-mobile-icon-beta', false),
      // Fire a format change
      Step.sync(function () {
        realm.system().broadcastOn([ TinyChannels.formatChanged() ], {
          command: 'beta',
          state: true
        });
      }),
      Logger.t(
        'Checking toggle after broadcasting event for beta',
        TestUi.sTogglingIs(realm.system(), '.tinymce-mobile-icon-beta', true)
      ),
      tEditor.sClear
    ]);

    var sTestGamma = GeneralSteps.sequence([
      tEditor.sAssertEq('before gamma, store is empty', [ ]),
      sClickGamma,
      tEditor.sAssertEq('After clicking on gamma', [ 'gamma-action' ]),
      tEditor.sClear,
      TestUi.sTogglingIs(realm.system(), '.tinymce-mobile-icon-gamma-class', false),
      // Fire a format change
      Step.sync(function () {
        realm.system().broadcastOn([ TinyChannels.formatChanged() ], {
          command: 'gamma-query',
          state: true
        });
      }),
      Logger.t(
        'Checking toggle after broadcasting event for gamma',
        TestUi.sTogglingIs(realm.system(), '.tinymce-mobile-icon-gamma-class', true)
      )
    ]);

    Pipeline.async({}, [
      GuiSetup.mAddStyles(doc, [
        '.tinymce-mobile-icon-alpha:before { content: "ALPHA"; }',
        '.tinymce-mobile-icon-beta:before { content: "BETA"; }',
        '.tinymce-mobile-icon-gamma-class:before { content: "GAMMA"; }'
      ]),
      TestStyles.sWaitForToolstrip(realm),
      sTestAlpha,
      sTestBeta,
      sTestGamma
    ], function () {
      unload(); success();
    }, failure);
  }
);
<|endoftext|>


<commit_before>'use strict';

angular.module('<%=angularAppName%>')
    .config(function ($stateProvider) {
        $stateProvider
            .state('user-management', {
                parent: 'admin',
                url: '/user-management',
                data: {
                    authorities: ['ROLE_ADMIN'],
                    pageTitle: 'user-management.home.title'
                },
                views: {
                    'content@': {
                        templateUrl: 'app/admin/user-management/user-management.html',
                        controller: 'UserManagementController'
                    }
                },
                resolve: {
                    translatePartialLoader: ['$translate', '$translatePartialLoader', function ($translate, $translatePartialLoader) {
                        $translatePartialLoader.addPart('user-management');
                        return $translate.refresh();
                    }]
                }
            })
            .state('user-management-detail', {
                parent: 'admin',
                url: '/user/:login',
                data: {
                    authorities: ['ROLE_ADMIN'],
                    pageTitle: 'user-management.detail.title'
                },
                views: {
                    'content@': {
                        templateUrl: 'app/admin/user-management/user-management-detail.html',
                        controller: 'UserManagementDetailController'
                    }
                },
                resolve: {
                    translatePartialLoader: ['$translate', '$translatePartialLoader', function ($translate, $translatePartialLoader) {
                        $translatePartialLoader.addPart('user-management');
                        return $translate.refresh();
                    }]
                }
            })
            .state('user-management.new', {
                parent: 'user-management',
                url: '/new',
                data: {
                    authorities: ['ROLE_ADMIN'],
                },
                onEnter: ['$stateParams', '$state', '$uibModal', function($stateParams, $state, $uibModal) {
                    $uibModal.open({
                        templateUrl: 'app/admin/user-management/user-management-dialog.html',
                        controller: 'UserManagementDialogController',
                        size: 'lg',
                        resolve: {
                            entity: function () {
                                return {
                                    id: null, login: null, firstName: null, lastName: null, email: null,
                                    activated: true, langKey: null, createdBy: null, createdDate: null,
                                    lastModifiedBy: null, lastModifiedDate: null, resetDate: null,
                                    resetKey: null, authorities: null
                                };
                            }
                        }
                    }).result.then(function() {
                        $state.go('user-management', null, { reload: true });
                    }, function() {
                        $state.go('user-management');
                    });
                }]
            })
            .state('user-management.edit', {
                parent: 'user-management',
                url: '/{login}/edit',
                data: {
                    authorities: ['ROLE_ADMIN'],
                },
                onEnter: ['$stateParams', '$state', '$uibModal', function($stateParams, $state, $uibModal) {
                    $uibModal.open({
                        templateUrl: 'app/admin/user-management/user-management-dialog.html',
                        controller: 'UserManagementDialogController',
                        size: 'lg',
                        resolve: {
                            entity: ['User', function(User) {
                                return User.get({login : $stateParams.login});
                            }]
                        }
                    }).result.then(function() {
                        $state.go('user-management', null, { reload: true });
                    }, function() {
                        $state.go('^');
                    });
                }]
            })
            .state('user-management.delete', {
                parent: 'user-management',
                url: '/{login}/delete',
                data: {
                    authorities: ['ROLE_ADMIN'],
                },
                onEnter: ['$stateParams', '$state', '$uibModal', function($stateParams, $state, $uibModal) {
                    $uibModal.open({
                        templateUrl: 'app/admin/user-management/user-management-delete-dialog.html',
                        controller: 'UserManagementDeleteController',
                        size: 'md',
                        resolve: {
                            entity: ['User', function(User) {
                                return User.get({login : $stateParams.login});
                            }]
                        }
                    }).result.then(function() {
                        $state.go('user-management', null, { reload: true });
                    }, function() {
                        $state.go('^');
                    });
                }]
            });
    });
<commit_msg>remove translate code from projects without translation<commit_after>'use strict';

angular.module('<%=angularAppName%>')
    .config(function ($stateProvider) {
        $stateProvider
            .state('user-management', {
                parent: 'admin',
                url: '/user-management',
                data: {
                    authorities: ['ROLE_ADMIN'],
                    pageTitle: 'user-management.home.title'
                },
                views: {
                    'content@': {
                        templateUrl: 'app/admin/user-management/user-management.html',
                        controller: 'UserManagementController'
                    }
                },
                resolve: {
                <% if (enableTranslation) { %>
                    translatePartialLoader: ['$translate', '$translatePartialLoader', function ($translate, $translatePartialLoader) {
                        $translatePartialLoader.addPart('user-management');
                        return $translate.refresh();
                    }]
                <% } %>
                }
            })
            .state('user-management-detail', {
                parent: 'admin',
                url: '/user/:login',
                data: {
                    authorities: ['ROLE_ADMIN'],
                    pageTitle: 'user-management.detail.title'
                },
                views: {
                    'content@': {
                        templateUrl: 'app/admin/user-management/user-management-detail.html',
                        controller: 'UserManagementDetailController'
                    }
                },
                resolve: {
                <% if (enableTranslation) { %>
                    translatePartialLoader: ['$translate', '$translatePartialLoader', function ($translate, $translatePartialLoader) {
                        $translatePartialLoader.addPart('user-management');
                        return $translate.refresh();
                    }]
                <% } %>
                }
            })
            .state('user-management.new', {
                parent: 'user-management',
                url: '/new',
                data: {
                    authorities: ['ROLE_ADMIN'],
                },
                onEnter: ['$stateParams', '$state', '$uibModal', function($stateParams, $state, $uibModal) {
                    $uibModal.open({
                        templateUrl: 'app/admin/user-management/user-management-dialog.html',
                        controller: 'UserManagementDialogController',
                        size: 'lg',
                        resolve: {
                            entity: function () {
                                return {
                                    id: null, login: null, firstName: null, lastName: null, email: null,
                                    activated: true, langKey: null, createdBy: null, createdDate: null,
                                    lastModifiedBy: null, lastModifiedDate: null, resetDate: null,
                                    resetKey: null, authorities: null
                                };
                            }
                        }
                    }).result.then(function() {
                        $state.go('user-management', null, { reload: true });
                    }, function() {
                        $state.go('user-management');
                    });
                }]
            })
            .state('user-management.edit', {
                parent: 'user-management',
                url: '/{login}/edit',
                data: {
                    authorities: ['ROLE_ADMIN'],
                },
                onEnter: ['$stateParams', '$state', '$uibModal', function($stateParams, $state, $uibModal) {
                    $uibModal.open({
                        templateUrl: 'app/admin/user-management/user-management-dialog.html',
                        controller: 'UserManagementDialogController',
                        size: 'lg',
                        resolve: {
                            entity: ['User', function(User) {
                                return User.get({login : $stateParams.login});
                            }]
                        }
                    }).result.then(function() {
                        $state.go('user-management', null, { reload: true });
                    }, function() {
                        $state.go('^');
                    });
                }]
            })
            .state('user-management.delete', {
                parent: 'user-management',
                url: '/{login}/delete',
                data: {
                    authorities: ['ROLE_ADMIN'],
                },
                onEnter: ['$stateParams', '$state', '$uibModal', function($stateParams, $state, $uibModal) {
                    $uibModal.open({
                        templateUrl: 'app/admin/user-management/user-management-delete-dialog.html',
                        controller: 'UserManagementDeleteController',
                        size: 'md',
                        resolve: {
                            entity: ['User', function(User) {
                                return User.get({login : $stateParams.login});
                            }]
                        }
                    }).result.then(function() {
                        $state.go('user-management', null, { reload: true });
                    }, function() {
                        $state.go('^');
                    });
                }]
            });
    });
<|endoftext|>


<commit_before>import React from 'react'
import { connect } from 'react-redux'
import { compose, flattenProp, setDisplayName } from 'recompose'
import { StyleSheet, View } from 'react-native'
import { SimpleLineIcons } from '@expo/vector-icons'
import { Text, Divider, TouchableRipple } from 'react-native-paper'
import { goToOperation } from 'Coopcon/data/navigation/actions'
import { getOperation } from 'Coopcon/data/operation/selectors'

const styles = StyleSheet.create({
  container: {
    flexDirection: 'row',
    alignItems: 'center',
    paddingTop: 15,
    paddingBottom: 15,
    paddingLeft: 15,
    paddingRight: 5,
    backgroundColor: 'white',
  },
  name: {
    flex: 1,
  },
})

const mapStateToProps = (state, { id }) => ({
  operation: getOperation(state, id),
})

const mapDispatchToProps = (dispatch, { id }) => ({
  goToOperation: () => dispatch(goToOperation(id)),
})

const enhancer = compose(
  connect(mapStateToProps, mapDispatchToProps),
  flattenProp('operation'),
  setDisplayName('Operation'),
)

const Operation = enhancer(({ name, goToOperation }) => (
  <View>
    <TouchableRipple
      onPress={goToOperation}
    >
      <View
        style={styles.container}
      >
        <Text style={styles.name}>{name}</Text>
        <SimpleLineIcons name="arrow-right" size={20}/>
      </View>
    </TouchableRipple>
    <Divider/>
  </View>
))

export default Operation
<commit_msg>operation: fix ripple when touching on the operation list<commit_after>import React from 'react'
import { connect } from 'react-redux'
import { compose, flattenProp, setDisplayName } from 'recompose'
import { StyleSheet, View } from 'react-native'
import { SimpleLineIcons } from '@expo/vector-icons'
import { Text, Divider, TouchableRipple } from 'react-native-paper'
import { goToOperation } from 'Coopcon/data/navigation/actions'
import { getOperation } from 'Coopcon/data/operation/selectors'

const styles = StyleSheet.create({
  wrapper: {
    backgroundColor: 'white',
  },
  container: {
    flexDirection: 'row',
    alignItems: 'center',
    paddingTop: 15,
    paddingBottom: 15,
    paddingLeft: 15,
    paddingRight: 5,
  },
  name: {
    flex: 1,
  },
})

const mapStateToProps = (state, { id }) => ({
  operation: getOperation(state, id),
})

const mapDispatchToProps = (dispatch, { id }) => ({
  goToOperation: () => dispatch(goToOperation(id)),
})

const enhancer = compose(
  connect(mapStateToProps, mapDispatchToProps),
  flattenProp('operation'),
  setDisplayName('Operation'),
)

const Operation = enhancer(({ name, goToOperation }) => (
  <View
    style={styles.wrapper}
  >
    <TouchableRipple
      onPress={goToOperation}
    >
      <View
        style={styles.container}
      >
        <Text style={styles.name}>{name}</Text>
        <SimpleLineIcons name="arrow-right" size={20}/>
      </View>
    </TouchableRipple>
    <Divider/>
  </View>
))

export default Operation
<|endoftext|>


<commit_before>import Node from './node';
import { coerceTruthyValueToArray } from 'element-ui/src/utils/util';

const flatNodes = (data, leafOnly) => {
  return data.reduce((res, node) => {
    if (node.isLeaf) {
      res.push(node);
    } else {
      !leafOnly && res.push(node);
      res = res.concat(flatNodes(node.children, leafOnly));
    }
    return res;
  }, []);
};

export default class Store {

  constructor(data, config) {
    this.config = config;
    this.initNodes(data);
  }

  initNodes(data) {
    data = coerceTruthyValueToArray(data);
    this.nodes = data.map(nodeData => new Node(nodeData, this.config));
    this.flattedNodes = this.getFlattedNodes(false, false);
    this.leafNodes = this.getFlattedNodes(true, false);
  }

  appendNode(nodeData, parentNode) {
    const node = new Node(nodeData, this.config, parentNode);
    const children = parentNode ? parentNode.children : this.nodes;

    children.push(node);
  }

  appendNodes(nodeDataList, parentNode) {
    nodeDataList = coerceTruthyValueToArray(nodeDataList);
    nodeDataList.forEach(nodeData => this.appendNode(nodeData, parentNode));
  }

  getNodes() {
    return this.nodes;
  }

  getFlattedNodes(leafOnly, cached = true) {
    const cachedNodes = leafOnly ? this.leafNodes : this.flattedNodes;
    return cached
      ? cachedNodes
      : flatNodes(this.nodes, leafOnly);
  }

  getNodeByValue(value) {
    if (value) {
      value = Array.isArray(value) ? value[value.length - 1] : value;
      const nodes = this.getFlattedNodes(false, !this.config.lazy)
        .filter(node => node.value === value);
      return nodes && nodes.length ? nodes[0] : null;
    }
    return null;
  }

}
<commit_msg>Cascader: fix display errors (#15935)<commit_after>import Node from './node';
import { coerceTruthyValueToArray, valueEquals } from 'element-ui/src/utils/util';

const flatNodes = (data, leafOnly) => {
  return data.reduce((res, node) => {
    if (node.isLeaf) {
      res.push(node);
    } else {
      !leafOnly && res.push(node);
      res = res.concat(flatNodes(node.children, leafOnly));
    }
    return res;
  }, []);
};

export default class Store {

  constructor(data, config) {
    this.config = config;
    this.initNodes(data);
  }

  initNodes(data) {
    data = coerceTruthyValueToArray(data);
    this.nodes = data.map(nodeData => new Node(nodeData, this.config));
    this.flattedNodes = this.getFlattedNodes(false, false);
    this.leafNodes = this.getFlattedNodes(true, false);
  }

  appendNode(nodeData, parentNode) {
    const node = new Node(nodeData, this.config, parentNode);
    const children = parentNode ? parentNode.children : this.nodes;

    children.push(node);
  }

  appendNodes(nodeDataList, parentNode) {
    nodeDataList = coerceTruthyValueToArray(nodeDataList);
    nodeDataList.forEach(nodeData => this.appendNode(nodeData, parentNode));
  }

  getNodes() {
    return this.nodes;
  }

  getFlattedNodes(leafOnly, cached = true) {
    const cachedNodes = leafOnly ? this.leafNodes : this.flattedNodes;
    return cached
      ? cachedNodes
      : flatNodes(this.nodes, leafOnly);
  }

  getNodeByValue(value) {
    if (value) {
      const nodes = this.getFlattedNodes(false, !this.config.lazy)
        .filter(node => (valueEquals(node.path, value) || node.value === value));
      return nodes && nodes.length ? nodes[0] : null;
    }
    return null;
  }

}
<|endoftext|>


<commit_before>var Ipc = require('ipc');
var Async = require('async');
var Url = require('fire-url');

Ipc.on('scene:ipc-messages', function ( ipcList ) {
    for ( var i = 0; i < ipcList.length; ++i ) {
        Ipc.emit.apply( Ipc, ipcList[i] );
    }
});

Ipc.on('scene:new-scene', function () {
    window.sceneView.newScene();
});

Ipc.on('scene:save-scene-from-page', function ( url ) {
    var sceneAsset = new cc.SceneAsset();
    sceneAsset.scene = cc.director.getScene();

    // NOTE: we stash scene because we want to save and reload the connected browser
    Editor.stashScene(function () {
        // reload connected browser
        Editor.sendToCore('app:reload-on-device');

        //
        Editor.sendToCore( 'scene:save-scene', url, Editor.serialize(sceneAsset) );
    });
});

Ipc.on('scene:open-scene-by-uuid', function ( uuid ) {
    window.sceneView.loadScene(uuid);
});

Ipc.on('scene:play-on-device', function () {
    Editor.stashScene( function () {
        Editor.sendToCore( 'app:play-on-device' );
    });
});

Ipc.on('scene:reload-on-device', function () {
    Editor.stashScene( function () {
        Editor.sendToCore( 'app:reload-on-device' );
    });
});

Ipc.on('scene:drop', function ( uuids, type, x, y ) {
    Editor.Selection.clear('node');
    Async.each( uuids, function ( uuid, done ) {
        Async.waterfall([
            function ( next ) {
                Editor.createNode(uuid, next);
            },

            function ( node, next ) {
                var nodeID;
                if ( node ) {
                    nodeID = node.uuid;

                    node.setPosition(window.sceneView.pixelToScene( cc.v2(x,y) ));
                    node.parent = cc.director.getScene();
                }

                next ( null, nodeID );
            },

        ], function ( err, nodeID ) {
            if ( err ) {
                Editor.failed( 'Failed to drop asset %s, message: %s', uuid, err.stack || err.errorMessage );
                return;
            }

            if ( nodeID ) {
                Editor.Selection.select('node', nodeID, false, true );
            }
            cc.engine.repaintInEditMode();
            done();
        });
    });
});

Ipc.on('scene:create-nodes-by-uuids', function ( uuids, parentID ) {
    var parentNode;
    if ( parentID ) {
        parentNode = cc.engine.getInstanceById(parentID);
    }
    if ( !parentNode ) {
        parentNode = cc.director.getScene();
    }

    Editor.Selection.clear('node');

    //
    Async.each( uuids, function ( uuid, done ) {
        Async.waterfall([
            function ( next ) {
                Editor.createNode(uuid, next);
            },

            function ( node, next ) {
                var nodeID;
                if ( node ) {
                    nodeID = node.uuid;

                    if ( parentNode ) {
                        node.parent = parentNode;
                    }
                    var center_x = cc.game.canvas.width / 2;
                    var center_y = cc.game.canvas.height / 2;
                    node.scenePosition = window.sceneView.pixelToScene( cc.v2(center_x, center_y) );
                }

                next ( null, nodeID );
            }

        ], function ( err, nodeID ) {
            if ( err ) {
                Editor.failed( 'Failed to drop asset %s, message: %s', uuid, err.stack || err.errorMessage );
                return;
            }

            if ( nodeID ) {
                Editor.Selection.select('node', nodeID, false, true );
            }
            cc.engine.repaintInEditMode();
            done();
        });
    });
});

Ipc.on('scene:create-node-by-classid', function ( name, classID, referenceID, position ) {
    var parent;

    if ( referenceID ) {
        parent = cc.engine.getInstanceById(referenceID);
        if ( position === 'sibling' ) {
            parent = parent.parent;
        }
    }
    if ( !parent ) {
        parent = cc.director.getScene();
    }

    var node = new cc.ENode(name);
    node.parent = parent;

    var center_x = cc.game.canvas.width / 2;
    var center_y = cc.game.canvas.height / 2;
    node.scenePosition = window.sceneView.pixelToScene( cc.v2(center_x, center_y) );

    cc.engine.repaintInEditMode();
    Editor.Selection.select('node', node.uuid, true, true );

    if (classID) {
        // add component
        var Component = cc.js._getClassById(classID);
        if (Component) {
            node.addComponent(Component);
        }
        else {
            Editor.error('Unknown node to create:', classID);
        }
    }
});

Ipc.on('scene:query-hierarchy', function ( queryID ) {
    if (!cc.engine.isInitialized) {
        return Editor.sendToWindows( 'scene:reply-query-hierarchy', queryID, '', [] );
    }
    var nodes = Editor.getHierarchyDump();
    var sceneUuid = cc.director.getScene().uuid;
    Editor.sendToWindows( 'scene:reply-query-hierarchy', queryID, sceneUuid, nodes );
});

Ipc.on('scene:query-node', function ( queryID, nodeID ) {
    var node = cc.engine.getInstanceById(nodeID);
    var dump = Editor.getNodeDump(node);
    dump = JSON.stringify(dump);    // 改成发送字符串，以免字典的顺序发生改变
    Editor.sendToWindows( 'scene:reply-query-node', queryID, dump );
});

Ipc.on('scene:query-node-info', function ( sessionID, nodeID ) {
    var node = cc.engine.getInstanceById(nodeID);

    Editor.sendToWindows( 'scene:query-node-info:reply', sessionID, {
        name: node ? node.name : '',
        type: cc.js.getClassName(node),
        missed: node ? false : true,
    });
});

Ipc.on('scene:node-new-property', function ( info ) {
    var nodeOrComp = cc.engine.getInstanceById(info.id);
    if (nodeOrComp) {
        try {
            var id = info.type;
            var ctor;
            if (cc.js._isTempClassId(id)) {
                ctor = cc.js._getClassById(id);
            }
            else {
                ctor = cc.js.getClassByName(id);
            }
            if ( ctor ) {
                var obj;
                try {
                    obj = new ctor();
                }
                catch (e) {
                    Editor.error('Can not create new info.type directly.\nInner message: ' + e.stack);
                    return;
                }
                Editor.setDeepPropertyByPath(nodeOrComp, info.path, obj, info.type);
                cc.engine.repaintInEditMode();
            }
        }
        catch (e) {
            Editor.warn('Failed to new property %s of %s to %s, ' + e.message,
                info.path, nodeOrComp.name, info.value);
        }
    }
});

Ipc.on('scene:node-set-property', function ( info ) {
    var nodeOrComp = cc.engine.getInstanceById(info.id);
    if (nodeOrComp) {
        // 兼容旧版 Inspector
        if (info.mixinType) {
            nodeOrComp = nodeOrComp.getComponent(info.mixinType);
            if (!cc.isValid(nodeOrComp)) {
                return;
            }
        }
        //
        try {
            Editor.setPropertyByPath(nodeOrComp, info.path, info.value, info.type);
            cc.engine.repaintInEditMode();
        }
        catch (e) {
            Editor.warn('Failed to set property %s of %s to %s, ' + e.message,
                info.path, nodeOrComp.name, info.value);
        }
    }
});

Ipc.on('scene:component-add', function ( id, uuid ) {
    if (uuid && Editor.isUuid(uuid)) {
        // check script
        var className = Editor.compressUuid(uuid);
        var Comp = cc.js._getClassById(className);
        if (!Comp) {
            return Editor.error('Can not find cc.Component in the script "%s".', uuid);
        }
        //
        var node = cc.engine.getInstanceById(id);
        if (node) {
            node.addComponent(Comp);
        }
        else {
            Editor.error('Can not find node to add component: %s', id);
        }
    }
    else {
        Editor.error('invalid script to add component');
    }
});

Ipc.on('scene:component-remove', function ( id, className ) {
    var node = cc.engine.getInstanceById(id);
    if (node) {
        node.getComponent(className).destroy();
    }
});

function getSiblingIndex (node) {
    return node._parent._children.indexOf(node);
}

Ipc.on('scene:move-nodes', function ( ids, parentID, nextSiblingId ) {
    var parent;

    if (parentID)
        parent = cc.engine.getInstanceById(parentID);
    else
        parent = cc.director.getScene();

    var next = nextSiblingId ? cc.engine.getInstanceById(nextSiblingId) : null;
    var nextIndex = next ? getSiblingIndex(next) : -1;

    for (var i = 0; i < ids.length; i++) {
        var id = ids[i];
        var node = cc.engine.getInstanceById(id);
        if (node && (!parent || !parent.isChildOf(node))) {
            if (node.parent !== parent) {
                // keep world transform not changed
                var worldPos = node.worldPosition;
                var worldRotation = node.worldRotation;
                var lossyScale = node.worldScale;

                node.parent = parent;

                // restore world transform
                node.worldPosition = worldPos;
                node.worldRotation = worldRotation;
                if (parent) {
                    node.scale = lossyScale.divSelf(parent.worldScale);
                }
                else {
                    node.scale = lossyScale;
                }

                if (next) {
                    node.setSiblingIndex(nextIndex);
                    ++nextIndex;
                }
            }
            else if (next) {
                var lastIndex = getSiblingIndex(node);
                var newIndex = nextIndex;
                if (newIndex > lastIndex) {
                    --newIndex;
                }
                if (newIndex !== lastIndex) {
                    node.setSiblingIndex(newIndex);
                    if (lastIndex > newIndex) {
                        ++nextIndex;
                    }
                    else {
                        --nextIndex;
                    }
                }
            }
            else {
                // move to bottom
                node.setSiblingIndex(-1);
            }
        }
    }
});

Ipc.on('scene:delete-nodes', function ( ids ) {
    window.sceneView.delete(ids);
});

Ipc.on('scene:duplicate-nodes', function ( ids ) {
    var nodes = [];
    for ( var i = 0; i < ids.length; ++i ) {
         var node = cc.engine.getInstanceById(ids[i]);
        if (node) {
            nodes.push(node);
        }
    }

    // get top-level wrappers
    var results = Editor.Utils.arrayCmpFilter ( nodes, function ( a, b ) {
        if (a === b) {
            return 0;
        }

        if (b.isChildOf(a)) {
            return 1;
        }

        if (a.isChildOf(b)) {
            return -1;
        }

        return 0;
    });

    // duplicate results
    var clones = [];
    results.forEach(function ( node ) {
        var clone = cc.instantiate(node);
        clone.parent = node.parent;

        clones.push(clone.uuid);
    });

    // select the last one
    Editor.Selection.select('node', clones);
});

Ipc.on('scene:stash-and-reload', function () {
    Editor.stashScene(function () {
        Ipc.sendToHost('scene:ask-for-reload');
    });
});

Ipc.on('scene:soft-reload', function (compiled) {
    Editor.softReload(compiled);
});

Ipc.on('selection:activated', function ( type, id ) {
    if ( type !== 'node' || !id ) {
        return;
    }

    window.sceneView.activate(id);
});

Ipc.on('selection:deactivated', function ( type, id ) {
    if ( type !== 'node' ) {
        return;
    }

    window.sceneView.deactivate(id);
});

Ipc.on('selection:selected', function ( type, ids ) {
    if ( type !== 'node' ) {
        return;
    }
    window.sceneView.select(ids);
});

Ipc.on('selection:unselected', function ( type, ids ) {
    if ( type !== 'node' ) {
        return;
    }
    window.sceneView.unselect(ids);
});

Ipc.on('selection:hoverin', function ( type, id ) {
    if ( type !== 'node' ) {
        return;
    }
    window.sceneView.hoverin(id);
});

Ipc.on('selection:hoverout', function ( type, id ) {
    if ( type !== 'node' ) {
        return;
    }
    window.sceneView.hoverout(id);
});

Ipc.on('scene:init-scene-view', function ( settings ) {
    window.sceneView.$.gizmosView.transformTool = settings.transformTool;
    window.sceneView.$.gizmosView.coordinate = settings.coordinate;
    window.sceneView.$.gizmosView.pivot = settings.pivot;
    window.sceneView.$.gizmosView.designSize = [settings.designWidth, settings.designHeight];
});

Ipc.on('scene:transform-tool-changed', function ( value ) {
    window.sceneView.$.gizmosView.transformTool = value;
    cc.engine.repaintInEditMode();
});

Ipc.on('scene:coordinate-changed', function ( value ) {
    window.sceneView.$.gizmosView.coordinate = value;
    cc.engine.repaintInEditMode();
});

Ipc.on('scene:pivot-changed', function ( value ) {
    window.sceneView.$.gizmosView.pivot = value;
    cc.engine.repaintInEditMode();
});

Ipc.on('scene:design-size-changed', function ( w, h ) {
    window.sceneView.$.gizmosView.designSize = [w, h];
    cc.engine.repaintInEditMode();
});

Ipc.on('scene:create-prefab', function ( id, baseUrl ) {
    var node = cc.engine.getInstanceById(id);
    var prefab = Editor.PrefabUtils.createPrefabFrom(node);
    var json = Editor.serialize(prefab);
    var url = Url.join(baseUrl, node.name + '.prefab');

    Editor.sendRequestToCore('scene:create-prefab', url, json, function (err, uuid) {
        if (!err) {
            Editor.PrefabUtils.savePrefabUuid(node, uuid);
        }
    });
});

Ipc.on('scene:apply-prefab', function ( id ) {
    var node = cc.engine.getInstanceById(id);
    if (!node || !node._prefab) {
        return;
    }

    node = node._prefab.root;
    var uuid = node._prefab.asset._uuid;
    var prefab = Editor.PrefabUtils.createPrefabFrom(node);
    Editor.PrefabUtils.savePrefabUuid(node, uuid);
    var json = Editor.serialize(prefab);

    Editor.sendToCore('scene:apply-prefab', uuid, json);
});

Ipc.on('scene:revert-prefab', function ( id ) {
    var node = cc.engine.getInstanceById(id);
    if (!node || !node._prefab) {
        return;
    }

    node = node._prefab.root;
    Editor.PrefabUtils.revertPrefab(node);
});

<commit_msg>update scene:component-add<commit_after>var Ipc = require('ipc');
var Async = require('async');
var Url = require('fire-url');

Ipc.on('scene:ipc-messages', function ( ipcList ) {
    for ( var i = 0; i < ipcList.length; ++i ) {
        Ipc.emit.apply( Ipc, ipcList[i] );
    }
});

Ipc.on('scene:new-scene', function () {
    window.sceneView.newScene();
});

Ipc.on('scene:save-scene-from-page', function ( url ) {
    var sceneAsset = new cc.SceneAsset();
    sceneAsset.scene = cc.director.getScene();

    // NOTE: we stash scene because we want to save and reload the connected browser
    Editor.stashScene(function () {
        // reload connected browser
        Editor.sendToCore('app:reload-on-device');

        //
        Editor.sendToCore( 'scene:save-scene', url, Editor.serialize(sceneAsset) );
    });
});

Ipc.on('scene:open-scene-by-uuid', function ( uuid ) {
    window.sceneView.loadScene(uuid);
});

Ipc.on('scene:play-on-device', function () {
    Editor.stashScene( function () {
        Editor.sendToCore( 'app:play-on-device' );
    });
});

Ipc.on('scene:reload-on-device', function () {
    Editor.stashScene( function () {
        Editor.sendToCore( 'app:reload-on-device' );
    });
});

Ipc.on('scene:drop', function ( uuids, type, x, y ) {
    Editor.Selection.clear('node');
    Async.each( uuids, function ( uuid, done ) {
        Async.waterfall([
            function ( next ) {
                Editor.createNode(uuid, next);
            },

            function ( node, next ) {
                var nodeID;
                if ( node ) {
                    nodeID = node.uuid;

                    node.setPosition(window.sceneView.pixelToScene( cc.v2(x,y) ));
                    node.parent = cc.director.getScene();
                }

                next ( null, nodeID );
            },

        ], function ( err, nodeID ) {
            if ( err ) {
                Editor.failed( 'Failed to drop asset %s, message: %s', uuid, err.stack || err.errorMessage );
                return;
            }

            if ( nodeID ) {
                Editor.Selection.select('node', nodeID, false, true );
            }
            cc.engine.repaintInEditMode();
            done();
        });
    });
});

Ipc.on('scene:create-nodes-by-uuids', function ( uuids, parentID ) {
    var parentNode;
    if ( parentID ) {
        parentNode = cc.engine.getInstanceById(parentID);
    }
    if ( !parentNode ) {
        parentNode = cc.director.getScene();
    }

    Editor.Selection.clear('node');

    //
    Async.each( uuids, function ( uuid, done ) {
        Async.waterfall([
            function ( next ) {
                Editor.createNode(uuid, next);
            },

            function ( node, next ) {
                var nodeID;
                if ( node ) {
                    nodeID = node.uuid;

                    if ( parentNode ) {
                        node.parent = parentNode;
                    }
                    var center_x = cc.game.canvas.width / 2;
                    var center_y = cc.game.canvas.height / 2;
                    node.scenePosition = window.sceneView.pixelToScene( cc.v2(center_x, center_y) );
                }

                next ( null, nodeID );
            }

        ], function ( err, nodeID ) {
            if ( err ) {
                Editor.failed( 'Failed to drop asset %s, message: %s', uuid, err.stack || err.errorMessage );
                return;
            }

            if ( nodeID ) {
                Editor.Selection.select('node', nodeID, false, true );
            }
            cc.engine.repaintInEditMode();
            done();
        });
    });
});

Ipc.on('scene:create-node-by-classid', function ( name, classID, referenceID, position ) {
    var parent;

    if ( referenceID ) {
        parent = cc.engine.getInstanceById(referenceID);
        if ( position === 'sibling' ) {
            parent = parent.parent;
        }
    }
    if ( !parent ) {
        parent = cc.director.getScene();
    }

    var node = new cc.ENode(name);
    node.parent = parent;

    var center_x = cc.game.canvas.width / 2;
    var center_y = cc.game.canvas.height / 2;
    node.scenePosition = window.sceneView.pixelToScene( cc.v2(center_x, center_y) );

    cc.engine.repaintInEditMode();
    Editor.Selection.select('node', node.uuid, true, true );

    if (classID) {
        // add component
        var Component = cc.js._getClassById(classID);
        if (Component) {
            node.addComponent(Component);
        }
        else {
            Editor.error('Unknown node to create:', classID);
        }
    }
});

Ipc.on('scene:query-hierarchy', function ( queryID ) {
    if (!cc.engine.isInitialized) {
        return Editor.sendToWindows( 'scene:reply-query-hierarchy', queryID, '', [] );
    }
    var nodes = Editor.getHierarchyDump();
    var sceneUuid = cc.director.getScene().uuid;
    Editor.sendToWindows( 'scene:reply-query-hierarchy', queryID, sceneUuid, nodes );
});

Ipc.on('scene:query-node', function ( queryID, nodeID ) {
    var node = cc.engine.getInstanceById(nodeID);
    var dump = Editor.getNodeDump(node);
    dump = JSON.stringify(dump);    // 改成发送字符串，以免字典的顺序发生改变
    Editor.sendToWindows( 'scene:reply-query-node', queryID, dump );
});

Ipc.on('scene:query-node-info', function ( sessionID, nodeID ) {
    var node = cc.engine.getInstanceById(nodeID);

    Editor.sendToWindows( 'scene:query-node-info:reply', sessionID, {
        name: node ? node.name : '',
        type: cc.js.getClassName(node),
        missed: node ? false : true,
    });
});

Ipc.on('scene:node-new-property', function ( info ) {
    var nodeOrComp = cc.engine.getInstanceById(info.id);
    if (nodeOrComp) {
        try {
            var id = info.type;
            var ctor;
            if (cc.js._isTempClassId(id)) {
                ctor = cc.js._getClassById(id);
            }
            else {
                ctor = cc.js.getClassByName(id);
            }
            if ( ctor ) {
                var obj;
                try {
                    obj = new ctor();
                }
                catch (e) {
                    Editor.error('Can not create new info.type directly.\nInner message: ' + e.stack);
                    return;
                }
                Editor.setDeepPropertyByPath(nodeOrComp, info.path, obj, info.type);
                cc.engine.repaintInEditMode();
            }
        }
        catch (e) {
            Editor.warn('Failed to new property %s of %s to %s, ' + e.message,
                info.path, nodeOrComp.name, info.value);
        }
    }
});

Ipc.on('scene:node-set-property', function ( info ) {
    var nodeOrComp = cc.engine.getInstanceById(info.id);
    if (nodeOrComp) {
        // 兼容旧版 Inspector
        if (info.mixinType) {
            nodeOrComp = nodeOrComp.getComponent(info.mixinType);
            if (!cc.isValid(nodeOrComp)) {
                return;
            }
        }
        //
        try {
            Editor.setPropertyByPath(nodeOrComp, info.path, info.value, info.type);
            cc.engine.repaintInEditMode();
        }
        catch (e) {
            Editor.warn('Failed to set property %s of %s to %s, ' + e.message,
                info.path, nodeOrComp.name, info.value);
        }
    }
});

Ipc.on('scene:component-add', function ( id, compId ) {
    if (compId) {
        var isScript = Editor.isUuid(compId);
        if (isScript) {
            compId = Editor.compressUuid(compId);
        }
        var Comp = cc.js._getClassById(compId);
        if (!Comp) {
            if (isScript) {
                return Editor.error('Can not find cc.Component in the script "%s".', compId);
            }
            else {
                return Editor.error('Failed to get component "%s".', compId);
            }
        }
        //
        var node = cc.engine.getInstanceById(id);
        if (node) {
            node.addComponent(Comp);
        }
        else {
            Editor.error('Can not find node ' + id);
        }
    }
    else {
        Editor.error('invalid compId to add component');
    }
});

Ipc.on('scene:component-remove', function ( id, className ) {
    var node = cc.engine.getInstanceById(id);
    if (node) {
        node.getComponent(className).destroy();
    }
});

function getSiblingIndex (node) {
    return node._parent._children.indexOf(node);
}

Ipc.on('scene:move-nodes', function ( ids, parentID, nextSiblingId ) {
    var parent;

    if (parentID)
        parent = cc.engine.getInstanceById(parentID);
    else
        parent = cc.director.getScene();

    var next = nextSiblingId ? cc.engine.getInstanceById(nextSiblingId) : null;
    var nextIndex = next ? getSiblingIndex(next) : -1;

    for (var i = 0; i < ids.length; i++) {
        var id = ids[i];
        var node = cc.engine.getInstanceById(id);
        if (node && (!parent || !parent.isChildOf(node))) {
            if (node.parent !== parent) {
                // keep world transform not changed
                var worldPos = node.worldPosition;
                var worldRotation = node.worldRotation;
                var lossyScale = node.worldScale;

                node.parent = parent;

                // restore world transform
                node.worldPosition = worldPos;
                node.worldRotation = worldRotation;
                if (parent) {
                    node.scale = lossyScale.divSelf(parent.worldScale);
                }
                else {
                    node.scale = lossyScale;
                }

                if (next) {
                    node.setSiblingIndex(nextIndex);
                    ++nextIndex;
                }
            }
            else if (next) {
                var lastIndex = getSiblingIndex(node);
                var newIndex = nextIndex;
                if (newIndex > lastIndex) {
                    --newIndex;
                }
                if (newIndex !== lastIndex) {
                    node.setSiblingIndex(newIndex);
                    if (lastIndex > newIndex) {
                        ++nextIndex;
                    }
                    else {
                        --nextIndex;
                    }
                }
            }
            else {
                // move to bottom
                node.setSiblingIndex(-1);
            }
        }
    }
});

Ipc.on('scene:delete-nodes', function ( ids ) {
    window.sceneView.delete(ids);
});

Ipc.on('scene:duplicate-nodes', function ( ids ) {
    var nodes = [];
    for ( var i = 0; i < ids.length; ++i ) {
         var node = cc.engine.getInstanceById(ids[i]);
        if (node) {
            nodes.push(node);
        }
    }

    // get top-level wrappers
    var results = Editor.Utils.arrayCmpFilter ( nodes, function ( a, b ) {
        if (a === b) {
            return 0;
        }

        if (b.isChildOf(a)) {
            return 1;
        }

        if (a.isChildOf(b)) {
            return -1;
        }

        return 0;
    });

    // duplicate results
    var clones = [];
    results.forEach(function ( node ) {
        var clone = cc.instantiate(node);
        clone.parent = node.parent;

        clones.push(clone.uuid);
    });

    // select the last one
    Editor.Selection.select('node', clones);
});

Ipc.on('scene:stash-and-reload', function () {
    Editor.stashScene(function () {
        Ipc.sendToHost('scene:ask-for-reload');
    });
});

Ipc.on('scene:soft-reload', function (compiled) {
    Editor.softReload(compiled);
});

Ipc.on('selection:activated', function ( type, id ) {
    if ( type !== 'node' || !id ) {
        return;
    }

    window.sceneView.activate(id);
});

Ipc.on('selection:deactivated', function ( type, id ) {
    if ( type !== 'node' ) {
        return;
    }

    window.sceneView.deactivate(id);
});

Ipc.on('selection:selected', function ( type, ids ) {
    if ( type !== 'node' ) {
        return;
    }
    window.sceneView.select(ids);
});

Ipc.on('selection:unselected', function ( type, ids ) {
    if ( type !== 'node' ) {
        return;
    }
    window.sceneView.unselect(ids);
});

Ipc.on('selection:hoverin', function ( type, id ) {
    if ( type !== 'node' ) {
        return;
    }
    window.sceneView.hoverin(id);
});

Ipc.on('selection:hoverout', function ( type, id ) {
    if ( type !== 'node' ) {
        return;
    }
    window.sceneView.hoverout(id);
});

Ipc.on('scene:init-scene-view', function ( settings ) {
    window.sceneView.$.gizmosView.transformTool = settings.transformTool;
    window.sceneView.$.gizmosView.coordinate = settings.coordinate;
    window.sceneView.$.gizmosView.pivot = settings.pivot;
    window.sceneView.$.gizmosView.designSize = [settings.designWidth, settings.designHeight];
});

Ipc.on('scene:transform-tool-changed', function ( value ) {
    window.sceneView.$.gizmosView.transformTool = value;
    cc.engine.repaintInEditMode();
});

Ipc.on('scene:coordinate-changed', function ( value ) {
    window.sceneView.$.gizmosView.coordinate = value;
    cc.engine.repaintInEditMode();
});

Ipc.on('scene:pivot-changed', function ( value ) {
    window.sceneView.$.gizmosView.pivot = value;
    cc.engine.repaintInEditMode();
});

Ipc.on('scene:design-size-changed', function ( w, h ) {
    window.sceneView.$.gizmosView.designSize = [w, h];
    cc.engine.repaintInEditMode();
});

Ipc.on('scene:create-prefab', function ( id, baseUrl ) {
    var node = cc.engine.getInstanceById(id);
    var prefab = Editor.PrefabUtils.createPrefabFrom(node);
    var json = Editor.serialize(prefab);
    var url = Url.join(baseUrl, node.name + '.prefab');

    Editor.sendRequestToCore('scene:create-prefab', url, json, function (err, uuid) {
        if (!err) {
            Editor.PrefabUtils.savePrefabUuid(node, uuid);
        }
    });
});

Ipc.on('scene:apply-prefab', function ( id ) {
    var node = cc.engine.getInstanceById(id);
    if (!node || !node._prefab) {
        return;
    }

    node = node._prefab.root;
    var uuid = node._prefab.asset._uuid;
    var prefab = Editor.PrefabUtils.createPrefabFrom(node);
    Editor.PrefabUtils.savePrefabUuid(node, uuid);
    var json = Editor.serialize(prefab);

    Editor.sendToCore('scene:apply-prefab', uuid, json);
});

Ipc.on('scene:revert-prefab', function ( id ) {
    var node = cc.engine.getInstanceById(id);
    if (!node || !node._prefab) {
        return;
    }

    node = node._prefab.root;
    Editor.PrefabUtils.revertPrefab(node);
});

<|endoftext|>


<commit_before>/*
  There are three sources of schema information.

  1. Most of it lives within a regular data source, just like your
     other content does.

  2. But we need a tiny bit of schema to find the first data
     source. This is the `seedModels` that are passed into the
     constructor below. Note that only schema types are allowed in
     seedModels (not any of your other content).

  3. Internally, we also always load @cardstack/hub/bootstrap-schema,
     which is enough to wire up some of our own modules for things
     like core field types.
*/

const Searcher = require('@cardstack/elasticsearch/searcher');
const logger = require('@cardstack/plugin-utils/logger');
const bootstrapSchema = require('./bootstrap-schema');
const { declareInjections } = require('@cardstack/di');
const Schema = require('./schema');

module.exports = declareInjections({
  seedModels: 'config:seed-models',
  schemaLoader: 'hub:schema-loader'
},

class SchemaCache {

  static create(opts) {
    return new this(opts);
  }

  constructor({ seedModels, schemaLoader }) {
    this.seedModels = bootstrapSchema.concat(seedModels || []);
    this.searcher = new Searcher();
    this.searcher.schemaCache = new BootstrapSchemaCache(this.seedModels, this);
    this.cache = new Map();
    this.log = logger('schema-cache');
    this.schemaLoader = schemaLoader;

    // TODO move this value into plugins-configs for @cardstack/hub.
    this.controllingBranch = 'master';
  }

  async schemaForBranch(branch) {
    if (!this.cache.has(branch)) {
      // we synchronously place a Promise into the cache. This ensures
      // that a subsequent lookup that arrives while we are still
      // working on this one will join it instead of racing it.
      this.cache.set(branch, this._load(branch));
    }
    let schema = await this.cache.get(branch);
    this.log.debug("returning schema for branch %s %s", branch);
    return schema;
  }

  // The "controlling branch" is special because it's used for
  // configuration that is not scoped to any particular branch.
  //
  // For one example: the set of data sources that we're indexing is
  // not something that can vary by branch, since the set of branches
  // itself is discovered by the indexers.
  //
  // For another example: grants only take effect when they are
  // present on the controlling branch. This makes it easier to reason
  // about who can do what.
  async schemaForControllingBranch() {
    return this.schemaForBranch(this.controllingBranch);
  }

  // Instantiates a Schema, while respecting any seedModels. This
  // method does not alter the schemaCache's own state.
  async schemaFrom(models) {
    let types = this.schemaLoader.ownTypes();
    return this.schemaLoader.loadFrom(this.seedModels.concat(models).filter(s => types.includes(s.type)));
  }

  // When Indexers reads a branch, it necessarily reads the schema
  // first. And when Writers make a change to a schema model, they
  // need to derive the new schema to make sure it's safe. In either
  // case, the new schema is already available, so this method allows
  // us to push it into the cache.
  notifyBranchUpdate(branch, schema) {
    if (!(schema instanceof Schema)) {
      throw new Error("Bug: notifyBranchUpdate got a non-schema");
    }
    this.log.debug("full schema update on branch %s", branch);
    this.cache.set(branch, Promise.resolve(schema));
  }

  async indexBaseContent(ops) {
    for (let model of this.seedModels) {
      await ops.save(model.type, model.id, model);
    }
  }

  async _load(branch) {
    this.log.debug("initiating schema load on branch %s", branch);
    try {
      let { models, page } = await this.searcher.search(branch, {
        filter: {
          type: this.schemaLoader.ownTypes()
        },
        page: { size: 1000 }
      });
      if (page.cursor) {
        throw new Error("query for schema models had insufficient page size");
      }
      this.log.debug("completed schema model loading on branch %s, found %s models", branch, models.length);
      let schema = this.schemaFrom(models);
      this.log.debug("instantiated schema for branch %s", branch);
      return schema;
    } catch (err) {
      if (err.status === 404 && err.title === 'No such branch') {
        // our searcher can fail if no index exists yet. But that's OK
        // -- in that case our schema is just our seed models.
        this.log.debug("no search index exists for branch %s, using seeds only", branch);
        return this.schemaFrom([]);
      } else {
        throw err;
      }
    }
  }
});

class BootstrapSchemaCache {
  constructor(seedModels, schemaCache) {
    this.seedModels = seedModels;
    this.schema = null;
    this.schemaCache = schemaCache;
  }
  async schemaForBranch() {
    if (!this.schema) {
      this.schema = await this.schemaCache.schemaFrom(this.seedModels);
    }
    return this.schema;
  }
}
<commit_msg>fix a log message<commit_after>/*
  There are three sources of schema information.

  1. Most of it lives within a regular data source, just like your
     other content does.

  2. But we need a tiny bit of schema to find the first data
     source. This is the `seedModels` that are passed into the
     constructor below. Note that only schema types are allowed in
     seedModels (not any of your other content).

  3. Internally, we also always load @cardstack/hub/bootstrap-schema,
     which is enough to wire up some of our own modules for things
     like core field types.
*/

const Searcher = require('@cardstack/elasticsearch/searcher');
const logger = require('@cardstack/plugin-utils/logger');
const bootstrapSchema = require('./bootstrap-schema');
const { declareInjections } = require('@cardstack/di');
const Schema = require('./schema');

module.exports = declareInjections({
  seedModels: 'config:seed-models',
  schemaLoader: 'hub:schema-loader'
},

class SchemaCache {

  static create(opts) {
    return new this(opts);
  }

  constructor({ seedModels, schemaLoader }) {
    this.seedModels = bootstrapSchema.concat(seedModels || []);
    this.searcher = new Searcher();
    this.searcher.schemaCache = new BootstrapSchemaCache(this.seedModels, this);
    this.cache = new Map();
    this.log = logger('schema-cache');
    this.schemaLoader = schemaLoader;

    // TODO move this value into plugins-configs for @cardstack/hub.
    this.controllingBranch = 'master';
  }

  async schemaForBranch(branch) {
    if (!this.cache.has(branch)) {
      // we synchronously place a Promise into the cache. This ensures
      // that a subsequent lookup that arrives while we are still
      // working on this one will join it instead of racing it.
      this.cache.set(branch, this._load(branch));
    }
    let schema = await this.cache.get(branch);
    this.log.debug("returning schema for branch %s", branch);
    return schema;
  }

  // The "controlling branch" is special because it's used for
  // configuration that is not scoped to any particular branch.
  //
  // For one example: the set of data sources that we're indexing is
  // not something that can vary by branch, since the set of branches
  // itself is discovered by the indexers.
  //
  // For another example: grants only take effect when they are
  // present on the controlling branch. This makes it easier to reason
  // about who can do what.
  async schemaForControllingBranch() {
    return this.schemaForBranch(this.controllingBranch);
  }

  // Instantiates a Schema, while respecting any seedModels. This
  // method does not alter the schemaCache's own state.
  async schemaFrom(models) {
    let types = this.schemaLoader.ownTypes();
    return this.schemaLoader.loadFrom(this.seedModels.concat(models).filter(s => types.includes(s.type)));
  }

  // When Indexers reads a branch, it necessarily reads the schema
  // first. And when Writers make a change to a schema model, they
  // need to derive the new schema to make sure it's safe. In either
  // case, the new schema is already available, so this method allows
  // us to push it into the cache.
  notifyBranchUpdate(branch, schema) {
    if (!(schema instanceof Schema)) {
      throw new Error("Bug: notifyBranchUpdate got a non-schema");
    }
    this.log.debug("full schema update on branch %s", branch);
    this.cache.set(branch, Promise.resolve(schema));
  }

  async indexBaseContent(ops) {
    for (let model of this.seedModels) {
      await ops.save(model.type, model.id, model);
    }
  }

  async _load(branch) {
    this.log.debug("initiating schema load on branch %s", branch);
    try {
      let { models, page } = await this.searcher.search(branch, {
        filter: {
          type: this.schemaLoader.ownTypes()
        },
        page: { size: 1000 }
      });
      if (page.cursor) {
        throw new Error("query for schema models had insufficient page size");
      }
      this.log.debug("completed schema model loading on branch %s, found %s models", branch, models.length);
      let schema = this.schemaFrom(models);
      this.log.debug("instantiated schema for branch %s", branch);
      return schema;
    } catch (err) {
      if (err.status === 404 && err.title === 'No such branch') {
        // our searcher can fail if no index exists yet. But that's OK
        // -- in that case our schema is just our seed models.
        this.log.debug("no search index exists for branch %s, using seeds only", branch);
        return this.schemaFrom([]);
      } else {
        throw err;
      }
    }
  }
});

class BootstrapSchemaCache {
  constructor(seedModels, schemaCache) {
    this.seedModels = seedModels;
    this.schema = null;
    this.schemaCache = schemaCache;
  }
  async schemaForBranch() {
    if (!this.schema) {
      this.schema = await this.schemaCache.schemaFrom(this.seedModels);
    }
    return this.schema;
  }
}
<|endoftext|>


<commit_before>/*
 * Multi-inheritance with mixin and es6 class
 */
function mix(...mixins) {
    class Mix {}
    // 以编程方式给Mix类添加
    // mixins的所有方法和访问器
    for (let mixin of mixins) {
        copyProperties(Mix, mixin);
        copyProperties(Mix.prototype, mixin.prototype);
    }
    return Mix;
}

function copyProperties(target, source) {
    for (let key of Reflect.ownKeys(source)) {
        if (key !== "constructor" && key !== "prototype" && key !== "name") {
            let desc = Object.getOwnPropertyDescriptor(source, key);
            Object.defineProperty(target, key, desc);
        }
    }
}

/*
 * Static prop on class
 */
class T {
    constructor(opts){
        this._a = 's';
    }
}

T.propp = "pppp";

print("T.propp: ");
print(T.propp);<commit_msg>Added an essential class sample.<commit_after>/**
 * 1. Essense of es6 class, with 6 differences from es5 proto func class

   let Class = class ClassName {
      constructor(name) {
          this.name = name;
      }

      sayName() {
          console.log(this.name);
      }
  };

 */
// 1.1 can't hoisted by being let
let Class = (function() {

  "use strict"; // 1.2 always strict mode inside

  // 1.3 forbid overwrite class name internally by being const
  const ClassName = function(name) {
    // 1.4 make sure the function was called with new
    if (typeof new.target === "undefined") {
      throw new Error("Constructor must be called with new.");
    }

    this.name = name;
  }

  Object.defineProperty(ClassName.prototype, "sayName", {
    value: function() {

      // 1.5 make sure the method wasn't called with new
      if (typeof new.target !== "undefined") {
        throw new Error("Method cannot be called with new.");
      }

      console.log(this.name);
    },
    enumerable: false, // 1.6 can't enum methods
    writable: true,
    configurable: true
  });

  return ClassName;
}());

// ------------------------------
//  to be verified
// ------------------------------
/*
 * Multi-inheritance with mixin and es6 class
 */
function mix(...mixins) {
  class Mix {}
  // 以编程方式给Mix类添加
  // mixins的所有方法和访问器
  for (let mixin of mixins) {
    copyProperties(Mix, mixin);
    copyProperties(Mix.prototype, mixin.prototype);
  }
  return Mix;
}

function copyProperties(target, source) {
  for (let key of Reflect.ownKeys(source)) {
    if (key !== "constructor" && key !== "prototype" && key !== "name") {
      let desc = Object.getOwnPropertyDescriptor(source, key);
      Object.defineProperty(target, key, desc);
    }
  }
}

/*
 * Static prop on class
 */
class T {
  constructor(opts) {
    this._a = 's';
  }
}

T.propp = "pppp";

print("T.propp: ");
print(T.propp);
<|endoftext|>


<commit_before>define(['js/data/Entity', 'sprd/entity/Offset', 'sprd/entity/Size', 'sprd/entity/PrintArea', 'sprd/model/PrintType', 'js/core/List' , "sprd/entity/Price", "sprd/type/Matrix2d", "sprd/util/ProductUtil"], function (Entity, Offset, Size, PrintArea, PrintType, List, Price, Matrix2d, ProductUtil) {

    var undefined;

    return Entity.inherit('sprd.entity.Configuration', {

        schema: {
            offset: Offset,
            printArea: {
                type: PrintArea,
                isReference: true
            },
            printType: PrintType
        },

        defaults: {
            printArea: null,
            printType: null,
            offset: Offset,
            scale: {
                x: 1,
                y: 1
            },
            rotation: 0,
            printColors: List,

            // bind this
            _size: "{size()}",
            _x: "{offset.x}",
            _y: "{offset.y}",

            _printTypePrice: "{printType.price}"
        },

        ctor: function(){
            this.callBase();

            function triggerConfigurationChanged(e){
                this.trigger('configurationChanged');
            }

            this.bind('change:offset',function(e){
                if(e.$ && !e.$.isDeepEqual(this.$previousAttributes["offset"])){
                    this.trigger('configurationChanged');
                }
            }, this);
            this.bind('change:scale',triggerConfigurationChanged, this);
            this.bind('change:rotation',triggerConfigurationChanged, this);
            this.bind('change:printArea',triggerConfigurationChanged, this);
            this.bind('change:printColors',triggerConfigurationChanged, this);
        },

        _commitChangedAttributes: function ($) {
            this._validateTransform($);
        },

        _validateTransform: function ($) {

            var rotationChanged = this._hasSome($, ["rotation"]),
                sizeChanged = this._hasSome($, ["_size", "_x", "_y", "scale", "offset"]),
                printTypeChanged = this._hasSome($, ["printType"]),
                width, height,
                scale = $.scale || this.$.scale,
                rotation = $.rotation || this.$.rotation;

            if (sizeChanged || rotationChanged) {
                width = this.width(scale.x);
                height = this.height(scale.y);
                this._setError("hardBoundary", this._hasHardBoundaryError($.offset || this.$.offset, width, height, rotation, scale));
            }

            if (sizeChanged || printTypeChanged) {
                width = width || this.width();
                height = height || this.height();

                this._validatePrintTypeSize(this.$.printType, width, height, scale);
            }

        },

        _validatePrintTypeSize: function (printType, width, height, scale) {
            if (!printType) {
                return;
            }

            this._setError({
                printTypeScaling: !printType.isScalable() && (scale.x != 1 || scale.y != 1),
                printTypeEnlarged: printType.isShrinkable() && Math.min(scale.x, scale.y) > 1,
                maxBounds: width > printType.get("size.width") || height > printType.get("size.height")
            });
        },

        _hasHardBoundaryError: function (offset, width, height, rotation, scale) {

            var printArea = this.$.printArea;

            if (!(printArea && offset)) {
                return;
            }

            var boundingBox = this._getBoundingBox(offset,width,height, rotation, scale);

            return !(boundingBox.x >= 0 && boundingBox.y >= 0 &&
                (boundingBox.x + boundingBox.width) <= printArea.get("boundary.size.width") &&
                (boundingBox.y + boundingBox.height) <= printArea.get("boundary.size.height"));

        },

        _getBoundingBox: function(offset, width, height, rotation, scale) {

            var x = offset.$.x,
                y = offset.$.y;

            if (!rotation) {
                return {
                    x: x,
                    y: y,
                    height: height,
                    width: width
                };
            }

            var minX,
                maxX,
                minY,
                maxY,
                matrix = new Matrix2d().rotateDeg(rotation);

            var halfW = width / 2,
                halfH = height /2;

            var points = [
                [-halfW, -halfH],
                [halfW, -halfH],
                [halfW, halfH],
                [-halfW, halfH]
            ];

            var point = matrix.transformPoint(points[0]);
            minX = maxX = point[0];
            minY = maxY = point[1];

            for (var i = 1; i < points.length; i++) {
                point = matrix.transformPoint(points[i]);

                minX = Math.min(point[0], minX);
                maxX = Math.max(point[0], maxX);
                minY = Math.min(point[1], minY);
                maxY = Math.max(point[1], maxY);
            }

            return {
                x: minX + halfW + x,
                y: minY + halfH + y,
                width: maxX - minX,
                height: maxY - minY
            };

        },

        size: function () {
            this.log("size() not implemented", "debug");
            return null;
        },

        height: function (scale) {

            if (!scale && scale !== 0) {
                scale = this.$.scale.y;
            }

            return Math.abs(this.size().$.height * scale);
        }.onChange("scale", "size()"),

        width: function (scale) {

            if (!scale && scale !== 0) {
                scale = this.$.scale.x;
            }

            return Math.abs(this.size().$.width * scale);
        }.onChange("scale", "size()"),

        isScalable: function () {
            return this.get("printType.isScalable()");
        }.onChange("printType"),

        isRotatable: function () {
            return true;
        },

        isRemovable: function () {
            return true;
        },

        price: function () {
            return this.get('_printTypePrice').clone() || new Price();
        },

        possiblePrintTypes: function(appearance) {
            var ret = [],
                printArea = this.$.printArea;

            if (printArea && appearance) {
                ret = ProductUtil.getPossiblePrintTypesForPrintAreas([printArea], appearance.$.id);
            }

            return ret;
        }.onChange("printArea")
    });
});
<commit_msg>fixed empty size problem ...<commit_after>define(['js/data/Entity', 'sprd/entity/Offset', 'sprd/entity/Size', 'sprd/entity/PrintArea', 'sprd/model/PrintType', 'js/core/List' , "sprd/entity/Price", "sprd/type/Matrix2d", "sprd/util/ProductUtil"], function (Entity, Offset, Size, PrintArea, PrintType, List, Price, Matrix2d, ProductUtil) {

    var undefined;

    return Entity.inherit('sprd.entity.Configuration', {

        schema: {
            offset: Offset,
            printArea: {
                type: PrintArea,
                isReference: true
            },
            printType: PrintType
        },

        defaults: {
            printArea: null,
            printType: null,
            offset: Offset,
            scale: {
                x: 1,
                y: 1
            },
            rotation: 0,
            printColors: List,

            // bind this
            _size: "{size()}",
            _x: "{offset.x}",
            _y: "{offset.y}",

            _printTypePrice: "{printType.price}"
        },

        ctor: function(){
            this.callBase();

            function triggerConfigurationChanged(e){
                this.trigger('configurationChanged');
            }

            this.bind('change:offset',function(e){
                if(e.$ && !e.$.isDeepEqual(this.$previousAttributes["offset"])){
                    this.trigger('configurationChanged');
                }
            }, this);
            this.bind('change:scale',triggerConfigurationChanged, this);
            this.bind('change:rotation',triggerConfigurationChanged, this);
            this.bind('change:printArea',triggerConfigurationChanged, this);
            this.bind('change:printColors',triggerConfigurationChanged, this);
        },

        _commitChangedAttributes: function ($) {
            this._validateTransform($);
        },

        _validateTransform: function ($) {

            var rotationChanged = this._hasSome($, ["rotation"]),
                sizeChanged = this._hasSome($, ["_size", "_x", "_y", "scale", "offset"]),
                printTypeChanged = this._hasSome($, ["printType"]),
                width, height,
                scale = $.scale || this.$.scale,
                rotation = $.rotation || this.$.rotation;

            if (sizeChanged || rotationChanged) {
                width = this.width(scale.x);
                height = this.height(scale.y);
                this._setError("hardBoundary", this._hasHardBoundaryError($.offset || this.$.offset, width, height, rotation, scale));
            }

            if (sizeChanged || printTypeChanged) {
                width = width || this.width();
                height = height || this.height();

                this._validatePrintTypeSize(this.$.printType, width, height, scale);
            }

        },

        _validatePrintTypeSize: function (printType, width, height, scale) {
            if (!printType) {
                return;
            }

            this._setError({
                printTypeScaling: !printType.isScalable() && (scale.x != 1 || scale.y != 1),
                printTypeEnlarged: printType.isShrinkable() && Math.min(scale.x, scale.y) > 1,
                maxBounds: width > printType.get("size.width") || height > printType.get("size.height")
            });
        },

        _hasHardBoundaryError: function (offset, width, height, rotation, scale) {

            var printArea = this.$.printArea;

            if (!(printArea && offset)) {
                return;
            }

            var boundingBox = this._getBoundingBox(offset,width,height, rotation, scale);

            return !(boundingBox.x >= 0 && boundingBox.y >= 0 &&
                (boundingBox.x + boundingBox.width) <= printArea.get("boundary.size.width") &&
                (boundingBox.y + boundingBox.height) <= printArea.get("boundary.size.height"));

        },

        _getBoundingBox: function(offset, width, height, rotation, scale) {

            var x = offset.$.x,
                y = offset.$.y;

            if (!rotation) {
                return {
                    x: x,
                    y: y,
                    height: height,
                    width: width
                };
            }

            var minX,
                maxX,
                minY,
                maxY,
                matrix = new Matrix2d().rotateDeg(rotation);

            var halfW = width / 2,
                halfH = height /2;

            var points = [
                [-halfW, -halfH],
                [halfW, -halfH],
                [halfW, halfH],
                [-halfW, halfH]
            ];

            var point = matrix.transformPoint(points[0]);
            minX = maxX = point[0];
            minY = maxY = point[1];

            for (var i = 1; i < points.length; i++) {
                point = matrix.transformPoint(points[i]);

                minX = Math.min(point[0], minX);
                maxX = Math.max(point[0], maxX);
                minY = Math.min(point[1], minY);
                maxY = Math.max(point[1], maxY);
            }

            return {
                x: minX + halfW + x,
                y: minY + halfH + y,
                width: maxX - minX,
                height: maxY - minY
            };

        },

        size: function () {
            this.log("size() not implemented", "debug");
            return Size.empty;
        },

        height: function (scale) {

            if (!scale && scale !== 0) {
                scale = this.$.scale.y;
            }

            return Math.abs(this.size().$.height * scale);
        }.onChange("scale", "size()"),

        width: function (scale) {

            if (!scale && scale !== 0) {
                scale = this.$.scale.x;
            }

            return Math.abs(this.size().$.width * scale);
        }.onChange("scale", "size()"),

        isScalable: function () {
            return this.get("printType.isScalable()");
        }.onChange("printType"),

        isRotatable: function () {
            return true;
        },

        isRemovable: function () {
            return true;
        },

        price: function () {
            return this.get('_printTypePrice').clone() || new Price();
        },

        possiblePrintTypes: function(appearance) {
            var ret = [],
                printArea = this.$.printArea;

            if (printArea && appearance) {
                ret = ProductUtil.getPossiblePrintTypesForPrintAreas([printArea], appearance.$.id);
            }

            return ret;
        }.onChange("printArea")
    });
});
<|endoftext|>