<commit_before>const nestedRoutesToTest = [
  { url: "/networking/networks", parentMenuLabel: "Networking" },
  { url: "/settings/repositories", parentMenuLabel: "Settings" },
  { url: "/organization/users", parentMenuLabel: "Organization" }
];

describe("Sidebar", function() {
  beforeEach(function() {
    cy.configureCluster({
      mesos: "1-task-healthy",
      componentHealth: false
    });
  });

  context("Sidebar Items", function() {
    it("opens nested items in the sidebar when clicked", function() {
      cy.visitUrl({ url: "/dashboard", identify: true, fakeAnalytics: true });

      cy.get(".sidebar-sections .sidebar-menu-item")
        .contains("Settings")
        .as("settingsMenuItem");

      // The menu item should not contain a nested list.
      cy.get("@settingsMenuItem").should(function($anchorTag) {
        const $parentMenuItem = $anchorTag.closest("li.sidebar-menu-item");
        expect($parentMenuItem.hasClass("open")).to.equal(false);
        expect($parentMenuItem.find("ul li").length).to.equal(0);
      });

      cy.get("@settingsMenuItem").click();

      // Now the menu item should be expanded, so it contains a nested list.
      cy.get("@settingsMenuItem").should(function($anchorTag) {
        const $parentMenuItem = $anchorTag.closest("li.sidebar-menu-item");
        expect($parentMenuItem.hasClass("open")).to.equal(true);
        expect($parentMenuItem.find("ul li").length).to.equal(1);
      });
    });

    it("marks the active tab as selected", function() {
      cy.visitUrl({ url: "/dashboard", identify: true, fakeAnalytics: true });

      cy.get(".sidebar-sections .sidebar-menu-item")
        .contains("Jobs")
        .as("jobsMenuItem");

      // The jobs menu item should not be marked as selected.
      cy.get("@jobsMenuItem").should(function($anchorTag) {
        const $liElement = $anchorTag.closest("li");
        expect($liElement.hasClass("selected")).to.equal(false);
      });

      cy.get("@jobsMenuItem").click();

      // The jobs menu item should be marked as selected.
      cy.get("@jobsMenuItem").should(function($anchorTag) {
        const $liElement = $anchorTag.closest("li");
        expect($liElement.hasClass("selected")).to.equal(true);
      });
    });

    nestedRoutesToTest.forEach(function(nestedRoute) {
      it(`renders nested route ${
        nestedRoute.url
      } with parent selected when visiting directly`, function() {
        cy.visitUrl({
          url: nestedRoute.url,
          identify: true,
          fakeAnalytics: true
        });

        cy.get(".sidebar-sections .sidebar-menu-item")
          .contains(nestedRoute.parentMenuLabel)
          .as("parentMenuItem");

        // Now the menu item should be expanded, so it contains a nested list
        // with at least one item.
        cy.get("@parentMenuItem").should(function($anchorTag) {
          const $parentMenuItem = $anchorTag.closest("li.sidebar-menu-item");
          expect($parentMenuItem.hasClass("open")).to.equal(true);
          expect($parentMenuItem.find("ul li").length).to.be.at.least(1);
        });
      });
    });
  });

  context("Sidebar Wrapper", function() {
    it("is exactly the same width as the sidebar", function() {
      cy.get(".sidebar").then(function($sidebar) {
        const sidebarWidth = $sidebar.get(0).getBoundingClientRect().width;

        cy.get(".sidebar-wrapper").then(function($sidebarWrapper) {
          expect($sidebarWrapper.get(0).getBoundingClientRect().width).to.equal(
            sidebarWidth
          );
        });
      });
    });
  });

  context("User Account Menu", function() {
    beforeEach(function() {
      cy.visitUrl({ url: "/dashboard", identify: true, fakeAnalytics: true });
    });

    it("has a click-target with exactly the same width as the sidebar", function() {
      cy.get(".sidebar").then(function($sidebar) {
        const sidebarWidth = $sidebar.get(0).getBoundingClientRect().width;

        cy.get(".header-dropdown").then(function($clickTarget) {
          expect($clickTarget.get(0).getBoundingClientRect().width).to.equal(
            sidebarWidth
          );
        });
      });
    });

    it("has a click-target whose children are not any wider than the sidebar itself", function() {
      cy.get(".header-dropdown").then(function($clickTarget) {
        const targetWidth = $clickTarget.get(0).getBoundingClientRect().width;

        cy.get(".header-dropdown *").then(function($children) {
          $children.each(function(index, child) {
            expect(child.getBoundingClientRect().width).to.be.lessThan(
              targetWidth
            );
          });
        });
      });
    });
  });

  // TODO: remove skip when sidebar new header toggle enabled
  context.skip("Sidebar toggle", function() {
    beforeEach(function() {
      cy.clearLocalStorage();
      cy.visitUrl({ url: "/dashboard", identify: true, fakeAnalytics: true });
    });

    it("adds the proper class to the .sidebar-wrapper element", function() {
      cy.get(".application-wrapper").then(function($sidebarWrapper) {
        expect($sidebarWrapper.hasClass("sidebar-docked")).to.equal(true);
      });
    });

    it("close/open sidebar when sidebarToggle button clicked", function() {
      // close sidebar
      cy.get(".page-header-sidebar-toggle").click();
      cy.get(".sidebar-visible").should("not.exist");

      // open sidebar
      cy.get(".page-header-sidebar-toggle").click();
      cy.get(".sidebar-visible").should("exist");
    });

    it("automatically close sidebar when view is mobile/tablet", function() {
      cy.viewport("iphone-6");
      cy.get(".sidebar-visible.sidebar-docked").should("not.exist");

      // reset viewport back
      cy.viewport("macbook-15");
    });

    it("display overlay when sidebar is open on mobile/tablet", function() {
      cy.viewport("iphone-6");

      cy.get(".sidebar-visible.sidebar-docked").should("exist");
      cy.get(".sidebar-backdrop").should("exist");
    });

    it("close Sidebar clicking on overlay when sidebar is open on mobile/tablet", function() {
      cy.viewport("iphone-6");
      cy.get(".sidebar-backdrop").click({ force: true });
      cy.get(".sidebar-backdrop").should("not.exist");
    });
  });
});
<commit_msg>fix(Sidebar-cy.js): fix sidebar tests to account for header bar height<commit_after>const HEADER_BAR_HEIGHT = 32;

const nestedRoutesToTest = [
  { url: "/networking/networks", parentMenuLabel: "Networking" },
  { url: "/settings/repositories", parentMenuLabel: "Settings" },
  { url: "/organization/users", parentMenuLabel: "Organization" }
];

describe("Sidebar", function() {
  beforeEach(function() {
    cy.configureCluster({
      mesos: "1-task-healthy",
      componentHealth: false
    });
  });

  context("Sidebar Items", function() {
    it("opens nested items in the sidebar when clicked", function() {
      cy.visitUrl({ url: "/dashboard", identify: true, fakeAnalytics: true });

      cy.get(".sidebar-sections .sidebar-menu-item")
        .contains("Settings")
        .as("settingsMenuItem");

      // The menu item should not contain a nested list.
      cy.get("@settingsMenuItem").should(function($anchorTag) {
        const $parentMenuItem = $anchorTag.closest("li.sidebar-menu-item");
        expect($parentMenuItem.hasClass("open")).to.equal(false);
        expect($parentMenuItem.find("ul li").length).to.equal(0);
      });

      cy.get("@settingsMenuItem").click();

      // Now the menu item should be expanded, so it contains a nested list.
      cy.get("@settingsMenuItem").should(function($anchorTag) {
        const $parentMenuItem = $anchorTag.closest("li.sidebar-menu-item");
        expect($parentMenuItem.hasClass("open")).to.equal(true);
        expect($parentMenuItem.find("ul li").length).to.equal(1);
      });
    });

    it("marks the active tab as selected", function() {
      cy.visitUrl({ url: "/dashboard", identify: true, fakeAnalytics: true });

      cy.get(".sidebar-sections .sidebar-menu-item")
        .contains("Jobs")
        .as("jobsMenuItem");

      // The jobs menu item should not be marked as selected.
      cy.get("@jobsMenuItem").should(function($anchorTag) {
        const $liElement = $anchorTag.closest("li");
        expect($liElement.hasClass("selected")).to.equal(false);
      });

      cy.get("@jobsMenuItem").click();

      // The jobs menu item should be marked as selected.
      cy.get("@jobsMenuItem").should(function($anchorTag) {
        const $liElement = $anchorTag.closest("li");
        expect($liElement.hasClass("selected")).to.equal(true);
      });
    });

    nestedRoutesToTest.forEach(function(nestedRoute) {
      it(`renders nested route ${
        nestedRoute.url
      } with parent selected when visiting directly`, function() {
        cy.visitUrl({
          url: nestedRoute.url,
          identify: true,
          fakeAnalytics: true
        });

        cy.get(".sidebar-sections .sidebar-menu-item")
          .contains(nestedRoute.parentMenuLabel)
          .as("parentMenuItem");

        // Now the menu item should be expanded, so it contains a nested list
        // with at least one item.
        cy.get("@parentMenuItem").should(function($anchorTag) {
          const $parentMenuItem = $anchorTag.closest("li.sidebar-menu-item");
          expect($parentMenuItem.hasClass("open")).to.equal(true);
          expect($parentMenuItem.find("ul li").length).to.be.at.least(1);
        });
      });
    });
  });

  context("Sidebar Wrapper", function() {
    it("is exactly the same width as the sidebar", function() {
      cy.get(".sidebar").then(function($sidebar) {
        const sidebarWidth = $sidebar.get(0).getBoundingClientRect().width;

        cy.get(".sidebar-wrapper").then(function($sidebarWrapper) {
          expect($sidebarWrapper.get(0).getBoundingClientRect().width).to.equal(
            sidebarWidth
          );
        });
      });
    });
  });

  context("User Account Menu", function() {
    beforeEach(function() {
      cy.visitUrl({ url: "/dashboard", identify: true, fakeAnalytics: true });
    });

    it("has a click-target with exactly the same width as the sidebar", function() {
      cy.get(".sidebar").then(function($sidebar) {
        const sidebarWidth = $sidebar.get(0).getBoundingClientRect().width;

        cy.get(".header-dropdown").then(function($clickTarget) {
          expect($clickTarget.get(0).getBoundingClientRect().width).to.equal(
            sidebarWidth
          );
        });
      });
    });

    it("has a click-target whose children are not any wider than the sidebar itself", function() {
      cy.get(".header-dropdown").then(function($clickTarget) {
        const targetWidth = $clickTarget.get(0).getBoundingClientRect().width;

        cy.get(".header-dropdown *").then(function($children) {
          $children.each(function(index, child) {
            expect(child.getBoundingClientRect().width).to.be.lessThan(
              targetWidth
            );
          });
        });
      });
    });
  });

  // TODO: remove skip when sidebar new header toggle enabled
  context.skip("Sidebar toggle", function() {
    beforeEach(function() {
      cy.clearLocalStorage();
      cy.visitUrl({ url: "/dashboard", identify: true, fakeAnalytics: true });
    });

    it("adds the proper class to the .sidebar-wrapper element", function() {
      cy.get(".application-wrapper").then(function($sidebarWrapper) {
        expect($sidebarWrapper.hasClass("sidebar-docked")).to.equal(true);
      });
    });

    it("close/open sidebar when sidebarToggle button clicked", function() {
      // close sidebar
      cy.get(".page-header-sidebar-toggle").click();
      cy.get(".sidebar-visible").should("not.exist");

      // open sidebar
      cy.get(".page-header-sidebar-toggle").click();
      cy.get(".sidebar-visible").should("exist");
    });

    it("automatically close sidebar when view is mobile/tablet", function() {
      cy.viewport("iphone-6");
      cy.get(".sidebar-visible.sidebar-docked").should("not.exist");

      // reset viewport back
      cy.viewport("macbook-15");
    });

    it("display overlay when sidebar is open on mobile/tablet", function() {
      cy.viewport("iphone-6");

      cy.get(".sidebar-visible.sidebar-docked").should("exist");
      cy.get(".sidebar-backdrop").should("exist");
    });

    it("close Sidebar clicking on overlay when sidebar is open on mobile/tablet", function() {
      cy.viewport("iphone-6");
      cy.get(".sidebar-backdrop").click({ force: true });
      cy.get(".sidebar-backdrop").should("not.exist");
    });

    it("moves the sidebar content offscreen when it is undocked", function() {
      cy.get(".sidebar-dock-trigger").click();

      // We need to wait for the sidebar's transition to end.
      cy.wait(500)
        .get(".sidebar")
        .then(function($sidebar) {
          const sidebarRect = $sidebar.get(0).getBoundingClientRect();

          // Assert that the sidebar's dimensions are outside of the viewport.
          expect(sidebarRect.left).to.be.lessThan(0);
          expect(sidebarRect.left).to.equal(sidebarRect.width * -1);
          expect(sidebarRect.right).to.equal(0);
        });
    });

    it("expands the page content to fill the viewport when sidebar is undocked", function() {
      cy.get(".sidebar-dock-trigger").click();

      // We need to wait for the sidebar's transition to end.
      cy.wait(500)
        .get(".page")
        .then(function($page) {
          const pageRect = $page.get(0).getBoundingClientRect();

          expect(pageRect.left).to.equal(0);
          expect(pageRect.top).to.equal(HEADER_BAR_HEIGHT);

          cy.window().then(function($window) {
            expect(pageRect.right).to.equal($window.innerWidth);
            expect(pageRect.bottom).to.equal($window.innerHeight);
          });
        });
    });

    it("enters the viewport when the hamburger menu in the page header is clicked", function() {
      cy.get(".sidebar-dock-trigger").click();

      // We need to wait for the sidebar's exiting transition to end.
      cy.wait(500);

      // Let's first ensure that the sidebar is actually out of the viewport.
      cy.get(".sidebar").then(function($sidebar) {
        const sidebarRect = $sidebar.get(0).getBoundingClientRect();
        expect(sidebarRect.left).to.be.lessThan(0);
        expect(sidebarRect.right).to.equal(0);
      });

      cy.get(".page-header-sidebar-toggle").click();

      // We need to wait for the sidebar's entrance transition to end.
      cy.wait(500);

      cy.get(".sidebar").then(function($sidebar) {
        const sidebarRect = $sidebar.get(0).getBoundingClientRect();
        expect(sidebarRect.left).to.equal(0);
        expect(sidebarRect.right).to.be.greaterThan(0);
        expect(sidebarRect.right).to.equal(sidebarRect.width);
      });
    });

    it("renders on top of the page content when its visibility is toggled in undocked mode", function() {
      cy.get(".sidebar-dock-trigger").click();

      // We need to wait for the sidebar's exiting transition to end.
      cy.wait(500);

      cy.get(".page-header-sidebar-toggle").click();

      // We need to wait for the sidebar's entrance transition to end.
      cy.wait(500);

      cy.get(".page").then(function($page) {
        const pageRect = $page.get(0).getBoundingClientRect();
        expect(pageRect.left).to.equal(0);
      });

      cy.get(".sidebar-backdrop").click();

      // We need to wait for the sidebar's exit transition to end.
      cy.wait(500);

      cy.get(".sidebar").then(function($sidebar) {
        const sidebarRect = $sidebar.get(0).getBoundingClientRect();
        expect(sidebarRect.left).to.be.lessThan(0);
        expect(sidebarRect.right).to.equal(0);
      });
    });
  });
});
<|endoftext|>


<commit_before>var args = arguments[0] || {},
	enabled = true;

// custom properties that can/should be set in the TSS of the view where you're putting the tabbed bar
var selectedButtonColor = args.selectedButtonColor || "#d9bc1b",
	unselectedButtonColor = args.unselectedButtonColor || "#226e92",
	selectedButtonTextColor = args.selectedButtonTextColor || "#fff",
	unselectedButtonTextColor = args.unselectedButtonTextColor || "#000",
	disabledTextColor = args.disabledTextColor || '#aaa',
	disabledButtonBackgroundColor = args.disabledButtonBackgroundColor || '#444',
	borderColor = args.borderColor || 'transparent',
	font = args.font || (OS_IOS ? {
		fontFamily: 'Avenir-Light',
		fontSize: 11
	} : {
		fontWeight: 'normal',
		fontSize: '15dp'
	});

args.borderColor = borderColor; // stuff this back in there in case it's not set in the tss

$.segCtrlWrapper.applyProperties(_.omit(args, 'id', '__parentSymbol', '__itemTemplate', '$model', 'selectedButtonColor', 'unselectedButtonColor', 'selectedButtonTextColor', 'unselectedButtonTextColor', 'font'));

var height = ((isNaN(parseInt($.segCtrlWrapper.height))) ? 40 : parseInt($.segCtrlWrapper.height)) - 2;
if (OS_ANDROID) {
	height += 'dp';
}
$.segCtrlButtonContainer.height = Ti.UI.FILL;

var callback = function () {}; // empty function as placeholder

var buttons = [];
exports.init = function (labels, cb) {
	var wrapperWidthIsCalculated = false,
		calculatedWidth;
	if (typeof cb === 'function') {
		callback = cb;
	}
	if (!labels || !_.isArray(labels) || labels.length === 0) {
		labels = ['Yes', 'No'];
	}
	// calculate button width
	if (OS_ANDROID) {
		if ($.segCtrlWrapper.width.slice(-1) === '%') {
			calculatedWidth = Ti.Platform.displayCaps.platformWidth / Ti.Platform.displayCaps.logicalDensityFactor * parseInt($.segCtrlWrapper.width) / 100;
		} else if (isNaN(parseInt($.segCtrlWrapper.width))) {
			calculatedWidth = Ti.Platform.displayCaps.platformWidth / Ti.Platform.displayCaps.logicalDensityFactor;
			wrapperWidthIsCalculated = true;
		}
	} else if (OS_IOS) {
		if ($.segCtrlWrapper.width.slice(-1) === '%') {
			calculatedWidth = Ti.Platform.displayCaps.platformWidth * parseInt($.segCtrlWrapper.width) / 100;
			// console.log('Calculated the width of ' + args.id + ' to be ' + calculatedWidth);
		} else if (isNaN(parseInt($.segCtrlWrapper.width))) {
			// iOS handles rotation, but the wrapper width needs to be calculated to be
			// the smaller of the height or width to avoid layout issues
			if (Ti.Platform.displayCaps.platformWidth < Ti.Platform.displayCaps.platformHeight) {
				calculatedWidth = Ti.Platform.displayCaps.platformWidth;
			} else {
				calculatedWidth = Ti.Platform.displayCaps.platformHeight;
			}
		}
	}

	var btnWidth = calculatedWidth / labels.length;
	if (OS_ANDROID) {
		btnWidth += 'dp';
	}

	// make our buttons
	for (var i = 0, j = labels.length; i < j; i++) {
		if (!wrapperWidthIsCalculated && i === j - 1 && !onThreeDPDevice()) {
			// if an explicit width has been set, we need to shrink the last button
			// by 1 or it will be too wide for the container and won't be shown
			btnWidth = (parseInt(btnWidth) - 1);

			if (OS_ANDROID) {
				btnWidth += 'dp';
			}
		}
		var btn = Widget.createController('button', { // jshint ignore:line
			text: labels[i],
			width: btnWidth,
			height: Ti.UI.FILL,
			left: 0,
			top: 0,
			bottom: 0,
			color: unselectedButtonTextColor,
			backgroundColor: unselectedButtonColor,
			font: font
		}).getView();
		if (args.index === i) {
			_highlight(btn);
		}
		buttons.push(btn);
		$.segCtrlButtonContainer.add(btn);
	}

	// add the button dividers, if desired
	if (args.withDividers) {
		var left;
		for (var i = 0, j = labels.length - 1; i < j; i++) { // jshint ignore:line
			left = OS_ANDROID ? ((parseInt(btnWidth) * (i + 1) + 1) + 'dp') : (btnWidth * (i + 1) + (!onThreeDPDevice() ? 1 : -1));
			$.segCtrlWrapper.add(Ti.UI.createView({
				width: OS_ANDROID ? '1dp' : 1,
				height: height,
				left: left,
				backgroundColor: selectedButtonColor,
				zIndex: 10
			}));
		}
	}

	// event listener on the wrapper determines button clicked by x coord of click location
	$.segCtrlWrapper.addEventListener('click', function (e) {
		var clickedButton,
			butWid;
		var point = e.source.convertPointToView({
			x: e.x,
			y: e.y
		}, $.segCtrlWrapper);
		if (OS_ANDROID) {
			butWid = parseFloat(btnWidth.replace('dp', '')) * Ti.Platform.displayCaps.logicalDensityFactor;
			clickedButton = Math.floor(point.x / butWid);
		} else {
			butWid = btnWidth;
			clickedButton = Math.floor(point.x / butWid);
		}
		if (buttons[clickedButton].disabled) {
			return;
		}
		_.each(buttons, function (element, index) {
			if (enabled) {
				if (index === clickedButton) {
					_highlight(element);
				} else {
					_unhighlight(element);
				}
			}
		});
		callback({
			index: clickedButton,
			source: {
				id: args.id || undefined
			}
		});
	});
};

function _highlight(btn) {
	if (btn) {
		btn.backgroundColor = selectedButtonColor;
		btn.color = selectedButtonTextColor;
	}
}

function _unhighlight(btn) {
	if (!btn.disabled) {
		btn.backgroundColor = unselectedButtonColor;
		btn.color = unselectedButtonTextColor;
	}
}

exports.select = function (num) {
	var btnNumber = parseInt(num) || 0;
	_highlight(buttons[btnNumber]);
};
exports.setIndex = function (num) {
	var btnNumber = parseInt(num) || 0;
	exports.deselectAll();
	_highlight(buttons[btnNumber]);
};
exports.deselect = function (num) {
	var btnNumber = parseInt(num) || 0;
	_unhighlight(buttons[btnNumber]);
};
exports.enable = function () {
	enabled = true;
};
exports.disable = function () {
	enabled = false;
};
exports.deselectAll = function () {
	_.each(buttons, _unhighlight);
};

exports.changeButtonLabels = function (arr) {
	if (!arr || !arr.length || arr.length !== buttons.length) {
		throw "You must pass an array with " + buttons.length + " members to this function";
	}
	for (var b = 0, c = buttons.length; b < c; b++) {
		buttons[b].text = arr[b];
	}
};

/*
Public function to disable a button (make it non-clickable)
*/
exports.disableButton = function (num) {
	if (typeof num !== 'number' || !buttons[num]) {
		return;
	}
	// turn it semi-transparent
	// disable the click handler
	_unhighlight(buttons[num]);
	buttons[num].opacity = 0.4;
	buttons[num].color = disabledTextColor;
	buttons[num].backgroundColor = disabledButtonBackgroundColor;
	buttons[num].disabled = true;
};
exports.disableAllButtons = function () {
	for (var i = 0, j = buttons.length; i < j; i++) {
		exports.disableButton(i);
	}
};
/*
Public function to enable a button (make it clickable)
*/
exports.enableButton = function (num) {
	// turn it fully opaque
	// enable the click handler
	if (typeof num !== 'number' || !buttons[num]) {
		return;
	}
	_unhighlight(buttons[num]);
	buttons[num].opacity = 1;
	buttons[num].color = unselectedButtonTextColor;
	buttons[num].disabled = false;
};
exports.enableAllButtons = function () {
	for (var i = 0, j = buttons.length; i < j; i++) {
		exports.enableButton(i);
	}
};

function onThreeDPDevice() {
	//if we are on a 3DP device (6+ or 6s+) we need to slightly adjust the button width
	return OS_IOS && parseInt(Ti.Platform.displayCaps.logicalDensityFactor) === 3;
}<commit_msg>Fix bug in select() and add getIndex()<commit_after>var args = arguments[0] || {},
	enabled = true;

// custom properties that can/should be set in the TSS of the view where you're putting the tabbed bar
var selectedButtonColor = args.selectedButtonColor || "#d9bc1b",
	unselectedButtonColor = args.unselectedButtonColor || "#226e92",
	selectedButtonTextColor = args.selectedButtonTextColor || "#fff",
	unselectedButtonTextColor = args.unselectedButtonTextColor || "#000",
	disabledTextColor = args.disabledTextColor || '#aaa',
	disabledButtonBackgroundColor = args.disabledButtonBackgroundColor || '#444',
	borderColor = args.borderColor || 'transparent',
	font = args.font || (OS_IOS ? {
		fontFamily: 'Avenir-Light',
		fontSize: 11
	} : {
		fontWeight: 'normal',
		fontSize: '15dp'
	});

args.borderColor = borderColor; // stuff this back in there in case it's not set in the tss

$.segCtrlWrapper.applyProperties(_.omit(args, 'id', '__parentSymbol', '__itemTemplate', '$model', 'selectedButtonColor', 'unselectedButtonColor', 'selectedButtonTextColor', 'unselectedButtonTextColor', 'font'));

var height = ((isNaN(parseInt($.segCtrlWrapper.height))) ? 40 : parseInt($.segCtrlWrapper.height)) - 2;
if (OS_ANDROID) {
	height += 'dp';
}
$.segCtrlButtonContainer.height = Ti.UI.FILL;

var callback = function () {}; // empty function as placeholder
var selectedIndex = 0; // Stores the current selected index

var buttons = [];
exports.init = function (labels, cb) {
	var wrapperWidthIsCalculated = false,
		calculatedWidth;
	if (typeof cb === 'function') {
		callback = cb;
	}
	if (!labels || !_.isArray(labels) || labels.length === 0) {
		labels = ['Yes', 'No'];
	}
	// calculate button width
	if (OS_ANDROID) {
		if ($.segCtrlWrapper.width.slice(-1) === '%') {
			calculatedWidth = Ti.Platform.displayCaps.platformWidth / Ti.Platform.displayCaps.logicalDensityFactor * parseInt($.segCtrlWrapper.width) / 100;
		} else if (isNaN(parseInt($.segCtrlWrapper.width))) {
			calculatedWidth = Ti.Platform.displayCaps.platformWidth / Ti.Platform.displayCaps.logicalDensityFactor;
			wrapperWidthIsCalculated = true;
		}
	} else if (OS_IOS) {
		if ($.segCtrlWrapper.width.slice(-1) === '%') {
			calculatedWidth = Ti.Platform.displayCaps.platformWidth * parseInt($.segCtrlWrapper.width) / 100;
			// console.log('Calculated the width of ' + args.id + ' to be ' + calculatedWidth);
		} else if (isNaN(parseInt($.segCtrlWrapper.width))) {
			// iOS handles rotation, but the wrapper width needs to be calculated to be
			// the smaller of the height or width to avoid layout issues
			if (Ti.Platform.displayCaps.platformWidth < Ti.Platform.displayCaps.platformHeight) {
				calculatedWidth = Ti.Platform.displayCaps.platformWidth;
			} else {
				calculatedWidth = Ti.Platform.displayCaps.platformHeight;
			}
		}
	}

	var btnWidth = calculatedWidth / labels.length;
	if (OS_ANDROID) {
		btnWidth += 'dp';
	}

	// make our buttons
	for (var i = 0, j = labels.length; i < j; i++) {
		if (!wrapperWidthIsCalculated && i === j - 1 && !onThreeDPDevice()) {
			// if an explicit width has been set, we need to shrink the last button
			// by 1 or it will be too wide for the container and won't be shown
			btnWidth = (parseInt(btnWidth) - 1);

			if (OS_ANDROID) {
				btnWidth += 'dp';
			}
		}
		var btn = Widget.createController('button', { // jshint ignore:line
			text: labels[i],
			width: btnWidth,
			height: Ti.UI.FILL,
			left: 0,
			top: 0,
			bottom: 0,
			color: unselectedButtonTextColor,
			backgroundColor: unselectedButtonColor,
			font: font
		}).getView();
		if (args.index === i) {
			_highlight(btn);
		}
		buttons.push(btn);
		$.segCtrlButtonContainer.add(btn);
	}

	// add the button dividers, if desired
	if (args.withDividers) {
		var left;
		for (var i = 0, j = labels.length - 1; i < j; i++) { // jshint ignore:line
			left = OS_ANDROID ? ((parseInt(btnWidth) * (i + 1) + 1) + 'dp') : (btnWidth * (i + 1) + (!onThreeDPDevice() ? 1 : -1));
			$.segCtrlWrapper.add(Ti.UI.createView({
				width: OS_ANDROID ? '1dp' : 1,
				height: height,
				left: left,
				backgroundColor: selectedButtonColor,
				zIndex: 10
			}));
		}
	}

	// event listener on the wrapper determines button clicked by x coord of click location
	$.segCtrlWrapper.addEventListener('click', function (e) {
		var clickedButton,
			butWid;
		var point = e.source.convertPointToView({
			x: e.x,
			y: e.y
		}, $.segCtrlWrapper);
		if (OS_ANDROID) {
			butWid = parseFloat(btnWidth.replace('dp', '')) * Ti.Platform.displayCaps.logicalDensityFactor;
			clickedButton = Math.floor(point.x / butWid);
		} else {
			butWid = btnWidth;
			clickedButton = Math.floor(point.x / butWid);
		}
		if (buttons[clickedButton].disabled) {
			return;
		}
		_.each(buttons, function (element, index) {
			if (enabled) {
				if (index === clickedButton) {
					_highlight(element);
				} else {
					_unhighlight(element);
				}
			}
		});

		// Save current value
		selectedIndex = clickedButton;

		callback({
			index: clickedButton,
			source: {
				id: args.id || undefined
			}
		});
	});
};

function _highlight(btn) {
	if (btn) {
		btn.backgroundColor = selectedButtonColor;
		btn.color = selectedButtonTextColor;
	}
}

function _unhighlight(btn) {
	if (!btn.disabled) {
		btn.backgroundColor = unselectedButtonColor;
		btn.color = unselectedButtonTextColor;
	}
}

// Is an alias function
exports.select = function (num) {
	exports.setIndex(num);
};
exports.getIndex = function () {
	return selectedIndex;
};
exports.setIndex = function (num) {
    var btnNumber = parseInt(num) || 0;
    exports.deselectAll();
    _highlight(buttons[btnNumber]);
    selectedIndex = num;
};
exports.deselect = function (num) {
	var btnNumber = parseInt(num) || 0;
	_unhighlight(buttons[btnNumber]);
};
exports.enable = function () {
	enabled = true;
};
exports.disable = function () {
	enabled = false;
};
exports.deselectAll = function () {
	_.each(buttons, _unhighlight);
};

exports.changeButtonLabels = function (arr) {
	if (!arr || !arr.length || arr.length !== buttons.length) {
		throw "You must pass an array with " + buttons.length + " members to this function";
	}
	for (var b = 0, c = buttons.length; b < c; b++) {
		buttons[b].text = arr[b];
	}
};

/*
Public function to disable a button (make it non-clickable)
*/
exports.disableButton = function (num) {
	if (typeof num !== 'number' || !buttons[num]) {
		return;
	}
	// turn it semi-transparent
	// disable the click handler
	_unhighlight(buttons[num]);
	buttons[num].opacity = 0.4;
	buttons[num].color = disabledTextColor;
	buttons[num].backgroundColor = disabledButtonBackgroundColor;
	buttons[num].disabled = true;
};
exports.disableAllButtons = function () {
	for (var i = 0, j = buttons.length; i < j; i++) {
		exports.disableButton(i);
	}
};
/*
Public function to enable a button (make it clickable)
*/
exports.enableButton = function (num) {
	// turn it fully opaque
	// enable the click handler
	if (typeof num !== 'number' || !buttons[num]) {
		return;
	}
	_unhighlight(buttons[num]);
	buttons[num].opacity = 1;
	buttons[num].color = unselectedButtonTextColor;
	buttons[num].disabled = false;
};
exports.enableAllButtons = function () {
	for (var i = 0, j = buttons.length; i < j; i++) {
		exports.enableButton(i);
	}
};

function onThreeDPDevice() {
	//if we are on a 3DP device (6+ or 6s+) we need to slightly adjust the button width
	return OS_IOS && parseInt(Ti.Platform.displayCaps.logicalDensityFactor) === 3;
}
<|endoftext|>


<commit_before>var _und = require('underscore');
var serviceNames = require('../serviceNames');
var thirdpartyConfig = require('./3dpartyconfig');
var FacebookStrategy = require('passport-facebook').Strategy;
var GitHubStrategy = require('passport-github').Strategy;
var GoogleStrategy = require('passport-google-oauth').OAuth2Strategy;
var LinkedInStrategy = require('passport-linkedin-oauth2').Strategy;
var TwitterStrategy = require('passport-twitter').Strategy;

var logger = require('../../../utils/logger');
var util = require('../../../utils/util');

//----------experimental---
var authExperimentalFeatures = require('../common/auth-experimental-collapse-db.js');
//-------------------------

function updateUser (user, accessToken, profile, serviceName) {
  if(util.isNotSimpleCustomObjectOrDate(user)) {
    logger.error("impossible to update because user must be an object");
    throw 'impossible to update because user must be an object';
  }

  if(util.isNotSimpleCustomObjectOrDate(profile)) {
    logger.error("impossible to update because profile must be an object");
    throw 'impossible to update because profile must be an objects';
  }

  if(!_und.isString(serviceName) || !_und.isString(accessToken)) {
    logger.error("impossible to update because both serviceName and accessToken must be strings");
    throw 'impossible to update because both serviceName and accessToken must be strings';
  }

  const whitelistServices = _und.without(serviceNames, 'local', 'profile');
  if(whitelistServices.indexOf(serviceName) === -1) {
    logger.error("impossible to update because serviceName is not recognized");
    throw 'impossible to update because serviceName is not recognized';
  }

  // warning: if you are not able to set a value in user[serviceName]
  // go to models/users.js and add the missing property there.
  // common
  user[serviceName].id = profile.id;
  user[serviceName].token = accessToken;
  // other cases
  switch(serviceName) {
    case 'facebook':
      user[serviceName].name  = profile.name.givenName + ' ' + profile.name.familyName;
      user[serviceName].profileUrl = profile.profileUrl;
      user[serviceName].email = profile.emails[0].value; //get the first email
      return user;
    case 'github':
      user[serviceName].name  = profile.displayName;
      user[serviceName].username = profile.username;
      user[serviceName].profileUrl = profile.profileUrl;
      user[serviceName].email = profile.emails[0].value; //get the first email
      return user;
    case 'google':
      user[serviceName].name  = profile.displayName;
      user[serviceName].email = profile.emails[0].value; //get the first email
      return user;
    case 'linkedin':
      user[serviceName].name  = profile.name.givenName + ' ' + profile.name.familyName;
      user[serviceName].email = profile.emails[0].value; //get the first email
      return user;
    case 'twitter':
      user[serviceName].name  = profile.displayName ? profile.displayName : profile.username;
      user[serviceName].username  = profile.username;
      if(profile.emails && profile.emails[0] && profile.emails[0].value) {
        //twitter doesn't provide profile.email's field by default. You must
        //request the permission to twitter to ask email to users.
        //To be sure, I decided to check if email's field is available.
        user[serviceName].email = profile.emails[0].value; //get the first email
      }
      return user;
  }
  return user;
}

function authenticate(req, accessToken, refreshToken, profile, done, serviceName, userRef) {
  process.nextTick(() => {
    var sessionLocalUserId = req.session.localUserId;
    //check if the user is already logged in using the LOCAL authentication
    if(sessionLocalUserId) {
      console.log("sessionLocalUserId found - managing 3dauth + local");
      //the user is already logged in
      userRef.findOne({ '_id': sessionLocalUserId }, (err, user) => {
        if (err) {
          throw err;
        }
        console.log("User found - saving");
        var userUpdated = updateUser(user, accessToken, profile, serviceName);
        console.log("updated localuser with 3dpartyauth");
        userUpdated.save(err => {
          if (err) {
            throw err;
          }

          //----------------- experimental ---------------
          authExperimentalFeatures.collapseDb(user, serviceName, req)
          .then(result => {
            console.log("collapseDb localuser with 3dpartyauth promise: " + result);
            return done(null, result);
          }, reason => {
            console.log("ERROR collapseDb localuser with 3dpartyauth promise");
            return done(null, user);
          });
          //----------------------------------------------
        });
      });
    } else {
      console.log("Only 3dauth");
      if (!req.user) { //if the user is NOT already logged in
        console.log("User not already logged in");
        const serviceNameId = serviceName + '.id';

        const query = {};
        query[serviceNameId] = profile.id;

        userRef.findOne(query, (err, user) => {
          console.log("User.findOne...");
          if (err) {
            return done(err);
          }

          if (user) { // if the user is found, then log them in
            console.log("User found");
            // if there is already a user id but no token (user was linked at one point and then removed)
            // just add our token and profile informations
            var userUpdated = '';
            if (!user[serviceName].token) {
              console.log("Id is ok, but not token, updating...");
              userUpdated = updateUser(user, accessToken, profile, serviceName);
              userUpdated.save( err => {
                if (err) {
                  throw err;
                }
                return done(null, userUpdated);
              });
            }
            return done(null, user);
          } else {
            //otherwise, if there is no user found with that id, create them
            console.log("User not found with that id, creating a new one...");
            var newUser = updateUser(new userRef(), accessToken, profile, serviceName);
            console.log("New user created: " + newUser);
            newUser.save( err => {
              if (err) {
                throw err;
              }
              return done(null, newUser);
            });
          }
        });
      } else {
        // user already exists and is logged in, we have to link accounts
        // req.user pull the user out of the session
        // and finally update the user with the currecnt users credentials
        console.log("User already exists but I'm previously logged in");
        var user = updateUser(req.user, accessToken, profile, serviceName);
        user.save( (err, savedUser) => {
          if (err) {
            throw err;
          }

          console.log("Saving already existing user.");

          //----------------- experimental ---------------
          authExperimentalFeatures.collapseDb(savedUser, serviceName, req)
          .then(result => {
            console.log("collapseDb promise: " + result);
            return done(null, result);
          }, reason => {
            console.log("ERROR collapseDb promise");
            return done(null, savedUser);
          });
          //----------------------------------------------

        });
      }
    }
  });
}

function buildStrategy(serviceName, userRef) {
  console.log("service: " + serviceName + " env: " + process.env.NODE_ENV);
  switch(serviceName) {
    case 'facebook':
      return new FacebookStrategy( thirdpartyConfig[serviceName],
      (req, accessToken, refreshToken, profile, done) => { authenticate(req, accessToken, refreshToken, profile, done, serviceName, userRef);});
    case 'github':
      return new GitHubStrategy( thirdpartyConfig[serviceName],
      (req, accessToken, refreshToken, profile, done) => { authenticate(req, accessToken, refreshToken, profile, done, serviceName, userRef);});
    case 'google':
      return new GoogleStrategy( thirdpartyConfig[serviceName],
      (req, accessToken, refreshToken, profile, done) => { authenticate(req, accessToken, refreshToken, profile, done, serviceName, userRef);});
    case 'linkedin':
      return new LinkedInStrategy( thirdpartyConfig[serviceName],
      (req, accessToken, refreshToken, profile, done) => { authenticate(req, accessToken, refreshToken, profile, done, serviceName, userRef);});
    case 'twitter':
      return new TwitterStrategy( thirdpartyConfig[serviceName],
      (req, accessToken, refreshToken, profile, done) => { authenticate(req, accessToken, refreshToken, profile, done, serviceName, userRef);});
  }
}

module.exports = function (userRef, passportRef) {
  passportRef.use(buildStrategy('facebook', userRef));
  passportRef.use(buildStrategy('github', userRef));
  passportRef.use(buildStrategy('google', userRef));
  passportRef.use(buildStrategy('linkedin', userRef));
  passportRef.use(buildStrategy('twitter', userRef));

  return module;
};
<commit_msg>text updated<commit_after>var _und = require('underscore');
var serviceNames = require('../serviceNames');
var thirdpartyConfig = require('./3dpartyconfig');
var FacebookStrategy = require('passport-facebook').Strategy;
var GitHubStrategy = require('passport-github').Strategy;
var GoogleStrategy = require('passport-google-oauth').OAuth2Strategy;
var LinkedInStrategy = require('passport-linkedin-oauth2').Strategy;
var TwitterStrategy = require('passport-twitter').Strategy;

var logger = require('../../../utils/logger');
var util = require('../../../utils/util');

//----------experimental---
var authExperimentalFeatures = require('../common/auth-experimental-collapse-db.js');
//-------------------------

function updateUser (user, accessToken, profile, serviceName) {
  if(util.isNotSimpleCustomObjectOrDate(user)) {
    logger.error("impossible to update because user must be an object");
    throw 'impossible to update because user must be an object';
  }

  if(util.isNotSimpleCustomObjectOrDate(profile)) {
    logger.error("impossible to update because profile must be an object");
    throw 'impossible to update because profile must be an objects';
  }

  if(!_und.isString(serviceName) || !_und.isString(accessToken)) {
    logger.error("impossible to update because both serviceName and accessToken must be strings");
    throw 'impossible to update because both serviceName and accessToken must be strings';
  }

  const whitelistServices = _und.without(serviceNames, 'local', 'profile');
  if(whitelistServices.indexOf(serviceName) === -1) {
    logger.error("impossible to update because serviceName is not recognized");
    throw 'impossible to update because serviceName is not recognized';
  }

  // warning: if you are not able to set a value in user[serviceName]
  // go to models/users.js and add the missing property there.
  // common
  user[serviceName].id = profile.id;
  user[serviceName].token = accessToken;
  // other cases
  switch(serviceName) {
    case 'facebook':
      user[serviceName].name  = profile.name.givenName + ' ' + profile.name.familyName;
      user[serviceName].profileUrl = profile.profileUrl;
      user[serviceName].email = profile.emails[0].value; //get the first email
      return user;
    case 'github':
      user[serviceName].name  = profile.displayName;
      user[serviceName].username = profile.username;
      user[serviceName].profileUrl = profile.profileUrl;
      user[serviceName].email = profile.emails[0].value; //get the first email
      return user;
    case 'google':
      user[serviceName].name  = profile.displayName;
      user[serviceName].email = profile.emails[0].value; //get the first email
      return user;
    case 'linkedin':
      user[serviceName].name  = profile.name.givenName + ' ' + profile.name.familyName;
      user[serviceName].email = profile.emails[0].value; //get the first email
      return user;
    case 'twitter':
      user[serviceName].name  = profile.displayName ? profile.displayName : profile.username;
      user[serviceName].username  = profile.username;
      if(profile.emails && profile.emails[0] && profile.emails[0].value) {
        //twitter doesn't provide profile.email's field by default. You must
        //request the permission to twitter to ask email to users.
        //To be sure, I decided to check if email's field is available.
        user[serviceName].email = profile.emails[0].value; //get the first email
      }
      return user;
  }
  return user;
}

function authenticate(req, accessToken, refreshToken, profile, done, serviceName, userRef) {
  process.nextTick(() => {
    var sessionLocalUserId = req.session.localUserId;
    //check if the user is already logged in using the LOCAL authentication
    if(sessionLocalUserId) {
      console.log("sessionLocalUserId found - managing 3dauth + local");
      //the user is already logged in
      userRef.findOne({ '_id': sessionLocalUserId }, (err, user) => {
        if (err) {
          throw err;
        }
        console.log("User found - saving");
        var userUpdated = updateUser(user, accessToken, profile, serviceName);
        console.log("updated localuser with 3dpartyauth");
        userUpdated.save(err => {
          if (err) {
            throw err;
          }

          //----------------- experimental ---------------
          authExperimentalFeatures.collapseDb(user, serviceName, req)
          .then(result => {
            console.log("collapseDb localuser with 3dpartyauth promise: " + result);
            return done(null, result);
          }, reason => {
            console.log("ERROR collapseDb localuser with 3dpartyauth promise");
            return done(null, user);
          });
          //----------------------------------------------
        });
      });
    } else {
      console.log("Only 3dauth");
      if (!req.user) { //if the user is NOT already logged in
        console.log("User not already logged in");
        const serviceNameId = serviceName + '.id';

        const query = {};
        query[serviceNameId] = profile.id;

        userRef.findOne(query, (err, user) => {
          console.log("User.findOne...");
          if (err) {
            return done(err);
          }

          if (user) { // if the user is found, then log them in
            console.log("You aren't logged in, but I found an user on db");
            // if there is already a user id but no token (user was linked at one point and then removed)
            // just add our token and profile informations
            var userUpdated = '';
            if (!user[serviceName].token) {
              console.log("Id is ok, but not token, updating...");
              userUpdated = updateUser(user, accessToken, profile, serviceName);
              userUpdated.save( err => {
                if (err) {
                  throw err;
                }
                return done(null, userUpdated);
              });
            }
            return done(null, user);
          } else {
            //otherwise, if there is no user found with that id, create them
            console.log("User not found with that id, creating a new one...");
            var newUser = updateUser(new userRef(), accessToken, profile, serviceName);
            console.log("New user created: " + newUser);
            newUser.save( err => {
              if (err) {
                throw err;
              }
              return done(null, newUser);
            });
          }
        });
      } else {
        // user already exists and is logged in, we have to link accounts
        // req.user pull the user out of the session
        // and finally update the user with the currecnt users credentials
        console.log("User already exists and I'm previously logged in");
        var user = updateUser(req.user, accessToken, profile, serviceName);
        user.save( (err, savedUser) => {
          if (err) {
            throw err;
          }

          console.log("Saving already existing user.");

          //----------------- experimental ---------------
          authExperimentalFeatures.collapseDb(savedUser, serviceName, req)
          .then(result => {
            console.log("collapseDb promise: " + result);
            return done(null, result);
          }, reason => {
            console.log("ERROR collapseDb promise");
            return done(null, savedUser);
          });
          //----------------------------------------------

        });
      }
    }
  });
}

function buildStrategy(serviceName, userRef) {
  console.log("service: " + serviceName + " env: " + process.env.NODE_ENV);
  switch(serviceName) {
    case 'facebook':
      return new FacebookStrategy( thirdpartyConfig[serviceName],
      (req, accessToken, refreshToken, profile, done) => { authenticate(req, accessToken, refreshToken, profile, done, serviceName, userRef);});
    case 'github':
      return new GitHubStrategy( thirdpartyConfig[serviceName],
      (req, accessToken, refreshToken, profile, done) => { authenticate(req, accessToken, refreshToken, profile, done, serviceName, userRef);});
    case 'google':
      return new GoogleStrategy( thirdpartyConfig[serviceName],
      (req, accessToken, refreshToken, profile, done) => { authenticate(req, accessToken, refreshToken, profile, done, serviceName, userRef);});
    case 'linkedin':
      return new LinkedInStrategy( thirdpartyConfig[serviceName],
      (req, accessToken, refreshToken, profile, done) => { authenticate(req, accessToken, refreshToken, profile, done, serviceName, userRef);});
    case 'twitter':
      return new TwitterStrategy( thirdpartyConfig[serviceName],
      (req, accessToken, refreshToken, profile, done) => { authenticate(req, accessToken, refreshToken, profile, done, serviceName, userRef);});
  }
}

module.exports = function (userRef, passportRef) {
  passportRef.use(buildStrategy('facebook', userRef));
  passportRef.use(buildStrategy('github', userRef));
  passportRef.use(buildStrategy('google', userRef));
  passportRef.use(buildStrategy('linkedin', userRef));
  passportRef.use(buildStrategy('twitter', userRef));

  return module;
};
<|endoftext|>


<commit_before>'use strict';

// Set the jasmine fixture path
// jasmine.getFixtures().fixturesPath = 'base/';

describe('', function() {

    var module;
    var dependencies;
    dependencies = [];

    var hasModule = function(module) {
        return dependencies.indexOf(module) >= 0;
    };

    beforeEach(function() {

        // Get module
        module = angular.module('growlNotifications');
        dependencies = module.requires;
    });

    it('should load config module', function() {
        expect(hasModule('growlNotifications.config')).toBeTruthy();
    });

    it('should load filters module', function() {
        expect(hasModule('growlNotifications.filters')).toBeTruthy();
    });

    it('should load directives module', function() {
        expect(hasModule('growlNotifications.directives')).toBeTruthy();
    });

    it('should load services module', function() {
        expect(hasModule('growlNotifications.services')).toBeTruthy();
    });

});
<commit_msg>Update growlNotifications service unit tests<commit_after>'use strict';

// Set the jasmine fixture path
// jasmine.getFixtures().fixturesPath = 'base/';

describe('growlNotifications', function() {

    var module;
    var dependencies;
    dependencies = [];

    var hasModule = function(module) {
        return dependencies.indexOf(module) >= 0;
    };

    beforeEach(function() {

        // Get module
        module = angular.module('growlNotifications');
        dependencies = module.requires;
    });

    it('should load config module', function() {
        expect(hasModule('growlNotifications.config')).toBeTruthy();
    });

    it('should load filters module', function() {
        expect(hasModule('growlNotifications.filters')).toBeTruthy();
    });

    it('should load directives module', function() {
        expect(hasModule('growlNotifications.directives')).toBeTruthy();
    });

    it('should load services module', function() {
        expect(hasModule('growlNotifications.services')).toBeTruthy();
    });

});
<|endoftext|>


<commit_before>// $(document).foundation();
// $(document).foundationExtendEBI();

var mySVGsToInject = document.querySelectorAll('img.inject-me');

SVGInjector(mySVGsToInject);
var $searchInput = $('input[type="search"]')
var setupFilterable = function($current, $links, updateMethod) {
  $links.on('click', function(e) {
    e.preventDefault();
    var $el = $(e.currentTarget);
    var type = $el.data().type;
    $current.text($el.text());
    updateMethod(type);
    $links.each(function() {
      var $link = $(this);
      if (typeof($link.data().hideActive) === 'undefined') {
        if ($link.data().type === type) {
          $link.addClass('is-active');
        } else {
          $link.removeClass('is-active');
        }
      } else {
        if ($link.data().type === type) {
          $link.addClass('hide');
        } else {
          $link.removeClass('hide');
        }
      }
    });
  });
}
var params = getParams();
if($searchInput.is('*')) {
  window.search = new Search({
    input: $('input[type="search"]'),
    searchContainer: $('#search-results-container .card-container'),
    kitContainer: $('#search-results-container .kit-container'),
    initialQuery: params.q,
    onSearch: function(term, filter, sort, results, kitResults) {
      if(term.length > 0 || filter !== 'all' || sort !== 'newest') {
        $('#main-results-container').hide();
        $('#search-results-container').show();
        $('#search-results-container').foundation();
        $('#result-count').text(results.length);
      } else {
        $('#main-results-container').show();
        $('#search-results-container').hide();
        $('#result-count').text(results.length);
      }
    }
  });
  var $currentSort = $('[data-sort-current]');
  var $sortLinks = $('[data-sort]');
  setupFilterable($currentSort, $sortLinks, window.search.setSort.bind(window.search));

  var $currentFilter = $('[data-filter-current]');
  var $filterLinks = $('[data-filter]');
  setupFilterable($currentFilter, $filterLinks, window.search.setFilter.bind(window.search));
  $('#bb-search-bar').on('toggle.zf.trigger', function() {
    setTimeout( () => { $searchInput.focus();window.search.updateSearch();}, 1)
  });
}

function getParams() {
  var search = location.search.substring(1);
  return search?JSON.parse('{"' + search.replace(/&/g, '","').replace(/=/g,'":"') + '"}',
                   function(key, value) { return key===""?value:decodeURIComponent(value) }):{}
}

function toggleCode() {
  $('#codeBoxSCSS').toggleClass('is-active');
  $('#scssToggle').toggleClass('is-active');
  $('#codeBoxCSS').toggleClass('is-active');
  $('#cssToggle').toggleClass('is-active');
}

$('#scssToggle').click(function(){
  if ($('#cssToggle').hasClass('is-active')) {
    toggleCode();
  }
});

$('#cssToggle').click(function(){
  if ($('#scssToggle').hasClass('is-active')) {
    toggleCode();
  }
});

var toggleHTML = $('[data-toggle-HTML]');
var toggleSCSS = $('[data-toggle-SCSS]');
var toggleJS   = $('[data-toggle-JS]');

// toggles trigger for the code boxes
toggleHTML.click(function(e) {
  if( toggleSCSS.hasClass('is-active') || toggleJS.hasClass('.is-active') ) {
    $(this).toggleClass('is-active');
    $('#codeBoxHTML').toggleClass('is-active');
  }
  e.preventDefault();
});

toggleSCSS.click(function(e) {
  if( toggleHTML.hasClass('is-active') || toggleJS.hasClass('.is-active') ) {
    $(this).toggleClass('is-active');
    $('#codeBoxSCSS').toggleClass('is-active');
  }
  e.preventDefault();
});

toggleSCSS.click(function(e) {
  if( toggleSCSS.hasClass('is-active') || toggleJS.hasClass('.is-active') ) {
    $(this).toggleClass('is-active');
    $('#codeBoxJS').toggleClass('is-active');
  }
  e.preventDefault();
});

var socialName = $('meta[name="og:title"]').prop('content');
var socialImage = $('meta[name="og:image"]').prop('content');

var $footer = $('#footer');
var $window = $(window);

// table of contents
// Forked from https://css-tricks.com/automatic-table-of-contents/
var output = "
Table of Contents

";

$("#main-content-area h2, #main-content-area h3").each(function() {
  var el = $(this),
      title = el.text();

  // create ids if they don't yet exist
  if (el.attr("id") == undefined) {
    el.attr("id", title.split(" ").join("-").toLowerCase());
  }
  // don't insert the page title and TOC header in TOC
  if (!(el.parent().hasClass('intro')) && !(el.parent().hasClass('table-of-contents')) && !(el.hasClass('ignore-for-table-of-contents'))) {
    output += "
" + title + "
";
  }
});

output +="
";

$(".table-of-contents").html(output);

// Set iframe height for patterns
function setHeightOfPatternIframe() {
  var iframeHeightPadding = 5; // to prevent scrolling for 1px of margin or such
  if ($('#building-block-iframe').length > 0) {
    $('#building-block-iframe').css('min-height',(document.getElementById('building-block-iframe').contentWindow.document.body.scrollHeight+iframeHeightPadding)+'px')
    delayedCheckOfIframeHeight();
  }
}
setHeightOfPatternIframe();

var resizeTimer;
function delayedCheckOfIframeHeight() {
  clearTimeout(resizeTimer);
  resizeTimer = setTimeout(function() {
    setHeightOfPatternIframe();
  }, 250);

}
// Resize after user has finished resizing a window
$(window).on('resize', function(e) {
  delayedCheckOfIframeHeight();
});
<commit_msg>Even better iframe resizing!<commit_after>// $(document).foundation();
// $(document).foundationExtendEBI();

var mySVGsToInject = document.querySelectorAll('img.inject-me');

SVGInjector(mySVGsToInject);
var $searchInput = $('input[type="search"]')
var setupFilterable = function($current, $links, updateMethod) {
  $links.on('click', function(e) {
    e.preventDefault();
    var $el = $(e.currentTarget);
    var type = $el.data().type;
    $current.text($el.text());
    updateMethod(type);
    $links.each(function() {
      var $link = $(this);
      if (typeof($link.data().hideActive) === 'undefined') {
        if ($link.data().type === type) {
          $link.addClass('is-active');
        } else {
          $link.removeClass('is-active');
        }
      } else {
        if ($link.data().type === type) {
          $link.addClass('hide');
        } else {
          $link.removeClass('hide');
        }
      }
    });
  });
}
var params = getParams();
if($searchInput.is('*')) {
  window.search = new Search({
    input: $('input[type="search"]'),
    searchContainer: $('#search-results-container .card-container'),
    kitContainer: $('#search-results-container .kit-container'),
    initialQuery: params.q,
    onSearch: function(term, filter, sort, results, kitResults) {
      if(term.length > 0 || filter !== 'all' || sort !== 'newest') {
        $('#main-results-container').hide();
        $('#search-results-container').show();
        $('#search-results-container').foundation();
        $('#result-count').text(results.length);
      } else {
        $('#main-results-container').show();
        $('#search-results-container').hide();
        $('#result-count').text(results.length);
      }
    }
  });
  var $currentSort = $('[data-sort-current]');
  var $sortLinks = $('[data-sort]');
  setupFilterable($currentSort, $sortLinks, window.search.setSort.bind(window.search));

  var $currentFilter = $('[data-filter-current]');
  var $filterLinks = $('[data-filter]');
  setupFilterable($currentFilter, $filterLinks, window.search.setFilter.bind(window.search));
  $('#bb-search-bar').on('toggle.zf.trigger', function() {
    setTimeout( () => { $searchInput.focus();window.search.updateSearch();}, 1)
  });
}

function getParams() {
  var search = location.search.substring(1);
  return search?JSON.parse('{"' + search.replace(/&/g, '","').replace(/=/g,'":"') + '"}',
                   function(key, value) { return key===""?value:decodeURIComponent(value) }):{}
}

function toggleCode() {
  $('#codeBoxSCSS').toggleClass('is-active');
  $('#scssToggle').toggleClass('is-active');
  $('#codeBoxCSS').toggleClass('is-active');
  $('#cssToggle').toggleClass('is-active');
}

$('#scssToggle').click(function(){
  if ($('#cssToggle').hasClass('is-active')) {
    toggleCode();
  }
});

$('#cssToggle').click(function(){
  if ($('#scssToggle').hasClass('is-active')) {
    toggleCode();
  }
});

var toggleHTML = $('[data-toggle-HTML]');
var toggleSCSS = $('[data-toggle-SCSS]');
var toggleJS   = $('[data-toggle-JS]');

// toggles trigger for the code boxes
toggleHTML.click(function(e) {
  if( toggleSCSS.hasClass('is-active') || toggleJS.hasClass('.is-active') ) {
    $(this).toggleClass('is-active');
    $('#codeBoxHTML').toggleClass('is-active');
  }
  e.preventDefault();
});

toggleSCSS.click(function(e) {
  if( toggleHTML.hasClass('is-active') || toggleJS.hasClass('.is-active') ) {
    $(this).toggleClass('is-active');
    $('#codeBoxSCSS').toggleClass('is-active');
  }
  e.preventDefault();
});

toggleSCSS.click(function(e) {
  if( toggleSCSS.hasClass('is-active') || toggleJS.hasClass('.is-active') ) {
    $(this).toggleClass('is-active');
    $('#codeBoxJS').toggleClass('is-active');
  }
  e.preventDefault();
});

var socialName = $('meta[name="og:title"]').prop('content');
var socialImage = $('meta[name="og:image"]').prop('content');

var $footer = $('#footer');
var $window = $(window);

// table of contents
// Forked from https://css-tricks.com/automatic-table-of-contents/
var output = "
Table of Contents

";

$("#main-content-area h2, #main-content-area h3").each(function() {
  var el = $(this),
      title = el.text();

  // create ids if they don't yet exist
  if (el.attr("id") == undefined) {
    el.attr("id", title.split(" ").join("-").toLowerCase());
  }
  // don't insert the page title and TOC header in TOC
  if (!(el.parent().hasClass('intro')) && !(el.parent().hasClass('table-of-contents')) && !(el.hasClass('ignore-for-table-of-contents'))) {
    output += "
" + title + "
";
  }
});

output +="
";

$(".table-of-contents").html(output);

// Set iframe height for patterns
function setHeightOfPatternIframe() {
  var iframeHeightPadding = 5; // to prevent scrolling for 1px of margin or such
  if ($('#building-block-iframe').length > 0) {
    try {
      $('#building-block-iframe').css('min-height',(document.getElementById('building-block-iframe').contentWindow.document.body.scrollHeight+iframeHeightPadding)+'px')
    }
    catch(error) {
      setHeightOfPatternIframe(); // iframe probably wasn't fully loaded, try again
      // console.error(error);
    }
  }
}

var resizeTimer;
function delayedCheckOfIframeHeight() {
  clearTimeout(resizeTimer);
  resizeTimer = setTimeout(function() {
    setHeightOfPatternIframe();
  }, 250);

}
// Resize after user has finished resizing a window
$(window).on('resize', function(e) {
  delayedCheckOfIframeHeight();
});
delayedCheckOfIframeHeight();
<|endoftext|>


<commit_before>var role = "nothing";
module.exports = function(app){
	var mysql = require('mysql');//it loads the mysql package
	var dbconfig = require('../../config/database');//it loads the configuration of the database
	var connConstant = require('../../config/ConnectConstant');//it loads a module that ensure continuous connection to the database
	var connection;//variable used for the connection to the database
	var ownerflag=false;//flag used to check if the user is an owner
	var jwt = require('jsonwebtoken');//
	var ownerflag;//flag used to check if the user is an owner
	//function to check if the user is owner of a specific project
	function checkIfOwner(user,proj_name,callback){
		connection=connConstant.connection;
		var selectProjects = "SELECT `project_name` FROM " + dbconfig.projects_table +" JOIN " + dbconfig.owners_table + " ON "+ dbconfig.projects_table+
		".`project_id` = "+ dbconfig.owners_table + ".`project_id` "+" WHERE "+ dbconfig.owners_table+".`user_id` = '" + user.id + "'";
		//console.log(selectProjects)
		connection.query(selectProjects, function(err, rows){
			if (rows.length > 0) {
            	for(var i in rows){
        			if(rows[i].project_name==proj_name){
        				ownerflag=true;
        			}
            	}
	        }
	        console.log(ownerflag);
	        callback(ownerflag);
		});
	}
	// =============================================================================
	// Create a project I own API===================================
	// =============================================================================
	app.get('/api/changePrivacyProjOwn', function(req, res) {
		res.setHeader('Content-Type', 'application/json');
		var scase_token= req.param('scase_token');//require your scase token in order to authenticate
		var scase_signature = req.param('scase_signature');//require your scase_signature in order to authenticate
		var proj_name= req.param('project_name');//require project name
		var privacy=req.param('privacy_level');
		if(scase_token&&proj_name&&scase_signature&&privacy_level){
			connection=connConstant.connection;//ensure that there is a connection to the DB
			//we select the user with the scase_token provided
			var selectUsersQuery = "SELECT * FROM " + dbconfig.users_table + " WHERE scase_token = '" + scase_token + "'";//query to get all the info of the user with the provided scase token
			connection.query(selectUsersQuery, function(err, rows){
                if (rows.length > 0) {
                	jwt.verify(scase_signature,rows[0].scase_secret,function(err,decoded){
                		if(err){
							var obj = '{"message": "User with scase_signature '+scase_signature + 'does not exist in S-Case"}';
							var Jobj=JSON.parse(obj);
							res.status(401).send(Jobj);
                		}
                		if(decoded){
							if(decoded.scasetoken==scase_token){//we check if the produced signature is the same with the one provided
		                		var user = rows[0];
		                		var createProjectQuery = "INSERT INTO " + dbconfig.projects_table +
										" (project_name,privacy_level)" +
										" VALUES ("+ "'" + proj_name+"','"+privacy_level+"')";//query to create the project
								//console.log(createProjectQuery);
								connection=connConstant.connection;
								checkIfOwner(user,proj_name,function(ownerflag){
										if(ownerflag==true){
											connection=connConstant.connection;
											var getProjectId = "SELECT project_id FROM " + dbconfig.projects_table + " WHERE project_name="+ "'"
														+ proj_name +"'";//query to get the project's ID
											//console.log(getProjectId);
											connection.query(getProjectId, function(err, rows){
												if(rows.length>0){
													var changePrivacyQuery = "UPDATE " +dbconfig.projects_table+ " SET `privacy_level`='" +privacy
														+ "' WHERE `project_id`='"+rows[0].project_id+"'";
													connection=connConstant.connection;
													console.log(changePrivacyQuery);
													connection.query(changePrivacyQuery, function(err, rows){
														var obj = '{"message": "Privacy level of' + proj_name +' set to '+ privacy+ '"}';
														var Jobj=JSON.parse(obj);
														res.status(200).send(Jobj);
													});
												}
												else{
													var obj = '{"message": "There is no project with name '+proj_name + '"}';
													var Jobj=JSON.parse(obj);
													res.status(404).send(Jobj);
												}
											});
										}
										else{
											var obj = '{"message": "User with scase_signature '+scase_signature + ' is not owner of the project"}';
											var Jobj=JSON.parse(obj);
											res.status(401).send(Jobj);
										}

								});
		                	}
		                	else{
								var obj = '{"message": "User with scase_signature '+scase_signature + 'does not exist in S-Case"}';
								var Jobj=JSON.parse(obj);
								res.status(401).send(Jobj);
	                		}
	                	}
	                	else{
							var obj = '{"message": "User with scase_signature '+scase_signature + 'does not exist in S-Case"}';
							var Jobj=JSON.parse(obj);
							res.status(401).send(Jobj);
	                	}
                	});
                }
                else {
					var obj = '{"message": "User with scase_token '+scase_token + 'does not exist in S-Case"}';
					var Jobj=JSON.parse(obj);
					res.status(401).send(Jobj);
				}
            });
		}
		else{
			//res.setHeader('Content-Type', 'application/json');
			var obj = '{"message": "you miss some parameters"}';
			var Jobj=JSON.parse(obj);
			res.status(400).send(Jobj);
		}
	});
};<commit_msg>fixed error code<commit_after>var role = "nothing";
module.exports = function(app){
	var mysql = require('mysql');//it loads the mysql package
	var dbconfig = require('../../config/database');//it loads the configuration of the database
	var connConstant = require('../../config/ConnectConstant');//it loads a module that ensure continuous connection to the database
	var connection;//variable used for the connection to the database
	var ownerflag=false;//flag used to check if the user is an owner
	var jwt = require('jsonwebtoken');//
	var ownerflag;//flag used to check if the user is an owner
	//function to check if the user is owner of a specific project
	function checkIfOwner(user,proj_name,callback){
		connection=connConstant.connection;
		var selectProjects = "SELECT `project_name` FROM " + dbconfig.projects_table +" JOIN " + dbconfig.owners_table + " ON "+ dbconfig.projects_table+
		".`project_id` = "+ dbconfig.owners_table + ".`project_id` "+" WHERE "+ dbconfig.owners_table+".`user_id` = '" + user.id + "'";
		//console.log(selectProjects)
		connection.query(selectProjects, function(err, rows){
			if (rows.length > 0) {
            	for(var i in rows){
        			if(rows[i].project_name==proj_name){
        				ownerflag=true;
        			}
            	}
	        }
	        console.log(ownerflag);
	        callback(ownerflag);
		});
	}
	// =============================================================================
	// Create a project I own API===================================
	// =============================================================================
	app.get('/api/changePrivacyProjOwn', function(req, res) {
		res.setHeader('Content-Type', 'application/json');
		var scase_token= req.param('scase_token');//require your scase token in order to authenticate
		var scase_signature = req.param('scase_signature');//require your scase_signature in order to authenticate
		var proj_name= req.param('project_name');//require project name
		var privacy=req.param('privacy_level');
		if(scase_token&&proj_name&&scase_signature&&privacy){
			connection=connConstant.connection;//ensure that there is a connection to the DB
			//we select the user with the scase_token provided
			var selectUsersQuery = "SELECT * FROM " + dbconfig.users_table + " WHERE scase_token = '" + scase_token + "'";//query to get all the info of the user with the provided scase token
			connection.query(selectUsersQuery, function(err, rows){
                if (rows.length > 0) {
                	jwt.verify(scase_signature,rows[0].scase_secret,function(err,decoded){
                		if(err){
							var obj = '{"message": "User with scase_signature '+scase_signature + 'does not exist in S-Case"}';
							var Jobj=JSON.parse(obj);
							res.status(401).send(Jobj);
                		}
                		if(decoded){
							if(decoded.scasetoken==scase_token){//we check if the produced signature is the same with the one provided
		                		var user = rows[0];
		                		var createProjectQuery = "INSERT INTO " + dbconfig.projects_table +
										" (project_name,privacy_level)" +
										" VALUES ("+ "'" + proj_name+"','"+privacy_level+"')";//query to create the project
								//console.log(createProjectQuery);
								connection=connConstant.connection;
								checkIfOwner(user,proj_name,function(ownerflag){
										if(ownerflag==true){
											connection=connConstant.connection;
											var getProjectId = "SELECT project_id FROM " + dbconfig.projects_table + " WHERE project_name="+ "'"
														+ proj_name +"'";//query to get the project's ID
											//console.log(getProjectId);
											connection.query(getProjectId, function(err, rows){
												if(rows.length>0){
													var changePrivacyQuery = "UPDATE " +dbconfig.projects_table+ " SET `privacy_level`='" +privacy
														+ "' WHERE `project_id`='"+rows[0].project_id+"'";
													connection=connConstant.connection;
													console.log(changePrivacyQuery);
													connection.query(changePrivacyQuery, function(err, rows){
														var obj = '{"message": "Privacy level of' + proj_name +' set to '+ privacy+ '"}';
														var Jobj=JSON.parse(obj);
														res.status(200).send(Jobj);
													});
												}
												else{
													var obj = '{"message": "There is no project with name '+proj_name + '"}';
													var Jobj=JSON.parse(obj);
													res.status(404).send(Jobj);
												}
											});
										}
										else{
											var obj = '{"message": "User with scase_signature '+scase_signature + ' is not owner of the project"}';
											var Jobj=JSON.parse(obj);
											res.status(401).send(Jobj);
										}

								});
		                	}
		                	else{
								var obj = '{"message": "User with scase_signature '+scase_signature + 'does not exist in S-Case"}';
								var Jobj=JSON.parse(obj);
								res.status(401).send(Jobj);
	                		}
	                	}
	                	else{
							var obj = '{"message": "User with scase_signature '+scase_signature + 'does not exist in S-Case"}';
							var Jobj=JSON.parse(obj);
							res.status(401).send(Jobj);
	                	}
                	});
                }
                else {
					var obj = '{"message": "User with scase_token '+scase_token + 'does not exist in S-Case"}';
					var Jobj=JSON.parse(obj);
					res.status(401).send(Jobj);
				}
            });
		}
		else{
			//res.setHeader('Content-Type', 'application/json');
			var obj = '{"message": "you miss some parameters"}';
			var Jobj=JSON.parse(obj);
			res.status(400).send(Jobj);
		}
	});
};<|endoftext|>


<commit_before>/* eslint-env jquery */
/* global relative */
import i18n from 'i18next'
import XHR from 'i18next-xhr-backend'
import lngDetector from 'i18next-browser-languagedetector'
import JSON5 from 'json5'

/**
 * Export the instance of i18n.
 *
 * Usage:
 *    import i18n from './i18n.js'
 *    i18n.on('initialized languageChanged', () => {
        // called upon initialization and changeLanguage
 *      i18n.t('key')  // returns the translation
 *    })
 */
export default i18n

$(() => {
  // page loaded
  const locales = ['nb-NO', 'nn-NO', 'en-US']  // first is default language
  i18n.use(XHR)
  .use(lngDetector)
  .init({
    debug: false,
    whitelist: locales,
    lng: locales[0],
    fallbackLng: [],
    load: 'currentOnly',
    backend: {
      // relative is defined in layout.jade
      loadPath: relative('assets/locales/{{lng}}/{{ns}}.json5'),
      parse: JSON5.parse
    }
  }, () => {
    i18n.on('languageChanged', onLanguageChanged)
  })

  /**
  * When i18n is initialized, or if the language is changed, translate all tags
  * with the attribute "data-i18n".
  * E.g. a tag with:
  *   data-i18n="html=key" will set this tag's innerHTML to the caption given by "key".
  *   data-i18n="placeholder=key" will set the attribute "placeholder" to the caption given by "key".
  *   data-i18n="html=key1placeholder=key2" will set both innerHTML and the attribute "placeholder" to
  *                                          the captions for "key1" and "key2", respectively.
  */

  function onLanguageChanged () {
    $('[data-i18n]').each((_, item) => {
      const captions = $(item).attr('data-i18n').split('')
      for (let i = 0; i < captions.length; ++i) {
        const capSplit = captions[i].split('=')
        const key = capSplit[0]
        const caption = i18n.t(capSplit[1])
        if (key === 'html') {
          // console.log("Setting innerHTML=" + caption)
          $(item).html(caption)
        } else {
          // console.log("Setting attribute " + key + ": " + caption)
          $(item).attr(key, caption)
        }
      }
    })
    $('[title]').tooltip('destroy').tooltip()  // reset tooltips
  }
})

/**
 * Called from html, e.g. clicking on flag
 * Example: onclick="setLanguage('nb-NO')"
 */
window.setLanguage = (locale) => {
  i18n.changeLanguage(locale, (err) => {
    if (err) { console.log(err) }
  })
}
<commit_msg>fix removed ; afther ruthless find/replace in #193<commit_after>/* eslint-env jquery */
/* global relative */
import i18n from 'i18next'
import XHR from 'i18next-xhr-backend'
import lngDetector from 'i18next-browser-languagedetector'
import JSON5 from 'json5'

/**
 * Export the instance of i18n.
 *
 * Usage:
 *    import i18n from './i18n.js'
 *    i18n.on('initialized languageChanged', () => {
        // called upon initialization and changeLanguage
 *      i18n.t('key')  // returns the translation
 *    })
 */
export default i18n

$(() => {
  // page loaded
  const locales = ['nb-NO', 'nn-NO', 'en-US']  // first is default language
  i18n.use(XHR)
  .use(lngDetector)
  .init({
    debug: false,
    whitelist: locales,
    lng: locales[0],
    fallbackLng: [],
    load: 'currentOnly',
    backend: {
      // relative is defined in layout.jade
      loadPath: relative('assets/locales/{{lng}}/{{ns}}.json5'),
      parse: JSON5.parse
    }
  }, () => {
    i18n.on('languageChanged', onLanguageChanged)
  })

  /**
  * When i18n is initialized, or if the language is changed, translate all tags
  * with the attribute "data-i18n".
  * E.g. a tag with:
  *   data-i18n="html=key" will set this tag's innerHTML to the caption given by "key".
  *   data-i18n="placeholder=key" will set the attribute "placeholder" to the caption given by "key".
  *   data-i18n="html=key1;placeholder=key2" will set both innerHTML and the attribute "placeholder" to
  *                                          the captions for "key1" and "key2", respectively.
  */

  function onLanguageChanged () {
    $('[data-i18n]').each((_, item) => {
      const captions = $(item).attr('data-i18n').split(';')
      for (let i = 0; i < captions.length; ++i) {
        const capSplit = captions[i].split('=')
        const key = capSplit[0]
        const caption = i18n.t(capSplit[1])
        if (key === 'html') {
          // console.log("Setting innerHTML=" + caption)
          $(item).html(caption)
        } else {
          // console.log("Setting attribute " + key + ": " + caption)
          $(item).attr(key, caption)
        }
      }
    })
    $('[title]').tooltip('destroy').tooltip()  // reset tooltips
  }
})

/**
 * Called from html, e.g. clicking on flag
 * Example: onclick="setLanguage('nb-NO')"
 */
window.setLanguage = (locale) => {
  i18n.changeLanguage(locale, (err) => {
    if (err) { console.log(err) }
  })
}
<|endoftext|>


<commit_before>function graph(graphId, type) {

    var id = '#'.concat(graphId);

    var height = 20;
    var stroke_width = 1;
    var box_fill = "#000";
    var stroke_color = "#000";

    var font_size = 8;
    var red_band = Number($(id).parent().find($(".band-red")).html());
    var green_band = Number($(id).parent().find($(".band-green")).html());
    var blue_band = Number($(id).parent().find($(".band-blue")).html());
    var red_color = "#c02137";
    var green_color = "#4e9c62";
    var blue_color = "#00668e";

    var xLowNorm = 0.400;
    var widthNorm = 2.294;

    var bandLegend = {};
    bandLegend["1"] = "Band 1: Coastal aerosol";
    bandLegend["2"] = "Band 2: Blue";
    bandLegend["3"] = "Band 3: Green";
    bandLegend["4"] = "Band 4: Red";
    bandLegend["5"] = "Band 5: Near Infrared (NIR)";
    bandLegend["6"] = "Band 6: SWIR 1";
    bandLegend["7"] = "Band 7: SWIR 2";
    bandLegend["9"] = "Band 9: Cirrus";

    var freqLegend = {};
    freqLegend["1"] = "1: Coastal/Aerosol (0.435 - 0.451 µm)";
    freqLegend["2"] = "2: Blue (0.452 - 0.512 µm)";
    freqLegend["3"] = "3: Green (0.533 - 0.590 µm)";
    freqLegend["4"] = "4: Red (0.636 - 0.673 µm)";
    freqLegend["5"] = "5: Near Infrared (NIR) (0.851 - 0.879 µm)";
    freqLegend["6"] = "6: SWIR 1 (1.566 - 1.651 µm)";
    freqLegend["7"] = "7: SWIR 2 (2.107 - 2.294 µm)";
    freqLegend["9"] = "9: Cirrus (1.363 - 1.384 µm)";

    if(type == "reference"){
        width = $(".d3-container").width();

        waveLengths = [[0.435, 0.451, 1, "#6ca4d3"],
                       [0.452, 0.512, 2, blue_color],
                       [0.533, 0.590, 3, green_color],
                       [0.636, 0.673, 4, red_color],
                       [0.851, 0.879, 5, "#c5a3be"],
                       [1.566, 1.651, 6, "#d49979"],
                       [2.107, 2.294, 7, "#999b98"],
                       [1.362, 1.384, 9, "#7f87b5"]];

        svgBar = d3.selectAll(id)
            .append("svg")
            .attr("width", width)
            .attr("height", height + stroke_width)
            .attr('class', 'spectrumMap');

        tip = d3.tip()
        .attr('class', 'd3-tip')
        .offset([height *2 , 0])
        .html(function(d) {
            return '
' + freqLegend[d[2]] + '
';
            });

        svgBar.call(tip);

        svgBar.append("rect")
            .attr("x", 0 + "px")
            .attr("y", 0 + "px")
            .attr("width", width)
            .attr("height", height + stroke_width);

        svgBar.selectAll("rect")
            .data(waveLengths, function(d){return d;})
            .enter()
            .append("rect")
            .attr("stroke-width", stroke_width)
            .attr("stroke", stroke_color)
            .attr("fill", function (d){ return (d[3]); })
            .attr("x", function (d){ return (width * ((d[0] - xLowNorm) / widthNorm)) + "px"; })
            .attr("y", 0 + "px")
            .attr("width", function (d){ return (width * (d[1] - d[0]) / (widthNorm - xLowNorm)) + "px"; })
            .attr("height", height + "px")
            .on('mouseover', tip.show)
            .on('mouseout', tip.hide);

        svgBar.selectAll("text")
            .data(waveLengths, function(d){return d;})
            .enter()
            .append("text")
            .attr("x", function (d){ return (width * ((d[0] - xLowNorm) / widthNorm)) + "px"; })
            .attr("y", 0 + "px")
            .attr("text-anchor", "middle")
            .attr("dx", function (d){ return ((width * (d[1] - d[0]) / (widthNorm - xLowNorm)) / 2) + "px"; })
            .attr("dy", height / 2 + font_size / 2)
            .attr("font-size", font_size)
            .text(function(d) { return d[2]; })
            .attr("pointer-events", "none");

    }else if(type == "preview"){
        width = $(id).parent().width();

        waveLengths = [[0.435, 0.451, 1, box_fill],
                       [0.452, 0.512, 2, box_fill],
                       [0.533, 0.590, 3, box_fill],
                       [0.636, 0.673, 4, box_fill],
                       [0.851, 0.879, 5, box_fill],
                       [1.566, 1.651, 6, box_fill],
                       [2.107, 2.294, 7, box_fill],
                       [0.503, 0.676, 8, box_fill],
                       [1.362, 1.384, 9, box_fill],
                       [10.60, 12.51, 10, box_fill],
                       [11.50, 12.51, 11, box_fill]];

        for (var j in waveLengths){
            if(waveLengths[j][2] == red_band){
                waveLengths[j][3] = red_color;
            }else if(waveLengths[j][2] == blue_band){
                waveLengths[j][3] = blue_color;
            }else if(waveLengths[j][2] == green_band){
                waveLengths[j][3] = green_color;
            }
        }

        svgBar = d3.selectAll(id)
            .append("svg")
            .attr("width", width)
            .attr("height", height + stroke_width)
            .attr('class', 'spectrumMap');

        svgBar.append("rect")
            .attr("x", 0 + "px")
            .attr("y", 0 + "px")
            .attr("width", width)
            .attr("height", height + stroke_width);

        svgBar.selectAll("rect")
            .data(waveLengths, function(d){return d;})
            .enter()
            .append("rect")
            .attr("stroke-width", stroke_width)
            .attr("stroke", stroke_color)
            .attr("fill", function (d){ return (d[3]); })
            .attr("x", function (d){ return ((width / waveLengths.length) * (d[2] - 1)) + "px"; })
            .attr("y", 0 + "px")
            .attr("width", function (d){ return (width / waveLengths.length)+ "px"; })
            .attr("height", height + "px")
            .attr("pointer-events", "none");

    }

}

$(document).ready(function(){
    $(".preview").each(function(){
        graphId = $(this).find($(".graph")).attr("id");
        graph(graphId, "preview");
        });

    $("#reference").each(function(){
        graphId = $(this).attr("id");
        graph(graphId, "reference");
        });
});

$(window).on('resize', function (){
    $(".graph").contents().remove();

    $(".preview").each(function(){
        graphId = $(this).find($(".graph")).attr("id");
        graph(graphId, "preview");
        });

    $("#reference").each(function(){
        graphId = $(this).attr("id");
        graph(graphId, "reference");
        });
});
<commit_msg>#84 Simplify all code<commit_after>function graph(graphId, type) {

    var id = '#'.concat(graphId);

    var height = 20;
    var stroke_width = 1;
    var box_fill = "#000";
    var stroke_color = "#000";

    var font_size = 8;
    var red_band = Number($(id).parent().find($(".band-red")).html());
    var green_band = Number($(id).parent().find($(".band-green")).html());
    var blue_band = Number($(id).parent().find($(".band-blue")).html());
    var red_color = "#c02137";
    var green_color = "#4e9c62";
    var blue_color = "#00668e";

    var xLowNorm = 0.400;
    var widthNorm = 2.294;

    if(type == "reference"){
        width = $(".d3-container").width();

        waveLengths = [[0.435, 0.451, 1, "#6ca4d3", "Coastal/Aerosol"],
                       [0.452, 0.512, 2, blue_color, "Blue"],
                       [0.533, 0.590, 3, green_color, "Green"],
                       [0.636, 0.673, 4, red_color, "Red"],
                       [0.851, 0.879, 5, "#c5a3be", "Near Infrared (NIR)"],
                       [1.566, 1.651, 6, "#d49979", "SWIR 1"],
                       [2.107, 2.294, 7, "#999b98", "SWIR 2"],
                       [1.362, 1.384, 9, "#7f87b5", "Cirrus"]];

        svgBar = d3.selectAll(id)
            .append("svg")
            .attr("width", width)
            .attr("height", height + stroke_width)
            .attr('class', 'spectrumMap');

        tip = d3.tip()
        .attr('class', 'd3-tip')
        .offset([height *2 , 0])
        .html(function(d) {
            return '
' + d[2] + ': ' + d[4] + ' (' + d[0] + " - " + d[1] + ' µm)' + '
';
            });

        svgBar.call(tip);

        svgBar.append("rect")
            .attr("x", 0 + "px")
            .attr("y", 0 + "px")
            .attr("width", width)
            .attr("height", height + stroke_width);

        svgBar.selectAll("rect")
            .data(waveLengths, function(d){return d;})
            .enter()
            .append("rect")
            .attr("stroke-width", stroke_width)
            .attr("stroke", stroke_color)
            .attr("fill", function (d){ return (d[3]); })
            .attr("x", function (d){ return (width * ((d[0] - xLowNorm) / widthNorm)) + "px"; })
            .attr("y", 0 + "px")
            .attr("width", function (d){ return (width * (d[1] - d[0]) / (widthNorm - xLowNorm)) + "px"; })
            .attr("height", height + "px")
            .on('mouseover', tip.show)
            .on('mouseout', tip.hide);

        svgBar.selectAll("text")
            .data(waveLengths, function(d){return d;})
            .enter()
            .append("text")
            .attr("x", function (d){ return (width * ((d[0] - xLowNorm) / widthNorm)) + "px"; })
            .attr("y", 0 + "px")
            .attr("text-anchor", "middle")
            .attr("dx", function (d){ return ((width * (d[1] - d[0]) / (widthNorm - xLowNorm)) / 2) + "px"; })
            .attr("dy", height / 2 + font_size / 2)
            .attr("font-size", font_size)
            .text(function(d) { return d[2]; })
            .attr("pointer-events", "none");

    }else if(type == "preview"){
        width = $(id).parent().width();

        waveLengths = [[red_band, red_color],
                       [blue_band, blue_color],
                       [green_band, green_color]];

        svgBar = d3.selectAll(id)
            .append("svg")
            .attr("width", width)
            .attr("height", height + stroke_width)
            .attr('class', 'spectrumMap');

        svgBar.append("rect")
            .attr("x", 0 + "px")
            .attr("y", 0 + "px")
            .attr("width", width)
            .attr("height", height + stroke_width);

        svgBar.selectAll("rect")
            .data(waveLengths, function(d){return d;})
            .enter()
            .append("rect")
            .attr("stroke-width", stroke_width)
            .attr("stroke", stroke_color)
            .attr("fill", function (d){ return (d[1]); })
            .attr("x", function (d){ return ((width / 11) * (d[0] - 1)) + "px"; })
            .attr("y", 0 + "px")
            .attr("width", function (d){ return (width / 11)+ "px"; })
            .attr("height", height + "px")
            .attr("pointer-events", "none");

    }

}

$(document).ready(function(){
    $(".preview").each(function(){
        graphId = $(this).find($(".graph")).attr("id");
        graph(graphId, "preview");
        });

    $("#reference").each(function(){
        graphId = $(this).attr("id");
        graph(graphId, "reference");
        });
});

$(window).on('resize', function (){
    $(".graph").contents().remove();

    $(".preview").each(function(){
        graphId = $(this).find($(".graph")).attr("id");
        graph(graphId, "preview");
        });

    $("#reference").each(function(){
        graphId = $(this).attr("id");
        graph(graphId, "reference");
        });
});
<|endoftext|>


<commit_before>/* Main code */

/* RequireJS configurations */
requirejs.config({
	shim: {
		'bootstrap':{
			deps: ['jquery']
		}
	}
});

var INFODESK_GLOBAL = {};

/* Pop error message */
function add_error(args) {
	//alert('error: '+ JSON.stringify(args));
	var data, dialog;
	if(args && (typeof args === 'object')) {
		if(args.title || args.desc) {
			data = args;
		} else {
			data = {'desc': JSON.stringify(args)};
		}
	} else {
		data = {'title':''+args};
	}
	if(!data.date) data.date = new Date();
	require(["jquery"], function(jquery) {
		dialog = jquery('#elements .error_dialog').clone();
		dialog.find('.date').text(data.date);
		dialog.find('.title').text(data.title);
		if(data.desc && ((data.desc+'').length > 0) ) {
			dialog.find('.desc').text(data.desc);
		} else {
			dialog.find('.desc_container').hide();
		}
		dialog.appendTo('#notifications');
		dialog.alert();
	}, function(err) {
		alert('Error: ' . err);
	});
};

/* Post message to server */
function post_msg(args) {
		//alert('In post_msg() with args=' + JSON.stringify(args) );
		var args = args || {};
		var msg = (args && (typeof args === 'object') && args.msg) ? ''+args.msg : '';
		if(msg.length === 0) {
			return;
		}
		var jqxhr;
		require(["jquery"], function(jquery) {
			jqxhr = jquery.post('backend.php', {'send_msg':'1', 'msg':''+msg});
		}, function(err) { add_error(JSON.stringify(err)); });
		jqxhr.complete(function(response) {
			try {
				if(response && response.status && (200 === response.status) && (response.responseText.substr(0, 2) === 'OK') ) {
					require(["jquery"], function(jquery) {
						jquery("#control_form .msg_field").val('');
					}, function(err) { add_error(JSON.stringify(err)); });
				} else if(response && (response.status !== undefined)) {
					add_error({'title':'Connection failed with #' + response.status, 'desc':response.responseText});
				} else {
					add_error('Connection failed');
				}
			} catch(e) {
				add_error('Connection failed');
			}
		});
	/*
	require(["jquery"], function(jquery) {
	}, function(err) {
		add_error({'title':'Connection failed', 'desc':JSON.stringify(err)});
	});
	*/
}

/* Post message to server */
function post_msg_form() {
	var msg;
	require(["jquery"], function(jquery) {
		msg = jquery('#control_form').find('.msg_field').val();
	}, function(err) {
		add_error({'title':'Clearing form failed', 'desc':JSON.stringify(err)});
	});
	//alert('Calling post_msg() with msg=' + msg);
	post_msg({'msg':msg});
	update_events();
	return false;
}

/* */
function update_events() {
	require(["jquery"], function(jquery) {
		jquery.get('backend.php', {'msgs':'1', 'start':''+INFODESK_GLOBAL.last_id}, function(data) {
			var events = JSON.parse(data), event, div;
			//alert('got events: ' + events.length);
			for(i in events) if(events.hasOwnProperty(i)) {
				event = events[i];
				if(event.log_id > INFODESK_GLOBAL.last_id) {
					INFODESK_GLOBAL.last_id = event.log_id;
				}
				div = jquery('#elements .event_container').clone();
				div.find('.log_id').text(''+event.log_id);
				div.find('.date').text(''+event.updated);
				div.find('.msg').text(''+event.msg);
				div.appendTo('#events');
			}
		});
	}, function(err) { add_error(JSON.stringify(err)); });
}

/* Init everything at onLoad event */
window.onload = function() {
	require(["bootstrap"], function(b) {});

	// TODO: Setup simple clock on control form

	// TODO: Setup previous event history
	INFODESK_GLOBAL.last_id = 0;
	update_events();

	// TODO: Start fetching new events
	function update_events_timer() {
		update_events();
		setTimeout(update_events_timer, 1000);
	}
	update_events_timer();
};

/* EOF */
<commit_msg>Updated<commit_after>/* Main code */

/* RequireJS configurations */
requirejs.config({
	shim: {
		'bootstrap':{
			deps: ['jquery']
		}
	}
});

var INFODESK_GLOBAL = {};

/* Pop error message */
function add_error(args) {
	//alert('error: '+ JSON.stringify(args));
	var data, dialog;
	if(args && (typeof args === 'object')) {
		if(args.title || args.desc) {
			data = args;
		} else {
			data = {'desc': JSON.stringify(args)};
		}
	} else {
		data = {'title':''+args};
	}
	if(!data.date) data.date = new Date();
	require(["jquery"], function(jquery) {
		dialog = jquery('#elements .error_dialog').clone();
		dialog.find('.date').text(data.date);
		dialog.find('.title').text(data.title);
		if(data.desc && ((data.desc+'').length > 0) ) {
			dialog.find('.desc').text(data.desc);
		} else {
			dialog.find('.desc_container').hide();
		}
		dialog.appendTo('#notifications');
		dialog.alert();
	}, function(err) {
		alert('Error: ' . err);
	});
};

/* Post message to server */
function post_msg(args) {
		//alert('In post_msg() with args=' + JSON.stringify(args) );
		var args = args || {};
		var msg = (args && (typeof args === 'object') && args.msg) ? ''+args.msg : '';
		if(msg.length === 0) {
			return;
		}
		var jqxhr;
		require(["jquery"], function(jquery) {
			jqxhr = jquery.post('backend.php', {'send_msg':'1', 'msg':''+msg});
		}, function(err) { add_error(JSON.stringify(err)); });
		jqxhr.complete(function(response) {
			try {
				if(response && response.status && (200 === response.status) && (response.responseText.substr(0, 2) === 'OK') ) {
					require(["jquery"], function(jquery) {
						jquery("#control_form .msg_field").val('');
					}, function(err) { add_error(JSON.stringify(err)); });
				} else if(response && (response.status !== undefined)) {
					add_error({'title':'Connection failed with #' + response.status, 'desc':response.responseText});
				} else {
					add_error('Connection failed');
				}
			} catch(e) {
				add_error('Connection failed');
			}
		});
	/*
	require(["jquery"], function(jquery) {
	}, function(err) {
		add_error({'title':'Connection failed', 'desc':JSON.stringify(err)});
	});
	*/
}

/* Post message to server */
function post_msg_form() {
	var msg;
	require(["jquery"], function(jquery) {
		msg = jquery('#control_form').find('.msg_field').val();
	}, function(err) {
		add_error({'title':'Clearing form failed', 'desc':JSON.stringify(err)});
	});
	//alert('Calling post_msg() with msg=' + msg);
	post_msg({'msg':msg});
	update_events();
	return false;
}

/* */
function update_events() {
	require(["jquery"], function(jquery) {
		jquery.get('backend.php', {'msgs':'1', 'start':''+(INFODESK_GLOBAL.last_id+1)}, function(data) {
			var events = JSON.parse(data), event, div;
			//alert('got events: ' + events.length);
			for(i in events) if(events.hasOwnProperty(i)) {
				event = events[i];
				if(event.log_id > INFODESK_GLOBAL.last_id) {
					INFODESK_GLOBAL.last_id = event.log_id;
				}
				div = jquery('#elements .event_container').clone();
				div.find('.log_id').text(''+event.log_id);
				div.find('.date').text(''+event.updated);
				div.find('.msg').text(''+event.msg);
				div.appendTo('#events');
			}
		});
	}, function(err) { add_error(JSON.stringify(err)); });
}

/* Init everything at onLoad event */
window.onload = function() {
	require(["bootstrap"], function(b) {});

	// TODO: Setup simple clock on control form

	// TODO: Setup previous event history
	INFODESK_GLOBAL.last_id = 0;
	update_events();

	// TODO: Start fetching new events
	function update_events_timer() {
		update_events();
		setTimeout(update_events_timer, 1000);
	}
	update_events_timer();
};

/* EOF */
<|endoftext|>


<commit_before>/* All related comment actions will be managed here */
/* appending comment see views/comments/create.js.erb */

$(function(){

  // declare variables for link, button, form ids
  var viewCommentForm = '#view_comment_form';
  var commentForm = '#comment_form';
  var newComment = '#new_comment';

  toggleLink(commentForm);  // initially hide comment form

  // show/hide form when user clicks on comment
  $('h3').on('click', viewCommentForm, function(e) {
    e.preventDefault();
    toggleLink(commentForm);
  });

  // edit form text when user clicks on comment
  $('h3').on('click', viewCommentForm, function(e) {
    e.preventDefault();
    $(viewCommentForm).text(toggleLinkText($(viewCommentForm)));  // set text depending on current text
  });

  // remove comments form when user submits
  $(commentForm).on('submit', newComment, function(e) {
    e.preventDefault();
    toggleLink(commentForm);
    $(viewCommentForm).text(toggleLinkText($(viewCommentForm)));
  });

});

/*** Helper Methods Below ***/

// toggle between show and hidden
function toggleLink(selector) {
  $(selector).toggle("medium");
}

// toggle text on link/button depending on what is currently set
function toggleLinkText(linkText) {
  text = linkText.text();
  var text = text === "Add a comment" ? "Cancel comment" : "Add a comment";
  return text;
}
<commit_msg>Clean up file and remove editor text on submit<commit_after>/* All related comment actions will be managed here */
/* appending comment see views/comments/create.js.erb */

$(function(){

  // declare variables for link, button, form ids
  var viewCommentForm = '#view_comment_form';
  var commentForm = '#comment_form';
  var newComment = '#new_comment';

  toggleLink(commentForm);  // initially hide comment form

  // show/hide form when user clicks on comment
  $('h3').on('click', viewCommentForm, function(e) {
    e.preventDefault();
    toggleLink(commentForm);
  });

  // edit form text when user clicks on comment
  $('h3').on('click', viewCommentForm, function(e) {
    e.preventDefault();
    changeFormText(viewCommentForm); // set text depending on current text
  });

  // remove comments form when user submits
  $(commentForm).on('submit', newComment, function(e) {
    e.preventDefault();
    clearFormText();                                      // clear form contents
    toggleLink(commentForm);                              // remove form from view
    changeFormText(viewCommentForm);                      // toggle link/button text
  });

});

/*** Helper Methods Below ***/

// toggle between show and hidden
function toggleLink(selector) {
  $(selector).toggle("medium");
}

// toggle text on link/button depending on what is currently set
function toggleLinkText(linkText) {
  text = linkText.text();
  var text = text === "Add a comment" ? "Cancel comment" : "Add a comment";
  return text;
}

// change text on comment form link/button
function changeFormText(form) {
  $(form).text(toggleLinkText($(form)));
}

// clear tiny mce form text after user submits
function clearFormText() {
  tinyMCE.activeEditor.setContent('');
}<|endoftext|>