<commit_before>/*global require: false, module: false */
'use strict';

// Domain logic for mutation datasets.

var _ = require('underscore');
var widgets = require('../columnWidgets');
var xenaQuery = require('../xenaQuery');
var Rx = require('rx');
var exonLayout = require('../exonLayout');
var intervalTree = require('static-interval-tree');
var {pxTransformFlatmap} = require('../layoutPlot');

var unknownEffect = 0,
	impact = {
		'Nonsense_Mutation': 3,
		'frameshift_variant': 3,
		'stop_gained': 3,
		'splice_acceptor_variant': 3,
		'splice_acceptor_variant&intron_variant':3,
		'splice_donor_variant': 3,
		'splice_donor_variant&intron_variant':3,
		'Splice_Site': 3,
		'Frame_Shift_Del': 3,
		'Frame_Shift_Ins': 3,

		'splice_region_variant': 2,
		'splice_region_variant&intron_variant': 2,
		'missense': 2,
		'non_coding_exon_variant': 2,
		'missense_variant': 2,
		'Missense_Mutation': 2,
		'exon_variant': 2,
		'RNA': 2,
		'Indel': 2,
		'start_lost': 2,
		'start_gained': 2,
		'De_novo_Start_OutOfFrame': 2,
		'Translation_Start_Site': 2,
		'De_novo_Start_InFrame': 2,
		'stop_lost': 2,
		'Nonstop_Mutation': 2,
		'initiator_codon_variant': 2,
		'5_prime_UTR_premature_start_codon_gain_variant': 2,
		'disruptive_inframe_deletion': 2,
		'inframe_deletion': 2,
		'inframe_insertion': 2,
		'In_Frame_Del': 2,
		'In_Frame_Ins': 2,

		'synonymous_variant': 1,
		'5_prime_UTR_variant': 1,
		'3_prime_UTR_variant': 1,
		"5'Flank": 1,
		"3'Flank": 1,
		"3'UTR": 1,
		"5'UTR": 1,
		'Silent': 1,
		'stop_retained_variant': 1,

		//mutations outside the exon region and splice region get organge color, code =0
		'others': 0,
		'SV':0,
		'upstream_gene_variant': 0,
		'downstream_gene_variant': 0,
		'intron_variant': 0,
		'intergenic_region': 0,
	},
	colors = {
		category4: [
			{r: 255, g: 127, b: 14, a: 1}, // orange #ff7f0e
			{r: 44, g: 160, b: 44, a: 1},  // green #2ca02c
			{r: 31, g: 119, b: 180, a: 1}, // blue #1f77b4
			{r: 214, g: 39, b: 40, a: 1}   // red #d62728
		],
		af: {r: 255, g: 0, b: 0},
		grey: {r: 128, g: 128, b: 128, a: 1}
	},
	colorStr = c =>
		'rgba(' + c.r + ', ' + c.g + ', ' + c.b + ', ' + c.a.toString() + ')',
	saveUndef = f => v => v === null ? v : f(v),
	round = Math.round,
	decimateFreq = saveUndef(v => round(v * 31) / 32), // reduce to 32 vals

	impactGroups = _.groupBy(_.pairs(impact), ([, imp]) => imp),
	vafLegend = {
		colors: [0, 0.5, 1].map(a => colorStr({...colors.af, a})),
		labels: ['0%', '50%', '100%'],
		align: 'center'
	},
	features = {
		impact: {
			get: (a, v) => impact[v.effect] || (v.effect ? unknownEffect : undefined),
			color: v => colorStr(v === null ? colors.grey : colors.category4[v]),
			legend: {
				colors: colors.category4.map(colorStr),
				labels: _.range(_.keys(impactGroups).length).map(
					i => _.pluck(impactGroups[i], 0).join(', ')),
				align: 'left'
			}
		},
		'dna_vaf': {
			get: (a, v) => v.dna_vaf === null ? undefined : decimateFreq(v.dna_vaf),
			color: v => colorStr(v === null ? colors.grey : _.assoc(colors.af, 'a', v)),
			legend: vafLegend
		},
		'rna_vaf': {
			get: (a, v) => v.rna_vaf === null ? undefined : decimateFreq(v.rna_vaf),
			color: v => colorStr(v === null ? colors.grey : _.assoc(colors.af, 'a', v)),
			legend: vafLegend
		}
	};

// XXX why is txStart needed? If we start doing more positions (fusion),
// this will be invalid. Shouldn't we just use position & invert on neg strand?
function evalMut(refGene, mut) {
	var geneInfo = refGene[mut.gene];
	return {
		impact: features.impact.get(null, mut),
		right: (geneInfo.strand === '+') ?
				mut.start - geneInfo.txStart :
				geneInfo.txStart - mut.start
	};
}

function cmpMut(mut1, mut2) {
	if (mut1.impact !== mut2.impact) {
		if (mut1.impact === undefined){
			return 1;
		} else if (mut2.impact === undefined) {
			return -1;
		} else {
			return mut2.impact - mut1.impact; // high impact sorts first
		}
	}

	return mut1.right - mut2.right;       // low coord sorts first
}

function rowOrder(row1, row2, refGene) {
	var row1a, row2a;

	// Native map is a lot faster than _.map. Need an es5 polyfill, or
	// perhaps lodash, or ramda.
	row1a = row1.map(m => evalMut(refGene, m));
	row2a = row2.map(m => evalMut(refGene, m));

	return cmpMut(_.maxWith(row1a, cmpMut), _.maxWith(row2a, cmpMut));
}

function cmpRowOrNoVariants(v1, v2, refGene) {
	if (v1.length === 0) {
		return (v2.length === 0) ? 0 : 1;
	}
	return (v2.length === 0) ? -1 : rowOrder(v1, v2, refGene);
}

function cmpRowOrNull(v1, v2, refGene) {
	if (v1 === null) {
		return (v2 === null) ? 0 : 1;
	}
	return (v2 === null) ? -1 : cmpRowOrNoVariants(v1, v2, refGene);
}

function cmpSamples(probes, sample, refGene, s1, s2) {
	return _.findValue(probes, function (f) {
		return refGene[f] ? cmpRowOrNull(sample[s1], sample[s2], refGene) : 0;
	});
}

function cmp({fields}, data, index) {
	var refGene = _.getIn(data, ['refGene']),
		samples = _.getIn(index, ['bySample']);
	return (refGene && samples) ?
		(s1, s2) => cmpSamples(fields, samples, refGene, s1, s2) :
		() => 0;
}

var sparseDataValues = xenaQuery.dsID_fn(xenaQuery.sparse_data_values);
var refGeneExonValues = xenaQuery.dsID_fn(xenaQuery.refGene_exon_values);

// support for hg18/CRCh36, hg19/CRCh37
var refGene = {
	hg18: JSON.stringify({host: 'https://reference.xenahubs.net', name: 'refgene_good_hg18'}),
	GRCh36: JSON.stringify({host: 'https://reference.xenahubs.net', name: 'refgene_good_hg18'}),
	hg19: JSON.stringify({host: 'https://reference.xenahubs.net', name: 'refgene_good_hg19'}),
	GRCh37: JSON.stringify({host: 'https://reference.xenahubs.net', name: 'refgene_good_hg19'})
};

function fetch({dsID, fields, assembly}, samples) {
		return Rx.Observable.zipArray(
			sparseDataValues(dsID, fields[0], samples),
			refGene[assembly] ? refGeneExonValues(refGene[assembly], fields): Rx.Observable.return({})
		).map(resp => _.object(['req', 'refGene'], resp));
}

// Group by, returning groups in sorted order. Scales O(n) vs.
// sort's O(n log n), if the number of values is much smaller than
// the number of elements.
function sortByGroup(arr, keyfn) {
	var grouped = _.groupBy(arr, keyfn);
	return _.map(_.sortBy(_.keys(grouped), _.identity),
			k => grouped[k]);
}

function findNodes(byPosition, layout, feature, samples, zoom) {
	var {index, count, height} = zoom,
		pixPerRow = height / count,
		sindex = _.object(samples.slice(index, index + count),
					_.range(samples.length)),
		group = features[feature].get,
		minSize = ([s, e]) => [s, e - s < 1 ? s + 1 : e],
		// sortfn is about 2x faster than sortBy, for large sets of variants
		sortfn = (coll, keyfn) => _.flatten(sortByGroup(coll, keyfn), true);
	return sortfn(pxTransformFlatmap(layout, (toPx, [start, end]) => {
		var variants = _.filter(
			intervalTree.matches(byPosition, {start: start, end: end}),
			v => _.has(sindex, v.sample));
		return _.map(variants, v => {
			var [pstart, pend] = minSize(toPx([v.start, v.end]));
			return {
				xStart: pstart,
				xEnd: pend,
				y: sindex[v.sample] * pixPerRow + (pixPerRow / 2),
			   // XXX 1st param to group was used for extending our coloring to other annotations. See
			   // ga4gh branch.
			   group: group(null, v), // needed for sort, before drawing.
			   data: v
			};
		});
	}), v => v.group);
}

function dataToDisplay({width, fields, sFeature, xzoom = {index: 0}},
		vizSettings, data, sortedSamples, dataset, index, zoom) {
	if (!data) {
		return {};
	}
	var {refGene} = data;

	if (_.isEmpty(refGene)){
		return {};
	}
	var refGeneObj = _.values(refGene)[0],
		padding = 200, // extra bp on both ends of transcripts
		startExon = 0,
		endExon = refGeneObj.exonCount,
		strand = refGeneObj.strand,
		layout = exonLayout.layout(refGeneObj, width, xzoom, padding, startExon, endExon),
		nodes = findNodes(index.byPosition, layout, sFeature, sortedSamples, zoom);

	return {
		layout,
		nodes,
		strand
	};
}

function index(dataType, data) {
	if (!data) {
		return null;
	}
	var {req: {rows, samplesInResp}} = data,
		bySample = _.groupBy(rows, 'sample'),
		empty = []; // use a single empty object.
	return {
		byPosition: intervalTree.index(rows),
		bySample: _.object(
				samplesInResp,
				samplesInResp.map(s => bySample[s] || empty))
	};
}

widgets.cmp.add('mutationVector', cmp);
widgets.fetch.add('mutationVector', fetch);
widgets.index.add('mutationVector', index);
widgets.transform.add('mutationVector', dataToDisplay);

module.exports = features;
<commit_msg>change x === null test back to x == null test<commit_after>/*global require: false, module: false */
'use strict';

// Domain logic for mutation datasets.

var _ = require('underscore');
var widgets = require('../columnWidgets');
var xenaQuery = require('../xenaQuery');
var Rx = require('rx');
var exonLayout = require('../exonLayout');
var intervalTree = require('static-interval-tree');
var {pxTransformFlatmap} = require('../layoutPlot');

var unknownEffect = 0,
	impact = {
		'Nonsense_Mutation': 3,
		'frameshift_variant': 3,
		'stop_gained': 3,
		'splice_acceptor_variant': 3,
		'splice_acceptor_variant&intron_variant':3,
		'splice_donor_variant': 3,
		'splice_donor_variant&intron_variant':3,
		'Splice_Site': 3,
		'Frame_Shift_Del': 3,
		'Frame_Shift_Ins': 3,

		'splice_region_variant': 2,
		'splice_region_variant&intron_variant': 2,
		'missense': 2,
		'non_coding_exon_variant': 2,
		'missense_variant': 2,
		'Missense_Mutation': 2,
		'exon_variant': 2,
		'RNA': 2,
		'Indel': 2,
		'start_lost': 2,
		'start_gained': 2,
		'De_novo_Start_OutOfFrame': 2,
		'Translation_Start_Site': 2,
		'De_novo_Start_InFrame': 2,
		'stop_lost': 2,
		'Nonstop_Mutation': 2,
		'initiator_codon_variant': 2,
		'5_prime_UTR_premature_start_codon_gain_variant': 2,
		'disruptive_inframe_deletion': 2,
		'inframe_deletion': 2,
		'inframe_insertion': 2,
		'In_Frame_Del': 2,
		'In_Frame_Ins': 2,

		'synonymous_variant': 1,
		'5_prime_UTR_variant': 1,
		'3_prime_UTR_variant': 1,
		"5'Flank": 1,
		"3'Flank": 1,
		"3'UTR": 1,
		"5'UTR": 1,
		'Silent': 1,
		'stop_retained_variant': 1,

		//mutations outside the exon region and splice region get organge color, code =0
		'others': 0,
		'SV':0,
		'upstream_gene_variant': 0,
		'downstream_gene_variant': 0,
		'intron_variant': 0,
		'intergenic_region': 0,
	},
	colors = {
		category4: [
			{r: 255, g: 127, b: 14, a: 1}, // orange #ff7f0e
			{r: 44, g: 160, b: 44, a: 1},  // green #2ca02c
			{r: 31, g: 119, b: 180, a: 1}, // blue #1f77b4
			{r: 214, g: 39, b: 40, a: 1}   // red #d62728
		],
		af: {r: 255, g: 0, b: 0},
		grey: {r: 128, g: 128, b: 128, a: 1}
	},
	colorStr = c =>
		'rgba(' + c.r + ', ' + c.g + ', ' + c.b + ', ' + c.a.toString() + ')',
	saveUndef = f => v => v == null ? v : f(v),
	round = Math.round,
	decimateFreq = saveUndef(v => round(v * 31) / 32), // reduce to 32 vals

	impactGroups = _.groupBy(_.pairs(impact), ([, imp]) => imp),
	vafLegend = {
		colors: [0, 0.5, 1].map(a => colorStr({...colors.af, a})),
		labels: ['0%', '50%', '100%'],
		align: 'center'
	},

	features = {
		impact: {
			get: (a, v) => impact[v.effect] || (v.effect ? unknownEffect : undefined),
			color: v => colorStr(v == null ? colors.grey : colors.category4[v]),
			legend: {
				colors: colors.category4.map(colorStr),
				labels: _.range(_.keys(impactGroups).length).map(
					i => _.pluck(impactGroups[i], 0).join(', ')),
				align: 'left'
			}
		},
		'dna_vaf': {
			get: (a, v) => v.dna_vaf == null ? undefined : decimateFreq(v.dna_vaf),
			color: v => colorStr(v == null ? colors.grey : _.assoc(colors.af, 'a', v)),
			legend: vafLegend
		},
		'rna_vaf': {
			get: (a, v) => v.rna_vaf == null ? undefined : decimateFreq(v.rna_vaf),
			color: v => colorStr(v == null ? colors.grey : _.assoc(colors.af, 'a', v)),
			legend: vafLegend
		}
	};

// XXX why is txStart needed? If we start doing more positions (fusion),
// this will be invalid. Shouldn't we just use position & invert on neg strand?
function evalMut(refGene, mut) {
	var geneInfo = refGene[mut.gene];
	return {
		impact: features.impact.get(null, mut),
		right: (geneInfo.strand === '+') ?
				mut.start - geneInfo.txStart :
				geneInfo.txStart - mut.start
	};
}

function cmpMut(mut1, mut2) {
	if (mut1.impact !== mut2.impact) {
		if (mut1.impact === undefined){
			return 1;
		} else if (mut2.impact === undefined) {
			return -1;
		} else {
			return mut2.impact - mut1.impact; // high impact sorts first
		}
	}

	return mut1.right - mut2.right;       // low coord sorts first
}

function rowOrder(row1, row2, refGene) {
	var row1a, row2a;

	// Native map is a lot faster than _.map. Need an es5 polyfill, or
	// perhaps lodash, or ramda.
	row1a = row1.map(m => evalMut(refGene, m));
	row2a = row2.map(m => evalMut(refGene, m));

	return cmpMut(_.maxWith(row1a, cmpMut), _.maxWith(row2a, cmpMut));
}

function cmpRowOrNoVariants(v1, v2, refGene) {
	if (v1.length === 0) {
		return (v2.length === 0) ? 0 : 1;
	}
	return (v2.length === 0) ? -1 : rowOrder(v1, v2, refGene);
}

function cmpRowOrNull(v1, v2, refGene) {
	if (v1 == null) {
		return (v2 == null) ? 0 : 1;
	}
	return (v2 == null) ? -1 : cmpRowOrNoVariants(v1, v2, refGene);
}

function cmpSamples(probes, sample, refGene, s1, s2) {
	return _.findValue(probes, function (f) {
		return refGene[f] ? cmpRowOrNull(sample[s1], sample[s2], refGene) : 0;
	});
}

function cmp({fields}, data, index) {
	var refGene = _.getIn(data, ['refGene']),
		samples = _.getIn(index, ['bySample']);
	return (refGene && samples) ?
		(s1, s2) => cmpSamples(fields, samples, refGene, s1, s2) :
		() => 0;
}

var sparseDataValues = xenaQuery.dsID_fn(xenaQuery.sparse_data_values);
var refGeneExonValues = xenaQuery.dsID_fn(xenaQuery.refGene_exon_values);

// support for hg18/CRCh36, hg19/CRCh37
var refGene = {
	hg18: JSON.stringify({host: 'https://reference.xenahubs.net', name: 'refgene_good_hg18'}),
	GRCh36: JSON.stringify({host: 'https://reference.xenahubs.net', name: 'refgene_good_hg18'}),
	hg19: JSON.stringify({host: 'https://reference.xenahubs.net', name: 'refgene_good_hg19'}),
	GRCh37: JSON.stringify({host: 'https://reference.xenahubs.net', name: 'refgene_good_hg19'})
};

function fetch({dsID, fields, assembly}, samples) {
		return Rx.Observable.zipArray(
			sparseDataValues(dsID, fields[0], samples),
			refGene[assembly] ? refGeneExonValues(refGene[assembly], fields): Rx.Observable.return({})
		).map(resp => _.object(['req', 'refGene'], resp));
}

// Group by, returning groups in sorted order. Scales O(n) vs.
// sort's O(n log n), if the number of values is much smaller than
// the number of elements.
function sortByGroup(arr, keyfn) {
	var grouped = _.groupBy(arr, keyfn);
	return _.map(_.sortBy(_.keys(grouped), _.identity),
			k => grouped[k]);
}

function findNodes(byPosition, layout, feature, samples, zoom) {
	var {index, count, height} = zoom,
		pixPerRow = height / count,
		sindex = _.object(samples.slice(index, index + count),
					_.range(samples.length)),
		group = features[feature].get,
		minSize = ([s, e]) => [s, e - s < 1 ? s + 1 : e],
		// sortfn is about 2x faster than sortBy, for large sets of variants
		sortfn = (coll, keyfn) => _.flatten(sortByGroup(coll, keyfn), true);
	return sortfn(pxTransformFlatmap(layout, (toPx, [start, end]) => {
		var variants = _.filter(
			intervalTree.matches(byPosition, {start: start, end: end}),
			v => _.has(sindex, v.sample));
		return _.map(variants, v => {
			var [pstart, pend] = minSize(toPx([v.start, v.end]));
			return {
				xStart: pstart,
				xEnd: pend,
				y: sindex[v.sample] * pixPerRow + (pixPerRow / 2),
			   // XXX 1st param to group was used for extending our coloring to other annotations. See
			   // ga4gh branch.
			   group: group(null, v), // needed for sort, before drawing.
			   data: v
			};
		});
	}), v => v.group);
}

function dataToDisplay({width, fields, sFeature, xzoom = {index: 0}},
		vizSettings, data, sortedSamples, dataset, index, zoom) {
	if (!data) {
		return {};
	}
	var {refGene} = data;

	if (_.isEmpty(refGene)){
		return {};
	}
	var refGeneObj = _.values(refGene)[0],
		padding = 200, // extra bp on both ends of transcripts
		startExon = 0,
		endExon = refGeneObj.exonCount,
		strand = refGeneObj.strand,
		layout = exonLayout.layout(refGeneObj, width, xzoom, padding, startExon, endExon),
		nodes = findNodes(index.byPosition, layout, sFeature, sortedSamples, zoom);

	return {
		layout,
		nodes,
		strand
	};
}

function index(dataType, data) {
	if (!data) {
		return null;
	}
	var {req: {rows, samplesInResp}} = data,
		bySample = _.groupBy(rows, 'sample'),
		empty = []; // use a single empty object.
	return {
		byPosition: intervalTree.index(rows),
		bySample: _.object(
				samplesInResp,
				samplesInResp.map(s => bySample[s] || empty))
	};
}

widgets.cmp.add('mutationVector', cmp);
widgets.fetch.add('mutationVector', fetch);
widgets.index.add('mutationVector', index);
widgets.transform.add('mutationVector', dataToDisplay);

module.exports = features;
<|endoftext|>


<commit_before>/**
 * This class is used for upload in TinyMCE editor.
 * If one of methods is not commented look for comment in Upload.js.
*/
TinyMCEImageEnhancement = Class.create();
TinyMCEImageEnhancement.prototype = {
    initialize: function() {
        this.filesUploaded = 0;
        this.processInProgress = false;
        Event.observe(window,'load',this.onWindowLoad.bind(this));
    },

    addListeners: function() {
        $('Form_EditorToolbarImageForm_FolderID').value = "";

        Event.observe($('AddFolder'),'click',this.onAddFolder.bind(this));
        Event.observe($('FolderOk'),'click',this.onFolderOk.bind(this));
        Event.observe($('FolderCancel'),'click',this.onFolderCancel.bind(this));
        Event.observe($('UploadFiles'),'click',this.onUpload.bind(this));
    },

    /**
     * Method creates HTML element, only reason for this method is DRY.
    */

    addElement: function(tag, className, parent, properties) {
        var e = document.createElement(tag);
        Element.addClassName(e,className);
        parent.appendChild(e);
        Object.extend(e,properties);
        return e;
    },

    onUpload: function(event) {
        Event.stop(event);
        if(!this.processInProgress) {
	        if(this.getParentID() != 'root') {
	            this.upload.browse();
	        } else {
	            statusMessage("Please choose folder","bad");
	        }
	    }
    },

    /**
     * Called when user clicks "add folder" anchor.
    */

    onAddFolder: function(event) {
        Event.stop(event);
        Element.hide('AddFolder');
        Element.show('NewFolderName','FolderOk','FolderCancel');
        this.applyIE6Hack();
    },

    /**
     * Called when user clicks "ok" anchor/ adds folder with given name.
    */

    onFolderOk: function(event) {
        Event.stop(event);
        var folderName = $('NewFolderName').value;
        var options = {
            method: 'post',
            postBody: 'ParentID=' + this.getParentID() + '&ajax=1&returnID=1' + ($('SecurityID') ? '&SecurityID=' + $('SecurityID').value : ''),
            onSuccess: this.onFolderGetSuccess.bind(this),
            onFailure: function(transport) {
                           errorMessage('Error: Folder not added', transport);
                       }
         };
         new Ajax.Request('admin/assets/addfolder', options);

    },

    /**
     * Method retrieves folder id and sends request which changes folder name.
    */

    onFolderGetSuccess: function(transport) {
        var folderID = transport.responseText;
        var date = new Date();
        var year = date.getFullYear();
        var month = date.getMonth() < 10 ? '0' + date.getMonth() : date.getMonth();
        var day = date.getDay() < 10  ? '0' + date.getDay() : date.getDay();
        var hours = date.getHours() < 10  ? '0' + date.getHours() : date.getHours();
        var minutes = date.getMinutes() < 10  ? '0' + date.getMinutes() : date.getMinutes();
        var seconds = date.getSeconds() < 10  == 1 ? '0' + date.getSeconds() : date.getSeconds();
        var currentDate = year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds;
        var folderName = $('NewFolderName').value;
        this.folderID = folderID;
        var options = {
            method: 'post',
            postBody: 'Created=' + currentDate + '&Name=' + folderName + '&ClassName=Folder&ID=' + folderID + '&ajax=1&action_save=1' + ($('SecurityID') ? '&SecurityID=' + $('SecurityID').value : ''),
            onSuccess: this.onFolderAddSuccess.bind(this),
            onFailure: function(transport) {
                           errorMessage('Error: Folder not added', transport);
                       }
        };
        new Ajax.Request('admin/assets/index/' + this.getParentID() + '?executeForm=EditForm', options);
    },

    /**
     * When folder name has been changed we need to refresh folder list and return to initial state of UI.
    */

    onFolderAddSuccess: function(transport) {
        statusMessage('Creating new folder');
        $('TreeDropdownField_Form_EditorToolbarImageForm_FolderID').itemTree = null;
        $('TreeDropdownField_Form_EditorToolbarImageForm_FolderID').setValue(this.folderID);
        $('NewFolderName').value = '';
        Element.show('AddFolder');
        Element.hide('NewFolderName','FolderOk','FolderCancel');
        this.removeIE6Hack();
    },

    /**
     * If user doesn't want to add folder return to default UI.
    */

    onFolderCancel: function(event) {
        Event.stop(event);
        $('NewFolderName').value = '';
        Element.show('AddFolder');
        Element.hide('NewFolderName','FolderOk','FolderCancel');
        this.removeIE6Hack();
    },

    /**
     * Called on window.onload
    */

    onWindowLoad: function() {
        // Due to a bug in the flash plugin on Linux and Mac, we need at least version 9.0.64 to use SWFUpload
        if(navigator.appVersion.indexOf("Mac") != -1 || navigator.appVersion.indexOf("X11") != -1 || navigator.appVersion.indexOf("Linux") != -1) {
           pv = getFlashPlayerVersion();
           if(pv.major < 9 || (pv.major == 9 && pv.minor == 0 && pv.rev < 64)) {
              if($('AddFolderGroup')) $('AddFolderGroup').style.display = 'none';
              if($('PipeSeparator')) $('PipeSeparator').style.display = 'none';
              if($('UploadGroup')) $('UploadGroup').style.display = 'none';
              return;
           }
        }

        if($('FolderID') != null) {
        	if($('SecurityID')) var securityid=$('SecurityID').value;
	        else var securityid=null;
	        this.upload = new Upload(
	            {
	               fileTypes : '*.jpeg;*.jpg;*.jpe;*.png;*.gif;',
	               fileTypesDescription : 'Image files',
	               fileUploadLimit : '100',
	               securityID : securityid,
	               beginUploadOnQueue : true,
                   buildUI : this.addListeners.bind(this),
                   fileQueued : this.uploadFileQueuedCallback.bind(this),
                   fileComplete : this.uploadFileCompleteCallback.bind(this),
                   queueComplete : this.uploadQueueCompleteCallback.bind(this)
	            }
            );
        }
    },

    uploadFileQueuedCallback: function(file,queueLength) {
        this.processInProgress = true;
        this.upload.setFolderID(this.getParentID());
        $('UploadFiles').innerHTML = "Uploading ... 1/" + this.upload.getFilesToUpload();
        this.upload.startUpload();
    },

    uploadFileCompleteCallback: function(file,serverData) {
        Element.addClassName($('UploadFiles'),'link');//Safari hack
        $('UploadFiles').innerHTML = 'Uploading ... ' + this.upload.getFilesUploaded() + "/" + this.upload.getFilesToUpload();
    },

    uploadQueueCompleteCallback: function() {
        this.filesUploaded = this.upload.getFilesUploaded();
        $('UploadFiles').innerHTML = "upload";
        statusMessage('Uploaded ' + this.upload.getFilesUploaded() + ' files','good');
        if(this.getParentID() != 'root') {
            $('Image').ajaxGetFiles(this.getParentID(),this.insertImages.bind(this));
        }
    },

    /**
     * Iterates over all uploaded images and add them to TinyMCE editor
     *
     * @param transport object
    */

    insertImages: function(transport) {
        //HACK FOR STRANGE ERROR OCCURING UNDER SAFARI
        if(transport.responseText == '') {
            $('Image').ajaxGetFiles(this.getParentID(),this.insertImages.bind(this));
            return;
        }
        //END OF HACK
        $('Image').reapplyBehaviour();
        this.addToTinyMCE = this.addToTinyMCE.bind(this);
        /* Don't insert images for now - this inserts the wrong image as images are now sorted by filename rather than date uploaded.
        var childNodes = $('Image').childNodes[0].childNodes;
        var newImages = $A(childNodes).slice(childNodes.length - this.filesUploaded);
        newImages.each(function(item) {
            tinyMCEImageEnhancement.addToTinyMCE(item.childNodes[0]);
        });
        */
        this.processInProgress = false;
    },

    /**
     * Adds particular image to TinyMCE. Most of code has been copied from tiny_mce_improvements.js / ImageThumbnail.onclick
     * Sorry for not following DRY, I didn't want to break smth in tiny_mce_improvements.
     *
     *  @param target object
    */

    addToTinyMCE: function(target) {
		var formObj = $('Form_EditorToolbarImageForm');
        var altText = formObj.elements.AltText.value;
        var cssClass = formObj.elements.CSSClass.value;
        var baseURL = document.getElementsByTagName('base')[0].href;
        var relativeHref = target.href.substr(baseURL.length)
        if(!tinyMCE.selectedInstance) tinyMCE.selectedInstance = Toolbar.instance().editor;
        if(tinyMCE.selectedInstance.contentWindow.focus) tinyMCE.selectedInstance.contentWindow.focus();
        // Extract dest width and dest height from the class name
        var destWidth = null;
        var destHeight = null;
        try {
            var imgTag = target.getElementsByTagName('img')[0];
            destWidth = imgTag.className.match(/destwidth=([0-9.\-]+)([, ]|$)/) ? RegExp.$1 : null;
            destHeight = imgTag.className.match(/destheight=([0-9.\-]+)([, ]|$)/) ? RegExp.$1 : null;
        } catch(er) {
        }
        TinyMCE_AdvancedTheme._insertImage(relativeHref, altText, 0, null, null, destWidth, destHeight, null, null, cssClass);
    },

    /**
     * Under IE6 when we click on "add folder" anchor, rest of anchors loose their correct position
     *
    */

    applyIE6Hack: function() {
        if(BrowserDetect.browser == 'Explorer') {
	        elements = [$('FolderOk'),$('FolderCancel'),$('UploadFiles')];
	        $A(elements).each(function(element) {
	            element.style.position = "relative";
	            element.style.top = "-3px";
	        });
	   }
    },

    removeIE6Hack: function() {
        if(BrowserDetect.browser == 'Explorer') {
	        elements = [$('FolderOk'),$('FolderCancel'),$('UploadFiles')];
	        $A(elements).each(function(element) {
	            element.style.position = "";
	        });
	    }
    },

    /**
     * Returns id of upload folder.
     *
    */

    getParentID: function() {
        return  $('Form_EditorToolbarImageForm_FolderID').value == '' ? 'root' : $('Form_EditorToolbarImageForm_FolderID').value;
    }
}
tinyMCEImageEnhancement = new TinyMCEImageEnhancement();
<commit_msg>BUGFIX New folders weren't getting their name set correctly, instead they would just be called "NewFolder". This occurred in the Site Content section of the CMS, creating a folder using the right hand panel in that section.<commit_after>/**
 * This class is used for upload in TinyMCE editor.
 * If one of methods is not commented look for comment in Upload.js.
*/
TinyMCEImageEnhancement = Class.create();
TinyMCEImageEnhancement.prototype = {
    initialize: function() {
        this.filesUploaded = 0;
        this.processInProgress = false;
        Event.observe(window,'load',this.onWindowLoad.bind(this));
    },

    addListeners: function() {
        $('Form_EditorToolbarImageForm_FolderID').value = "";

        Event.observe($('AddFolder'),'click',this.onAddFolder.bind(this));
        Event.observe($('FolderOk'),'click',this.onFolderOk.bind(this));
        Event.observe($('FolderCancel'),'click',this.onFolderCancel.bind(this));
        Event.observe($('UploadFiles'),'click',this.onUpload.bind(this));
    },

    /**
     * Method creates HTML element, only reason for this method is DRY.
    */

    addElement: function(tag, className, parent, properties) {
        var e = document.createElement(tag);
        Element.addClassName(e,className);
        parent.appendChild(e);
        Object.extend(e,properties);
        return e;
    },

    onUpload: function(event) {
        Event.stop(event);
        if(!this.processInProgress) {
	        if(this.getParentID() != 'root') {
	            this.upload.browse();
	        } else {
	            statusMessage("Please choose folder","bad");
	        }
	    }
    },

    /**
     * Called when user clicks "add folder" anchor.
    */

    onAddFolder: function(event) {
        Event.stop(event);
        Element.hide('AddFolder');
        Element.show('NewFolderName','FolderOk','FolderCancel');
        this.applyIE6Hack();
    },

	/**
	 * The user clicks the "ok" anchor link, the click event calls up
	 * this function which creates a new AJAX request to add a new folder
	 * using the addfolder function in AssetAdmin.php (admin/assets/addfolder).
	 */
	onFolderOk: function(event) {
		Event.stop(event);
		var folderName = $('NewFolderName').value;
		var options = {
			method: 'post',
			postBody: 'ParentID=' + this.getParentID() + '&ajax=1&returnID=1' + ($('SecurityID') ? '&SecurityID=' + $('SecurityID').value : ''),
			onSuccess: this.onFolderGetSuccess.bind(this),
			onFailure: function(transport) {
				errorMessage('Error: Folder not added', transport);
			}
		};

		new Ajax.Request('admin/assets/addfolder', options);
	},

	/**
	 * If the "addFolderOk" function does a successful AJAX post, call this
	 * function. Take the folder ID that was created in "addFolderOk"
	 * via ajax and send data to modify that folder record.
	 */
	onFolderGetSuccess: function(transport) {
		var folderID = transport.responseText;

		var date = new Date();
		var year = date.getFullYear();
		var month = date.getMonth() < 10 ? '0' + date.getMonth() : date.getMonth();
		var day = date.getDay() < 10  ? '0' + date.getDay() : date.getDay();
		var hours = date.getHours() < 10  ? '0' + date.getHours() : date.getHours();
		var minutes = date.getMinutes() < 10  ? '0' + date.getMinutes() : date.getMinutes();
		var seconds = date.getSeconds() < 10  == 1 ? '0' + date.getSeconds() : date.getSeconds();
		var currentDate = year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds;

		var folderName = $('NewFolderName').value;

		this.folderID = folderID;

		var options = {
			method: 'post',
			postBody: 'Created=' + currentDate + '&Name=' + folderName + '&ClassName=Folder&ID=' + folderID + '&ajax=1&action_save=1' + ($('SecurityID') ? '&SecurityID=' + $('SecurityID').value : ''),
			onSuccess: this.onFolderAddSuccess.bind(this),
			onFailure: function(transport) {
				errorMessage('Error: Folder not added', transport);
			}
		};

		new Ajax.Request('admin/assets/EditForm', options);
    },

    /**
     * When folder name has been changed we need to refresh folder list and return to initial state of UI.
    */

    onFolderAddSuccess: function(transport) {
        statusMessage('Creating new folder');
        $('TreeDropdownField_Form_EditorToolbarImageForm_FolderID').itemTree = null;
        $('TreeDropdownField_Form_EditorToolbarImageForm_FolderID').setValue(this.folderID);
        $('NewFolderName').value = '';
        Element.show('AddFolder');
        Element.hide('NewFolderName','FolderOk','FolderCancel');
        this.removeIE6Hack();
    },

    /**
     * If user doesn't want to add folder return to default UI.
    */

    onFolderCancel: function(event) {
        $('NewFolderName').value = '';
        Element.show('AddFolder');
        Element.hide('NewFolderName','FolderOk','FolderCancel');
        this.removeIE6Hack();
    },

    /**
     * Called on window.onload
    */

    onWindowLoad: function() {
        // Due to a bug in the flash plugin on Linux and Mac, we need at least version 9.0.64 to use SWFUpload
        if(navigator.appVersion.indexOf("Mac") != -1 || navigator.appVersion.indexOf("X11") != -1 || navigator.appVersion.indexOf("Linux") != -1) {
           pv = getFlashPlayerVersion();
           if(pv.major < 9 || (pv.major == 9 && pv.minor == 0 && pv.rev < 64)) {
              if($('AddFolderGroup')) $('AddFolderGroup').style.display = 'none';
              if($('PipeSeparator')) $('PipeSeparator').style.display = 'none';
              if($('UploadGroup')) $('UploadGroup').style.display = 'none';
              return;
           }
        }

        if($('FolderID') != null) {
        	if($('SecurityID')) var securityid=$('SecurityID').value;
	        else var securityid=null;
	        this.upload = new Upload(
	            {
	               fileTypes : '*.jpeg;*.jpg;*.jpe;*.png;*.gif;',
	               fileTypesDescription : 'Image files',
	               fileUploadLimit : '100',
	               securityID : securityid,
	               beginUploadOnQueue : true,
                   buildUI : this.addListeners.bind(this),
                   fileQueued : this.uploadFileQueuedCallback.bind(this),
                   fileComplete : this.uploadFileCompleteCallback.bind(this),
                   queueComplete : this.uploadQueueCompleteCallback.bind(this)
	            }
            );
        }
    },

    uploadFileQueuedCallback: function(file,queueLength) {
        this.processInProgress = true;
        this.upload.setFolderID(this.getParentID());
        $('UploadFiles').innerHTML = "Uploading ... 1/" + this.upload.getFilesToUpload();
        this.upload.startUpload();
    },

    uploadFileCompleteCallback: function(file,serverData) {
        Element.addClassName($('UploadFiles'),'link');//Safari hack
        $('UploadFiles').innerHTML = 'Uploading ... ' + this.upload.getFilesUploaded() + "/" + this.upload.getFilesToUpload();
    },

    uploadQueueCompleteCallback: function() {
        this.filesUploaded = this.upload.getFilesUploaded();
        $('UploadFiles').innerHTML = "upload";
        statusMessage('Uploaded ' + this.upload.getFilesUploaded() + ' files','good');
        if(this.getParentID() != 'root') {
            $('Image').ajaxGetFiles(this.getParentID(),this.insertImages.bind(this));
        }
    },

    /**
     * Iterates over all uploaded images and add them to TinyMCE editor
     *
     * @param transport object
    */

    insertImages: function(transport) {
        //HACK FOR STRANGE ERROR OCCURING UNDER SAFARI
        if(transport.responseText == '') {
            $('Image').ajaxGetFiles(this.getParentID(),this.insertImages.bind(this));
            return;
        }
        //END OF HACK
        $('Image').reapplyBehaviour();
        this.addToTinyMCE = this.addToTinyMCE.bind(this);
        /* Don't insert images for now - this inserts the wrong image as images are now sorted by filename rather than date uploaded.
        var childNodes = $('Image').childNodes[0].childNodes;
        var newImages = $A(childNodes).slice(childNodes.length - this.filesUploaded);
        newImages.each(function(item) {
            tinyMCEImageEnhancement.addToTinyMCE(item.childNodes[0]);
        });
        */
        this.processInProgress = false;
    },

    /**
     * Adds particular image to TinyMCE. Most of code has been copied from tiny_mce_improvements.js / ImageThumbnail.onclick
     * Sorry for not following DRY, I didn't want to break smth in tiny_mce_improvements.
     *
     *  @param target object
    */

    addToTinyMCE: function(target) {
		var formObj = $('Form_EditorToolbarImageForm');
        var altText = formObj.elements.AltText.value;
        var cssClass = formObj.elements.CSSClass.value;
        var baseURL = document.getElementsByTagName('base')[0].href;
        var relativeHref = target.href.substr(baseURL.length)
        if(!tinyMCE.selectedInstance) tinyMCE.selectedInstance = Toolbar.instance().editor;
        if(tinyMCE.selectedInstance.contentWindow.focus) tinyMCE.selectedInstance.contentWindow.focus();
        // Extract dest width and dest height from the class name
        var destWidth = null;
        var destHeight = null;
        try {
            var imgTag = target.getElementsByTagName('img')[0];
            destWidth = imgTag.className.match(/destwidth=([0-9.\-]+)([, ]|$)/) ? RegExp.$1 : null;
            destHeight = imgTag.className.match(/destheight=([0-9.\-]+)([, ]|$)/) ? RegExp.$1 : null;
        } catch(er) {
        }
        TinyMCE_AdvancedTheme._insertImage(relativeHref, altText, 0, null, null, destWidth, destHeight, null, null, cssClass);
    },

    /**
     * Under IE6 when we click on "add folder" anchor, rest of anchors loose their correct position
     *
    */

    applyIE6Hack: function() {
        if(BrowserDetect.browser == 'Explorer') {
	        elements = [$('FolderOk'),$('FolderCancel'),$('UploadFiles')];
	        $A(elements).each(function(element) {
	            element.style.position = "relative";
	            element.style.top = "-3px";
	        });
	   }
    },

    removeIE6Hack: function() {
        if(BrowserDetect.browser == 'Explorer') {
	        elements = [$('FolderOk'),$('FolderCancel'),$('UploadFiles')];
	        $A(elements).each(function(element) {
	            element.style.position = "";
	        });
	    }
    },

    /**
     * Returns id of upload folder.
     *
    */

    getParentID: function() {
        return  $('Form_EditorToolbarImageForm_FolderID').value == '' ? 'root' : $('Form_EditorToolbarImageForm_FolderID').value;
    }
}
tinyMCEImageEnhancement = new TinyMCEImageEnhancement();
<|endoftext|>


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

/**
 * The open query tab (Repository viewer)
 */
var OpenQuery = Backbone.View.extend({
    className: 'tab_container',

    events: {
        'click .query': 'view_query',
        'dblclick .query': 'select_and_open_query',
        'click .add_folder' : 'add_folder',
        'click li.folder': 'toggle_folder',
        'click .workspace_toolbar a.open': 'open_query',
        'click .workspace_toolbar [href=#edit_folder]': 'edit_folder',
        'click .workspace_toolbar [href=#delete_folder]': 'delete_folder',
        'click .workspace_toolbar [href=#delete_query]': 'delete_query',
        'click .workspace_toolbar [href=#edit_permissions]': 'edit_permissions',
        'click .queries' : 'click_canvas',
        'keyup .search_file' : 'search_file'
    },

    template: function() {
        return _.template($("#template-open-dialog").html())();
    },

    template_repository_objects: function( repository ) {
        var self = this;
        $(this.el).find('.sidebar ul').html(
            _.template( $( '#template-repository-objects' ).html( ) )( {
                repoObjects: repository
            } )
        );
    },

    caption: function() {
        return "Repository";
    },

    render: function() {
        // Load template
        $(this.el).html(this.template());

        // Adjust tab when selected
        this.tab.bind('tab:select', this.fetch_queries);
        this.tab.bind('tab:select', this.adjust);
        $(window).resize(this.adjust);

        return this;
    },

    initialize: function(args) {
        // Maintain `this`
        _.bindAll(this, "adjust", "fetch_queries",
                "clear_query","select_and_open_query");

        // Initialize repository
        this.repository = new Repository({}, { dialog: this });
    },

    fetch_queries: function() {
        this.repository.fetch();
    },

    populate: function( repository ) {
        var self = this;
        self.template_repository_objects( repository );
        self.queries = {};
        function getQueries( entries ) {
            _.forEach( entries, function( entry ) {
                self.queries[ entry.path ] = entry;
                if( entry.type === 'FOLDER' ) {
                    getQueries( entry.repoObjects );
                }
            } );
        }
        getQueries( repository );
    },

    search_file: function(event) {
        var filter = $(this.el).find('.search_file').val();
        var isEmpty = (typeof filter == "undefined" || filter == "" || filter == null);
        if (isEmpty || event.which == 27 || event.which == 9) {
            $(this.el).find('li.query').show();
            $(this.el).find( '.folder_row' ).find('.sprite').addClass( 'collapsed' );
            $(this.el).find( 'li.folder .folder_content' ).addClass('hide');
            $(this.el).find('.search_file').val('');
        } else {

            $(this.el).find('li.query').show();
            $(this.el).find('li.query a').not(':contains("' + filter + '")').parent().hide();
            $(this.el).find( 'li.folder .folder_row' ).find('.sprite').removeClass( 'collapsed' );
            $(this.el).find( 'li.folder .folder_content' ).removeClass('hide');
        }
        return false;
    },

    view_query: function(event) {
        event.preventDefault( );
        var $currentTarget = $( event.currentTarget );
        var $target = $currentTarget.find('a');
        this.unselect_current_selected( );
        $currentTarget.addClass( 'selected' );
        var path = $target.attr('href').replace('#', '');
        var name = $target.text();
        var query = this.queries[path];
        $( this.el ).find( '.workspace_toolbar' ).removeClass( 'hide' );
        $( this.el ).find( '.for_queries' ).addClass( 'hide' );
        $( this.el ).find( '.for_folder' ).addClass( 'hide' );
        $( this.el ).find( '.add_folder' ).parent().addClass( 'hide' );

        if (typeof query.acl != "undefined" && _.indexOf(query.acl, "READ") > -1) {
            $( this.el ).find( '.for_queries .open' ).parent().removeClass( 'hide' );
        }
        if (typeof query.acl != "undefined" && _.indexOf(query.acl, "WRITE") > -1) {
            $( this.el ).find( '.for_queries .delete' ).parent().removeClass( 'hide' );
        }
        if (typeof query.acl != "undefined" && _.indexOf(query.acl, "GRANT") > -1) {
            $( this.el ).find( '.for_queries .edit_permissions' ).parent().removeClass( 'hide' );
        }
        try {
            var query_path = path.split("/");
            if (query_path.length > 1) {
                    var folder_path = query_path.splice(0,query_path.length - 1).join("/");
                    var folder = this.queries[folder_path];
                    if (typeof folder.acl != "undefined" && _.indexOf(folder.acl, "WRITE") > -1) {
                        $( this.el ).find( '.add_folder' ).parent().removeClass( 'hide' );
                    }
            } else if (query_path.length == 1) {
                $( this.el ).find( '.add_folder' ).parent().removeClass( 'hide' );
            }
        } catch(e) {
            //console.log(e);
        }

        var $results = $(this.el).find('.workspace_results')
            .html('
' + query.name + '
');
        var $properties = $('
').appendTo($results);

        // Iterate through properties and show a key=>value set in the information pane
        for (var property in query) {
            if (query.hasOwnProperty(property) && property != "name") {
                $properties.append($('
').html("" +
                        property + " : " + query[property]));
            }
        }

        this.selected_query = new SavedQuery({ file: path, name: name });

        return false;
    },

    view_folder: function( event ) {
        var $target = $( event.currentTarget ).children('div').children('a');
        var path = $target.attr('href').replace('#', '');
        var name = $target.text();
        var folder = this.queries[path];
        $( this.el ).find( '.workspace_toolbar' ).removeClass( 'hide' );
        $( this.el ).find( '.add_folder' ).parent().addClass( 'hide' );
        $( this.el ).find( '.for_queries' ).addClass( 'hide' );
        $( this.el ).find( '.for_folder' ).addClass( 'hide' );

        if (typeof folder.acl != "undefined" && _.indexOf(folder.acl, "WRITE") > -1) {
            $( this.el ).find( '.for_folder .delete' ).parent().removeClass( 'hide' );
            $( this.el ).find( '.add_folder' ).parent().removeClass( 'hide' );
        }
        if (typeof folder.acl != "undefined" && _.indexOf(folder.acl, "GRANT") > -1) {
            $( this.el ).find( '.for_folder .edit_permissions' ).parent().removeClass( 'hide' );
        }

        $( this.el ).find( '.workspace_results' )
            .html( '
' + name + '
' );

        this.selected_query = new SavedQuery({ file: path , name: name });

    },

    add_folder: function( event ) {
        $selected = $(this.el).find('.selected');
        var path ="";
        if (typeof $selected !== "undefined" && $selected) {
            if ($selected.hasClass('folder_row')) {
                path = $selected.children('a').attr('href');
                path = path.length > 1 ? path.substring(1,path.length) : path;
                path+= "/";

            } else if ($selected.hasClass('query') && !$selected.parent().hasClass('RepositoryObjects')) {
                var query = $selected.find('a');
                path = query.attr('href');
                var queryname = query.text();
                path = path.substring(1, path.length - queryname.length );
            }
        }

        (new AddFolderModal({
            path: path,
            success: this.clear_query
        })).render().open();

        return false;
    },

    click_canvas: function(event) {
        var $target = $( event.currentTarget );
        if ($target.hasClass('sidebar')) {
            $(this.el).find('.selected').removeClass('selected');
        }
        $( this.el ).find( '.add_folder' ).parent().removeClass( 'hide' );
        return false;
    },

    toggle_folder: function( event ) {
        var $target = $( event.currentTarget );
        this.unselect_current_selected( );
        $target.children('.folder_row').addClass( 'selected' );
        var $queries = $target.children( '.folder_content' );
        var isClosed = $target.children( '.folder_row' ).find('.sprite').hasClass( 'collapsed' );
        if( isClosed ) {
            $target.children( '.folder_row' ).find('.sprite').removeClass( 'collapsed' );
            $queries.removeClass( 'hide' );
        } else {
            $target.children( '.folder_row' ).find('.sprite').addClass( 'collapsed' );
            $queries.addClass( 'hide' );
        }

        this.view_folder( event );

        return false;
    },

    select_and_open_query: function(event) {
        var $target = $(event.currentTarget).find('a');
        var path = $target.attr('href').replace('#', '');
        var name = $target.text();
        this.selected_query = new SavedQuery({ file: path, name: path });
        this.open_query();
    },

    open_query: function(event) {
        Saiku.ui.block("Opening query...");
        this.selected_query.fetch({
            success: this.selected_query.move_query_to_workspace,
            error: function() { Saiku.ui.unblock(); },
            dataType: "text"
        });

        return false;
    },

    delete_query: function(event) {
        (new DeleteRepositoryObject({
            query: this.selected_query,
            success: this.clear_query
        })).render().open();

        return false;
    },

    edit_folder: function( event ) {
        alert( 'todo: edit folder properties/permissions' );
        return false;
    },

    delete_folder: function( event ) {
        (new DeleteRepositoryObject({
            query: this.selected_query,
            success: this.clear_query
        })).render().open();
        return false;
    },

    edit_permissions: function(event) {
        (new PermissionsModal({
            workspace: this.workspace,
            title: "Permissions",
            file: this.selected_query.get('file')
        })).open();
    },

    clear_query: function() {
        $(this.el).find('.workspace_toolbar').addClass('hide');
        $(this.el).find('.workspace_results').html('');
        this.fetch_queries();
    },

    adjust: function() {
        // Adjust the height of the separator
        $separator = $(this.el).find('.sidebar_separator');
        $separator.height($("body").height() - 87);
        $(this.el).find('.sidebar').height($("body").height() - 87);

        // Adjust the dimensions of the results window
        $(this.el).find('.workspace_results').css({
            width: $(document).width() - $(this.el).find('.sidebar').width() - 30,
            height: $(document).height() - $("#header").height() -
                $(this.el).find('.workspace_toolbar').height() -
                $(this.el).find('.workspace_fields').height() - 40
        });
    },

    toggle_sidebar: function() {
        // Toggle sidebar
        $(this.el).find('.sidebar').toggleClass('hide');
        var new_margin = $(this.el).find('.sidebar').hasClass('hide') ?
                5 : 265;
        $(this.el).find('.workspace_inner').css({ 'margin-left': new_margin });
    },

    unselect_current_selected: function( ) {
        $( this.el ).find( '.selected' ).removeClass( 'selected' );
    }

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

/**
 * The open query tab (Repository viewer)
 */
var OpenQuery = Backbone.View.extend({
    className: 'tab_container',

    events: {
        'click .query': 'view_query',
        'dblclick .query': 'select_and_open_query',
        'click .add_folder' : 'add_folder',
        'click li.folder': 'toggle_folder',
        'click .workspace_toolbar a.open': 'open_query',
        'click .workspace_toolbar [href=#edit_folder]': 'edit_folder',
        'click .workspace_toolbar [href=#delete_folder]': 'delete_folder',
        'click .workspace_toolbar [href=#delete_query]': 'delete_query',
        'click .workspace_toolbar [href=#edit_permissions]': 'edit_permissions',
        'click .queries' : 'click_canvas',
        'keyup .search_file' : 'search_file'
    },

    template: function() {
        return _.template($("#template-open-dialog").html())();
    },

    template_repository_objects: function( repository ) {
        var self = this;
        $(this.el).find('.sidebar ul').html(
            _.template( $( '#template-repository-objects' ).html( ) )( {
                repoObjects: repository
            } )
        );
    },

    caption: function() {
        return "Repository";
    },

    render: function() {
        // Load template
        $(this.el).html(this.template());

        // Adjust tab when selected
        this.tab.bind('tab:select', this.fetch_queries);
        this.tab.bind('tab:select', this.adjust);
        $(window).resize(this.adjust);

        return this;
    },

    initialize: function(args) {
        // Maintain `this`
        _.bindAll(this, "adjust", "fetch_queries",
                "clear_query","select_and_open_query");

        // Initialize repository
        this.repository = new Repository({}, { dialog: this });
    },

    fetch_queries: function() {
        this.repository.fetch();
    },

    populate: function( repository ) {
        var self = this;
        self.template_repository_objects( repository );
        self.queries = {};
        function getQueries( entries ) {
            _.forEach( entries, function( entry ) {
                self.queries[ entry.path ] = entry;
                if( entry.type === 'FOLDER' ) {
                    getQueries( entry.repoObjects );
                }
            } );
        }
        getQueries( repository );
    },

    search_file: function(event) {
        var filter = $(this.el).find('.search_file').val().toLowerCase();
        var isEmpty = (typeof filter == "undefined" || filter == "" || filter == null);
        if (isEmpty || event.which == 27 || event.which == 9) {
            $(this.el).find('li.query, li.folder').removeClass('hide');
            $(this.el).find( '.folder_row' ).find('.sprite').addClass( 'collapsed' );
            $(this.el).find( 'li.folder .folder_content' ).addClass('hide');
            $(this.el).find('.search_file').val('');
        } else {

            $(this.el).find('li.query').removeClass('hide')
            $(this.el).find('li.query a').filter(function (index) {
                return this.text.toLowerCase().indexOf(filter) == -1;
            }).parent().addClass('hide');
            $(this.el).find('li.folder').addClass('hide');
            $(this.el).find('li.query').not('.hide').parents('li.folder').removeClass('hide');
            //$(this.el).find( 'li.folder .folder_content').not(':has(.query:visible)').parent().addClass('hide');

            //not(':contains("' + filter + '")').parent().hide();
            $(this.el).find( 'li.folder .folder_row' ).find('.sprite').removeClass( 'collapsed' );
            $(this.el).find( 'li.folder .folder_content' ).removeClass('hide');
        }
        return false;
    },

    view_query: function(event) {
        event.preventDefault( );
        var $currentTarget = $( event.currentTarget );
        var $target = $currentTarget.find('a');
        this.unselect_current_selected( );
        $currentTarget.addClass( 'selected' );
        var path = $target.attr('href').replace('#', '');
        var name = $target.text();
        var query = this.queries[path];
        $( this.el ).find( '.workspace_toolbar' ).removeClass( 'hide' );
        $( this.el ).find( '.for_queries' ).addClass( 'hide' );
        $( this.el ).find( '.for_folder' ).addClass( 'hide' );
        $( this.el ).find( '.add_folder' ).parent().addClass( 'hide' );

        if (typeof query.acl != "undefined" && _.indexOf(query.acl, "READ") > -1) {
            $( this.el ).find( '.for_queries .open' ).parent().removeClass( 'hide' );
        }
        if (typeof query.acl != "undefined" && _.indexOf(query.acl, "WRITE") > -1) {
            $( this.el ).find( '.for_queries .delete' ).parent().removeClass( 'hide' );
        }
        if (typeof query.acl != "undefined" && _.indexOf(query.acl, "GRANT") > -1) {
            $( this.el ).find( '.for_queries .edit_permissions' ).parent().removeClass( 'hide' );
        }
        try {
            var query_path = path.split("/");
            if (query_path.length > 1) {
                    var folder_path = query_path.splice(0,query_path.length - 1).join("/");
                    var folder = this.queries[folder_path];
                    if (typeof folder.acl != "undefined" && _.indexOf(folder.acl, "WRITE") > -1) {
                        $( this.el ).find( '.add_folder' ).parent().removeClass( 'hide' );
                    }
            } else if (query_path.length == 1) {
                $( this.el ).find( '.add_folder' ).parent().removeClass( 'hide' );
            }
        } catch(e) {
            //console.log(e);
        }

        var $results = $(this.el).find('.workspace_results')
            .html('
' + query.name + '
');
        var $properties = $('
').appendTo($results);

        // Iterate through properties and show a key=>value set in the information pane
        for (var property in query) {
            if (query.hasOwnProperty(property) && property != "name") {
                $properties.append($('
').html("" +
                        property + " : " + query[property]));
            }
        }

        this.selected_query = new SavedQuery({ file: path, name: name });

        return false;
    },

    view_folder: function( event ) {
        var $target = $( event.currentTarget ).children('div').children('a');
        var path = $target.attr('href').replace('#', '');
        var name = $target.text();
        var folder = this.queries[path];
        $( this.el ).find( '.workspace_toolbar' ).removeClass( 'hide' );
        $( this.el ).find( '.add_folder' ).parent().addClass( 'hide' );
        $( this.el ).find( '.for_queries' ).addClass( 'hide' );
        $( this.el ).find( '.for_folder' ).addClass( 'hide' );

        if (typeof folder.acl != "undefined" && _.indexOf(folder.acl, "WRITE") > -1) {
            $( this.el ).find( '.for_folder .delete' ).parent().removeClass( 'hide' );
            $( this.el ).find( '.add_folder' ).parent().removeClass( 'hide' );
        }
        if (typeof folder.acl != "undefined" && _.indexOf(folder.acl, "GRANT") > -1) {
            $( this.el ).find( '.for_folder .edit_permissions' ).parent().removeClass( 'hide' );
        }

        $( this.el ).find( '.workspace_results' )
            .html( '
' + name + '
' );

        this.selected_query = new SavedQuery({ file: path , name: name });

    },

    add_folder: function( event ) {
        $selected = $(this.el).find('.selected');
        var path ="";
        if (typeof $selected !== "undefined" && $selected) {
            if ($selected.hasClass('folder_row')) {
                path = $selected.children('a').attr('href');
                path = path.length > 1 ? path.substring(1,path.length) : path;
                path+= "/";

            } else if ($selected.hasClass('query') && !$selected.parent().hasClass('RepositoryObjects')) {
                var query = $selected.find('a');
                path = query.attr('href');
                var queryname = query.text();
                path = path.substring(1, path.length - queryname.length );
            }
        }

        (new AddFolderModal({
            path: path,
            success: this.clear_query
        })).render().open();

        return false;
    },

    click_canvas: function(event) {
        var $target = $( event.currentTarget );
        if ($target.hasClass('sidebar')) {
            $(this.el).find('.selected').removeClass('selected');
        }
        $( this.el ).find( '.add_folder' ).parent().removeClass( 'hide' );
        return false;
    },

    toggle_folder: function( event ) {
        var $target = $( event.currentTarget );
        this.unselect_current_selected( );
        $target.children('.folder_row').addClass( 'selected' );
        var $queries = $target.children( '.folder_content' );
        var isClosed = $target.children( '.folder_row' ).find('.sprite').hasClass( 'collapsed' );
        if( isClosed ) {
            $target.children( '.folder_row' ).find('.sprite').removeClass( 'collapsed' );
            $queries.removeClass( 'hide' );
        } else {
            $target.children( '.folder_row' ).find('.sprite').addClass( 'collapsed' );
            $queries.addClass( 'hide' );
        }

        this.view_folder( event );

        return false;
    },

    select_and_open_query: function(event) {
        var $target = $(event.currentTarget).find('a');
        var path = $target.attr('href').replace('#', '');
        var name = $target.text();
        this.selected_query = new SavedQuery({ file: path, name: path });
        this.open_query();
    },

    open_query: function(event) {
        Saiku.ui.block("Opening query...");
        this.selected_query.fetch({
            success: this.selected_query.move_query_to_workspace,
            error: function() { Saiku.ui.unblock(); },
            dataType: "text"
        });

        return false;
    },

    delete_query: function(event) {
        (new DeleteRepositoryObject({
            query: this.selected_query,
            success: this.clear_query
        })).render().open();

        return false;
    },

    edit_folder: function( event ) {
        alert( 'todo: edit folder properties/permissions' );
        return false;
    },

    delete_folder: function( event ) {
        (new DeleteRepositoryObject({
            query: this.selected_query,
            success: this.clear_query
        })).render().open();
        return false;
    },

    edit_permissions: function(event) {
        (new PermissionsModal({
            workspace: this.workspace,
            title: "Permissions",
            file: this.selected_query.get('file')
        })).open();
    },

    clear_query: function() {
        $(this.el).find('.workspace_toolbar').addClass('hide');
        $(this.el).find('.workspace_results').html('');
        this.fetch_queries();
    },

    adjust: function() {
        // Adjust the height of the separator
        $separator = $(this.el).find('.sidebar_separator');
        $separator.height($("body").height() - 87);
        $(this.el).find('.sidebar').height($("body").height() - 87);

        // Adjust the dimensions of the results window
        $(this.el).find('.workspace_results').css({
            width: $(document).width() - $(this.el).find('.sidebar').width() - 30,
            height: $(document).height() - $("#header").height() -
                $(this.el).find('.workspace_toolbar').height() -
                $(this.el).find('.workspace_fields').height() - 40
        });
    },

    toggle_sidebar: function() {
        // Toggle sidebar
        $(this.el).find('.sidebar').toggleClass('hide');
        var new_margin = $(this.el).find('.sidebar').hasClass('hide') ?
                5 : 265;
        $(this.el).find('.workspace_inner').css({ 'margin-left': new_margin });
    },

    unselect_current_selected: function( ) {
        $( this.el ).find( '.selected' ).removeClass( 'selected' );
    }

});
<|endoftext|>


<commit_before>var Workspace = Backbone.View.extend({
    className: 'tab_container',

    events: {
        'click .sidebar_separator': 'toggle_sidebar',
        'change .cubes': 'new_query',
        'drop': 'remove_dimension'
    },

    template: function() {
        return Saiku.template.get('Workspace')({
            cube_navigation: Saiku.session.cube_navigation
        });
    },

    render: function() {
        // Load template
        $(this.el).html(this.template());

        // Generate toolbar
        this.toolbar.render();
        $(this.el).find('.workspace_toolbar').append($(this.toolbar.el));

        // Generate drop zones
        this.drop_zones.render();
        $(this.drop_zones.el)
            .insertAfter($(this.el).find('.workspace_toolbar'));

        // Activate sidebar for removing elements
        $(this.el).find('.sidebar')
            .droppable();

        return this;
    },

    clear: function() {
        // Prepare the workspace for a new query
        $(this.el).find('.workspace_results,.connectable')
            .html('');
    },

    initialize: function(args) {
        // Maintain `this` in jQuery event handlers
        _.bindAll(this, "adjust", "toggle_sidebar", "flash_cube_navigation");

        // Generate toolbar and append to workspace
        this.toolbar = new WorkspaceToolbar({ workspace: this });
        this.tab = args.tab;

        // Create drop zones
        this.drop_zones = new WorkspaceDropZone({ workspace: this });

        // Adjust tab when selected
        this.tab.bind('tab:select', this.adjust);
        $(window).resize(this.adjust);

        // Flash cube navigation when rendered
        this.tab.bind('tab_rendered', this.flash_cube_navigation);
    },

    adjust: function() {
        // Adjust the height of the separator
        $separator = $(this.el).find('.sidebar_separator');
        $separator.height($("body").height() - 87);
    },

    toggle_sidebar: function() {
        // Toggle sidebar
        $(this.el).find('.sidebar').toggleClass('hide');
        var new_margin = $(this.el).find('.sidebar').hasClass('hide') ?
                5 : 265;
        $(this.el).find('.workspace_inner').css({ 'margin-left': new_margin });
    },

    flash_cube_navigation: function() {
        // Draw user's attention to cube navigation
        $(this.el).find('.cubes')
            .parent()
            .animate({ backgroundColor: '#AC1614' }, 'fast')
            .animate({ backgroundColor: '#fff' }, 'fast');
    },

    new_query: function() {
        // Delete the existing query
        if (this.query) {
            this.query.destroy();
        }

        // Initialize the new query
        var selected_cube = $(this.el).find('.cubes').val();
        this.query = new Query({ cube: selected_cube });

        // Create new DimensionList and MeasureList
        this.dimension_list = new DimensionList({
            workspace: this,
            dimension: Saiku.session.dimensions[selected_cube]
        });
        $(this.el).find('.dimension_tree').html('').append($(this.dimension_list.el));

        this.measure_list = new DimensionList({
            workspace: this,
            dimension: Saiku.session.measures[selected_cube]
        });
        $(this.el).find('.measure_tree').html('').append($(this.measure_list.el));

        // Clear workspace
        this.clear();

        // Make sure appropriate workspace buttons are enabled
        $(this.toolbar.el).find('.button').addClass('disabled_toolbar');
        $(this.toolbar.el).find('.auto,.non_empty')
            .removeClass('disabled_toolbar');
    },

    remove_dimension: function(event, ui) {
        this.drop_zones.remove_dimension(event, ui);
    }
});<commit_msg>Keep `this`. Silly js.<commit_after>var Workspace = Backbone.View.extend({
    className: 'tab_container',

    events: {
        'click .sidebar_separator': 'toggle_sidebar',
        'change .cubes': 'new_query',
        'drop': 'remove_dimension'
    },

    template: function() {
        return Saiku.template.get('Workspace')({
            cube_navigation: Saiku.session.cube_navigation
        });
    },

    render: function() {
        // Load template
        $(this.el).html(this.template());

        // Generate toolbar
        this.toolbar.render();
        $(this.el).find('.workspace_toolbar').append($(this.toolbar.el));

        // Generate drop zones
        this.drop_zones.render();
        $(this.drop_zones.el)
            .insertAfter($(this.el).find('.workspace_toolbar'));

        // Activate sidebar for removing elements
        $(this.el).find('.sidebar')
            .droppable();

        return this;
    },

    clear: function() {
        // Prepare the workspace for a new query
        $(this.el).find('.workspace_results,.connectable')
            .html('');
    },

    initialize: function(args) {
        // Maintain `this` in jQuery event handlers
        _.bindAll(this, "adjust", "toggle_sidebar",
                "flash_cube_navigation", "new_query");

        // Generate toolbar and append to workspace
        this.toolbar = new WorkspaceToolbar({ workspace: this });
        this.tab = args.tab;

        // Create drop zones
        this.drop_zones = new WorkspaceDropZone({ workspace: this });

        // Adjust tab when selected
        this.tab.bind('tab:select', this.adjust);
        $(window).resize(this.adjust);

        // Flash cube navigation when rendered
        this.tab.bind('tab_rendered', this.flash_cube_navigation);
    },

    adjust: function() {
        // Adjust the height of the separator
        $separator = $(this.el).find('.sidebar_separator');
        $separator.height($("body").height() - 87);
    },

    toggle_sidebar: function() {
        // Toggle sidebar
        $(this.el).find('.sidebar').toggleClass('hide');
        var new_margin = $(this.el).find('.sidebar').hasClass('hide') ?
                5 : 265;
        $(this.el).find('.workspace_inner').css({ 'margin-left': new_margin });
    },

    flash_cube_navigation: function() {
        // Draw user's attention to cube navigation
        $(this.el).find('.cubes')
            .parent()
            .animate({ backgroundColor: '#AC1614' }, 'fast')
            .animate({ backgroundColor: '#fff' }, 'fast');
    },

    new_query: function() {
        // Delete the existing query
        if (this.query) {
            this.query.destroy();
        }

        // Initialize the new query
        var selected_cube = $(this.el).find('.cubes').val();
        this.query = new Query({ cube: selected_cube });

        // Create new DimensionList and MeasureList
        this.dimension_list = new DimensionList({
            workspace: this,
            dimension: Saiku.session.dimensions[selected_cube]
        });
        $(this.el).find('.dimension_tree').html('').append($(this.dimension_list.el));

        this.measure_list = new DimensionList({
            workspace: this,
            dimension: Saiku.session.measures[selected_cube]
        });
        $(this.el).find('.measure_tree').html('').append($(this.measure_list.el));

        // Clear workspace
        this.clear();

        // Make sure appropriate workspace buttons are enabled
        $(this.toolbar.el).find('.button').addClass('disabled_toolbar');
        $(this.toolbar.el).find('.auto,.non_empty')
            .removeClass('disabled_toolbar');
    },

    remove_dimension: function(event, ui) {
        this.drop_zones.remove_dimension(event, ui);
    }
});<|endoftext|>


<commit_before>module.exports = {
  context: {
    title: 'Customer login',
    signInInfo: 'If you have an account, sign in with your email address.',
    createAccountInfo: 'Creating an account has many benefits: check out faster, keep more than one address, track orders and more.',
    email: {
      attribute: '',
      class: 'login__input',
      label: {
        attribute: '',
        text: 'Email',
        hidden: false
      },
      field: {
        attribute: '',
        class: '',
        id: 'email',
        name: 'email',
        placeholder: '',
        type: 'email'
      }
    },
    password: {
      attribute: '',
      class: 'login__input',
      label: {
        attribute: '',
        text: 'Password',
        hidden: false
      },
      field: {
        attribute: 'aria-required="true" autocomplete="off"',
        class: '',
        id: 'password',
        name: 'password',
        placeholder: '',
        type: 'password'
      }
    },
    loginButton: {
      class: 'login__button',
      tag: 'button',
      text: 'Sign in'
    },
    createAccountButton: {
      class: 'login__button',
      tag: 'button',
      text: 'Create an Account'
    },
    forgetPassword: {
        href: '#',
        text: 'Forgot your password?'
    },
    validationTips: '* Required Fields',
    tabs: {
      class: '',
      registeredCustomer: {
        active: true,
        tabId: 'registered-customer',
        title: 'Registered customer',
        content: ''
      },
      newCustomer: {
        tabId: 'new-customer',
        title: 'New customer'
      }
    },
    banner: {
      defaultSrc: '/images/login/banner-464-360@2x.jpg',
      sources: [
        {
          src: '/images/login/banner-304-144@2x.jpg',
          mediaQuery: '(max-width: 468px)'
        },
        {
          src: '/images/login/banner-304-144@3x.jpg',
          mediaQuery: '(max-width: 768px)'
        },
        {
          src: '/images/login/banner-464-360@2x.jpg',
          mediaQuery: '(max-width: 992px)'
        },
        {
          src: '/images/login/banner-656-360.jpg',
          mediaQuery: ''
        }
      ],
      alt: 'Description of image'
    }
  },
  variants: [
    {
      name: 'without-banner',
    }
  ]
};
<commit_msg>#35910 Fixing spaces in login.config.js<commit_after>module.exports = {
  context: {
    title: 'Customer login',
    signInInfo: 'If you have an account, sign in with your email address.',
    createAccountInfo: 'Creating an account has many benefits: check out faster, keep more than one address, track orders and more.',
    email: {
      attribute: '',
      class: 'login__input',
      label: {
        attribute: '',
        text: 'Email',
        hidden: false
      },
      field: {
        attribute: '',
        class: '',
        id: 'email',
        name: 'email',
        placeholder: '',
        type: 'email'
      }
    },
    password: {
      attribute: '',
      class: 'login__input',
      label: {
        attribute: '',
        text: 'Password',
        hidden: false
      },
      field: {
        attribute: 'aria-required="true" autocomplete="off"',
        class: '',
        id: 'password',
        name: 'password',
        placeholder: '',
        type: 'password'
      }
    },
    loginButton: {
      class: 'login__button',
      tag: 'button',
      text: 'Sign in'
    },
    createAccountButton: {
      class: 'login__button',
      tag: 'button',
      text: 'Create an Account'
    },
    forgetPassword: {
      href: '#',
      text: 'Forgot your password?'
    },
    validationTips: '* Required Fields',
    tabs: {
      class: '',
      registeredCustomer: {
        active: true,
        tabId: 'registered-customer',
        title: 'Registered customer',
        content: ''
      },
      newCustomer: {
        tabId: 'new-customer',
        title: 'New customer'
      }
    },
    banner: {
      defaultSrc: '/images/login/banner-464-360@2x.jpg',
      sources: [
        {
          src: '/images/login/banner-304-144@2x.jpg',
          mediaQuery: '(max-width: 468px)'
        },
        {
          src: '/images/login/banner-304-144@3x.jpg',
          mediaQuery: '(max-width: 768px)'
        },
        {
          src: '/images/login/banner-464-360@2x.jpg',
          mediaQuery: '(max-width: 992px)'
        },
        {
          src: '/images/login/banner-656-360.jpg',
          mediaQuery: ''
        }
      ],
      alt: 'Description of image'
    }
  },
  variants: [
    {
      name: 'without-banner',
    }
  ]
};
<|endoftext|>


<commit_before>(function () {
  "use strict";

  angular.module('mnXDCRService', [
    'mnTasksDetails',
    'mnPoolDefault',
    'mnFilters'
  ]).factory('mnXDCRService', mnXDCRServiceFactory);

  function mnXDCRServiceFactory($q, $http, mnTasksDetails, mnPoolDefault, mnPools, getStringBytesFilter) {
    var mnXDCRService = {
      removeExcessSettings: removeExcessSettings,
      saveClusterReference: saveClusterReference,
      deleteClusterReference: deleteClusterReference,
      deleteReplication: deleteReplication,
      getReplicationSettings: getReplicationSettings,
      saveReplicationSettings: saveReplicationSettings,
      postRelication: postRelication,
      getReplicationState: getReplicationState,
      validateRegex: validateRegex
    };

    return mnXDCRService;

    function doValidateOnOverLimit(text) {
      return getStringBytesFilter(text) > 250;
    }

    function validateRegex(regex, testKey) {
      if (doValidateOnOverLimit(regex)) {
        return $q.reject('Regex should not have size more than 250 bytes');
      }
      if (doValidateOnOverLimit(testKey)) {
        return $q.reject('Test key should not have size more than 250 bytes');
      }
      return $http({
        method: 'POST',
        mnHttp: {
          cancelPrevious: true
        },
        data: {
          expression: regex,
          keys: JSON.stringify([testKey])
        },
        transformResponse: function (data) {
          //angular expect response in JSON format
          //but server returns with text message in case of error
          var resp;

          try {
            resp = JSON.parse(data);
          } catch (e) {
            resp = data;
          }

          return resp;
        },
        url: '/_goxdcr/regexpValidation'
      });
    }

    function removeExcessSettings(settings) {
      var neededProperties = ["replicationType", "optimisticReplicationThreshold", "failureRestartInterval", "docBatchSizeKb", "workerBatchSize", "checkpointInterval", "type", "toBucket", "toCluster", "fromBucket"];
      if (mnPoolDefault.export.goxdcrEnabled) {
        neededProperties = neededProperties.concat(["sourceNozzlePerNode", "targetNozzlePerNode", "statsInterval", "logLevel"]);
      } else {
        neededProperties = neededProperties.concat(["maxConcurrentReps", "workerProcesses"]);
      }
      if (mnPools.export.isEnterprise &&
          mnPoolDefault.export.compat.atLeast50 &&
          mnPoolDefault.export.goxdcrEnabled &&
          settings.type === "xmem"
         ) {
        neededProperties.push("networkUsageLimit");
      }
      var rv = {};
      angular.forEach(neededProperties,  function (key) {
        rv[key] = settings[key];
      });
      return rv;
    }
    function saveClusterReference(cluster, name) {
      cluster = _.clone(cluster);
      cluster.hostname && !cluster.hostname.split(":")[1] && (cluster.hostname += ":8091");
      if (!cluster.demandEncryption) {
        delete cluster.certificate;
        delete cluster.demandEncryption;
        delete cluster.encryptionType;
      }
      return $http.post('/pools/default/remoteClusters' + (name ? ("/" + encodeURIComponent(name)) : ""), cluster);
    }
    function deleteClusterReference(name) {
      return $http.delete('/pools/default/remoteClusters/' + encodeURIComponent(name));
    }
    function deleteReplication(id) {
      return $http.delete('/controller/cancelXDCR/' + encodeURIComponent(id));
    }
    function getReplicationSettings(id) {
      return $http.get("/settings/replications" + (id ? ("/" + encodeURIComponent(id)) : ""));
    }
    function saveReplicationSettings(id, settings) {
      return $http.post("/settings/replications/" + encodeURIComponent(id), settings);
    }
    function postRelication(settings) {
      return $http.post("/controller/createReplication", settings);
    }
    function getReplicationState() {
      return $http.get('/pools/default/remoteClusters').then(function (resp) {
        var byUUID = {};
        _.forEach(resp.data, function (reference) {
          byUUID[reference.uuid] = reference;
        });
        return {
          filtered: _.filter(resp.data, function (cluster) { return !cluster.deleted }),
          all: resp.data,
          byUUID: byUUID
        };
      });
    }
  }
})();
<commit_msg>MB-27478: fix the handling of ipv6 addresses<commit_after>(function () {
  "use strict";

  angular.module('mnXDCRService', [
    'mnTasksDetails',
    'mnPoolDefault',
    'mnFilters'
  ]).factory('mnXDCRService', mnXDCRServiceFactory);

  function mnXDCRServiceFactory($q, $http, mnTasksDetails, mnPoolDefault, mnPools, getStringBytesFilter) {
    var mnXDCRService = {
      removeExcessSettings: removeExcessSettings,
      saveClusterReference: saveClusterReference,
      deleteClusterReference: deleteClusterReference,
      deleteReplication: deleteReplication,
      getReplicationSettings: getReplicationSettings,
      saveReplicationSettings: saveReplicationSettings,
      postRelication: postRelication,
      getReplicationState: getReplicationState,
      validateRegex: validateRegex
    };

    return mnXDCRService;

    function doValidateOnOverLimit(text) {
      return getStringBytesFilter(text) > 250;
    }

    function validateRegex(regex, testKey) {
      if (doValidateOnOverLimit(regex)) {
        return $q.reject('Regex should not have size more than 250 bytes');
      }
      if (doValidateOnOverLimit(testKey)) {
        return $q.reject('Test key should not have size more than 250 bytes');
      }
      return $http({
        method: 'POST',
        mnHttp: {
          cancelPrevious: true
        },
        data: {
          expression: regex,
          keys: JSON.stringify([testKey])
        },
        transformResponse: function (data) {
          //angular expect response in JSON format
          //but server returns with text message in case of error
          var resp;

          try {
            resp = JSON.parse(data);
          } catch (e) {
            resp = data;
          }

          return resp;
        },
        url: '/_goxdcr/regexpValidation'
      });
    }

    function removeExcessSettings(settings) {
      var neededProperties = ["replicationType", "optimisticReplicationThreshold", "failureRestartInterval", "docBatchSizeKb", "workerBatchSize", "checkpointInterval", "type", "toBucket", "toCluster", "fromBucket"];
      if (mnPoolDefault.export.goxdcrEnabled) {
        neededProperties = neededProperties.concat(["sourceNozzlePerNode", "targetNozzlePerNode", "statsInterval", "logLevel"]);
      } else {
        neededProperties = neededProperties.concat(["maxConcurrentReps", "workerProcesses"]);
      }
      if (mnPools.export.isEnterprise &&
          mnPoolDefault.export.compat.atLeast50 &&
          mnPoolDefault.export.goxdcrEnabled &&
          settings.type === "xmem"
         ) {
        neededProperties.push("networkUsageLimit");
      }
      var rv = {};
      angular.forEach(neededProperties,  function (key) {
        rv[key] = settings[key];
      });
      return rv;
    }
    function saveClusterReference(cluster, name) {
      cluster = _.clone(cluster);
      var re;
      var result;
      if (cluster.hostname) {
        re = /^\[?([^\]]+)\]?:(\d+)$/; // ipv4/ipv6/hostname + port
        result = re.exec(cluster.hostname);
        if (!result) {
          cluster.hostname += ":8091";
        }
      }
      if (!cluster.demandEncryption) {
        delete cluster.certificate;
        delete cluster.demandEncryption;
        delete cluster.encryptionType;
      }
      return $http.post('/pools/default/remoteClusters' + (name ? ("/" + encodeURIComponent(name)) : ""), cluster);
    }
    function deleteClusterReference(name) {
      return $http.delete('/pools/default/remoteClusters/' + encodeURIComponent(name));
    }
    function deleteReplication(id) {
      return $http.delete('/controller/cancelXDCR/' + encodeURIComponent(id));
    }
    function getReplicationSettings(id) {
      return $http.get("/settings/replications" + (id ? ("/" + encodeURIComponent(id)) : ""));
    }
    function saveReplicationSettings(id, settings) {
      return $http.post("/settings/replications/" + encodeURIComponent(id), settings);
    }
    function postRelication(settings) {
      return $http.post("/controller/createReplication", settings);
    }
    function getReplicationState() {
      return $http.get('/pools/default/remoteClusters').then(function (resp) {
        var byUUID = {};
        _.forEach(resp.data, function (reference) {
          byUUID[reference.uuid] = reference;
        });
        return {
          filtered: _.filter(resp.data, function (cluster) { return !cluster.deleted }),
          all: resp.data,
          byUUID: byUUID
        };
      });
    }
  }
})();
<|endoftext|>


<commit_before>// todo: add in some helpers!

export function dummyHelper(something) {
  return something;
}
<commit_msg>Add polyglot template Helper from the userPage branch.<commit_after>import app from '../app';

const polyT = function (...args) {
  return app.polyglot.t(...args);
};

export {
  polyT,
};

<|endoftext|>