<commit_before>var current_page;
var responses_expected = 0;
var response_counter = 0;
var total_submission_list = [];

self.port.on("show", function onShow(url) {
	reset();
	current_page = url;
	getAllSubmissions(url);
});

self.port.on("hide", function onHide() {
	$.each($("#links").children(), function(index, child) {
		child.remove();
	});
});

function reset(){
	current_page = "";
	responses_expected = 0;
	response_counter = 0;
	total_submission_list = [];
	$("img#loading").show(0);
}

function getAllSubmissions(url){
	var reddit_urls = getAllURLVersions(url);
	responses_expected = reddit_urls.length;

	$.each(reddit_urls, function(index, reddit_url) {
		$.getJSON(reddit_url, handleResponse);
	});
}

function getAllURLVersions(url){
	var without_http = "";
	var result = ['http://www.reddit.com/api/info.json?url=' + encodeURIComponent(url)];
	if (url.indexOf('https') === 0) {
		without_http = url.substring(5);
		result.push('http://www.reddit.com/api/info.json?url=' + encodeURIComponent(without_http));
		result.push('http://www.reddit.com/api/info.json?url=' + encodeURIComponent("http://" + without_http));
	}
	else{
		if (url.indexOf('http') === 0) {
			without_http = url.substring(4);
			result.push('http://www.reddit.com/api/info.json?url=' + encodeURIComponent(without_http));
			result.push('http://www.reddit.com/api/info.json?url=' + encodeURIComponent("https://" + without_http));
		}
		else{
			result.push('http://www.reddit.com/api/info.json?url=' + encodeURIComponent("http://" + without_http));
			result.push('http://www.reddit.com/api/info.json?url=' + encodeURIComponent("https://" + without_http));
		}
	}
	return result;
}

function handleResponse(jsonData){
	var now = new Date();
	var now_timestamp = now.getTime();// = new Date(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(), now.getUTCHours(), now.getUTCMinutes(), now.getUTCSeconds());
	var submissions = [];
	for(var i=0; entry = jsonData.data.children[i]; i++) {
		submission_timestamp = entry.data.created_utc*1000;
		submissions[i] = {
			link: "http://reddit.com" + entry.data.permalink,
			title: entry.data.title,
			score: entry.data.score+"",
			age: (now_timestamp - submission_timestamp) / (24 * 60 * 60 * 1000), // 24 * 60 * 60 * 1000 = milliseconds of 1 day
			comments: entry.data.num_comments+"",
			subreddit: entry.data.subreddit,
		};
	}
	total_submission_list.push.apply(total_submission_list, submissions);

	response_counter++;
	if(response_counter === responses_expected){
		$("img#loading").hide(0);
		putSubmissionsIntoUI(total_submission_list);
	}
}

function putSubmissionsIntoUI(submissions){
	if(submissions.length === 0){
		$("#links").append("
This page hasn't been submitted to reddit, yet.
");
		var element = $(
			"
" +
				"Create submission" +
			"
"
			);
		element.click(function(){
			openLinkInNewTab("http://www.reddit.com/submit?url=" + encodeURIComponent(current_page));
		});
		$("#links").append(element);
	}
	else{
		$.each(submissions, function(index, submission) {
			var t_score = document.createTextNode(submission.score);
			var t_title = document.createTextNode(submission.title);
			var t_subreddit = document.createTextNode("/r/" + submission.subreddit);
			var t_comments = document.createTextNode(submission.comments + " comments");
			var t_time = document.createTextNode(Math.round(submission.age) + " days ago");

			var e_submission = document.createElement("div");
			e_submission.setAttribute("class", "submission");

			var e_score = document.createElement("div");
			e_score.setAttribute("class", "score");
			e_score.setAttribute("align", "center");
			e_score.appendChild(t_score);

			var e_title = document.createElement("div");
			e_title.setAttribute("class", "title");
			e_title.appendChild(t_title);

			var e_infocontainer = document.createElement("div");

			var e_subreddit = document.createElement("div");
			e_subreddit.setAttribute("class", "subreddit");
			e_subreddit.appendChild(t_subreddit);

			var e_comments = document.createElement("div");
			e_comments.setAttribute("class", "comment");
			e_comments.appendChild(t_comments);

			var e_time = document.createElement("div");
			e_time.setAttribute("class", "time");
			e_time.appendChild(t_time);

			e_infocontainer.appendChild(e_subreddit);
			e_infocontainer.appendChild(e_comments);
			e_infocontainer.appendChild(e_time);

			e_submission.appendChild(e_score);
			e_submission.appendChild(e_title);
			e_submission.appendChild(e_infocontainer);

			e_submission.onclick = function() {
				openLinkInNewTab(submission.link);
			};

			$("#links").get(0).appendChild(e_submission);
		});
	}
}

function openLinkInNewTab(url){
	self.port.emit("open-link", url);
}

<commit_msg>format age like reddit does<commit_after>var current_page;
var responses_expected = 0;
var response_counter = 0;
var total_submission_list = [];

self.port.on("show", function onShow(url) {
	reset();
	current_page = url;
	getAllSubmissions(url);
});

self.port.on("hide", function onHide() {
	$.each($("#links").children(), function(index, child) {
		child.remove();
	});
});

function reset(){
	current_page = "";
	responses_expected = 0;
	response_counter = 0;
	total_submission_list = [];
	$("img#loading").show(0);
}

function getAllSubmissions(url){
	var reddit_urls = getAllURLVersions(url);
	responses_expected = reddit_urls.length;

	$.each(reddit_urls, function(index, reddit_url) {
		$.getJSON(reddit_url, handleResponse);
	});
}

function getAllURLVersions(url){
	var without_http = "";
	var result = ['http://www.reddit.com/api/info.json?url=' + encodeURIComponent(url)];
	if (url.indexOf('https') === 0) {
		without_http = url.substring(5);
		result.push('http://www.reddit.com/api/info.json?url=' + encodeURIComponent(without_http));
		result.push('http://www.reddit.com/api/info.json?url=' + encodeURIComponent("http://" + without_http));
	}
	else{
		if (url.indexOf('http') === 0) {
			without_http = url.substring(4);
			result.push('http://www.reddit.com/api/info.json?url=' + encodeURIComponent(without_http));
			result.push('http://www.reddit.com/api/info.json?url=' + encodeURIComponent("https://" + without_http));
		}
		else{
			result.push('http://www.reddit.com/api/info.json?url=' + encodeURIComponent("http://" + without_http));
			result.push('http://www.reddit.com/api/info.json?url=' + encodeURIComponent("https://" + without_http));
		}
	}
	return result;
}

function handleResponse(jsonData){
	var now = new Date();
	var now_timestamp = now.getTime();// = new Date(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(), now.getUTCHours(), now.getUTCMinutes(), now.getUTCSeconds());
	var submissions = [];
	for(var i=0; entry = jsonData.data.children[i]; i++) {
		submission_timestamp = entry.data.created_utc*1000;
		submissions[i] = {
			link: "http://reddit.com" + entry.data.permalink,
			title: entry.data.title,
			score: entry.data.score+"",
			age: (now_timestamp - submission_timestamp),
			comments: entry.data.num_comments+"",
			subreddit: entry.data.subreddit,
		};
	}
	total_submission_list.push.apply(total_submission_list, submissions);

	response_counter++;
	if(response_counter === responses_expected){
		$("img#loading").hide(0);
		putSubmissionsIntoUI(total_submission_list);
	}
}

function putSubmissionsIntoUI(submissions){
	if(submissions.length === 0){
		$("#links").append("
This page hasn't been submitted to reddit, yet.
");
		var element = $(
			"
" +
				"Create submission" +
			"
"
			);
		element.click(function(){
			openLinkInNewTab("http://www.reddit.com/submit?url=" + encodeURIComponent(current_page));
		});
		$("#links").append(element);
	}
	else{
		$.each(submissions, function(index, submission) {
			var t_score = document.createTextNode(submission.score);
			var t_title = document.createTextNode(submission.title);
			var t_subreddit = document.createTextNode("/r/" + submission.subreddit);
			var t_comments = document.createTextNode(submission.comments + " comments");
			var t_time = document.createTextNode(formatAge(submission.age));

			var e_submission = document.createElement("div");
			e_submission.setAttribute("class", "submission");

			var e_score = document.createElement("div");
			e_score.setAttribute("class", "score");
			e_score.setAttribute("align", "center");
			e_score.appendChild(t_score);

			var e_title = document.createElement("div");
			e_title.setAttribute("class", "title");
			e_title.appendChild(t_title);

			var e_infocontainer = document.createElement("div");

			var e_subreddit = document.createElement("div");
			e_subreddit.setAttribute("class", "subreddit");
			e_subreddit.appendChild(t_subreddit);

			var e_comments = document.createElement("div");
			e_comments.setAttribute("class", "comment");
			e_comments.appendChild(t_comments);

			var e_time = document.createElement("div");
			e_time.setAttribute("class", "time");
			e_time.appendChild(t_time);

			e_infocontainer.appendChild(e_subreddit);
			e_infocontainer.appendChild(e_comments);
			e_infocontainer.appendChild(e_time);

			e_submission.appendChild(e_score);
			e_submission.appendChild(e_title);
			e_submission.appendChild(e_infocontainer);

			e_submission.onclick = function() {
				openLinkInNewTab(submission.link);
			};

			$("#links").get(0).appendChild(e_submission);
		});
	}
}

function formatAge(age){
	var MINUTE = 60 * 1000;
	var HOUR = MINUTE * 60;
	var DAY = HOUR * 24;
	var WEEK = DAY * 7;
	var YEAR = WEEK * 52;
	var MONTH = YEAR / 12;
	if (age < MINUTE) {
		return age + " seconds ago";
	} else if(age < HOUR) {
		return Math.floor(age / MINUTE) + " minutes ago";
	} else if(age < DAY) {
		return Math.floor(age / HOUR) + " hours ago";
	} else if(age < WEEK) {
		return Math.floor(age / DAY) + " days ago";
	} else if(age < MONTH) {
		return Math.floor(age / WEEK) + " weeks ago";
	} else if(age < YEAR) {
		return Math.floor(age / MONTH) + " months ago";
	} else {
		return Math.floor(age / YEAR) + " years ago";
	}
}

function openLinkInNewTab(url){
	self.port.emit("open-link", url);
}

<|endoftext|>


<commit_before>//Remove <ul> from Releases
$('.toctree-l1 > a:contains("Releases")').siblings().remove();

//Check URL
var path = window.location.pathname.split('/');
var cleanedPath = $.grep(path,function(n){ return(n) });

// the second to last path segment is the section
switch(cleanedPath[cleanedPath.length-2]) {
  case 'understanding_deis':
    $('.toctree-l1 > a:contains("Understanding Deis")').attr('state', 'open');
    break;
  case 'installing_deis':
    $('.toctree-l1 > a:contains("Installing Deis")').attr('state', 'open');
    break;
  case 'using_deis':
    $('.toctree-l1 > a:contains("Using Deis")').attr('state', 'open');
    break;
  case 'managing_deis':
    $('.toctree-l1 > a:contains("Managing Deis")').attr('state', 'open');
    break;
  case 'contributing':
    $('.toctree-l1 > a:contains("Contributing")').attr('state', 'open');
    break;
  case 'reference':
  case 'client':
  case 'server':
  case 'terms':
    $('.toctree-l1 > a:contains("Reference Guide")').attr('state', 'open');
    break;
  default:
    $('.toctree-l1 > a:contains("Version")').attr('state', 'close');
    break;
}
<commit_msg>docs(customizing_deis): create new section for customization<commit_after>//Remove <ul> from Releases
$('.toctree-l1 > a:contains("Releases")').siblings().remove();

//Check URL
var path = window.location.pathname.split('/');
var cleanedPath = $.grep(path,function(n){ return(n) });

// the second to last path segment is the section
switch(cleanedPath[cleanedPath.length-2]) {
  case 'understanding_deis':
    $('.toctree-l1 > a:contains("Understanding Deis")').attr('state', 'open');
    break;
  case 'installing_deis':
    $('.toctree-l1 > a:contains("Installing Deis")').attr('state', 'open');
    break;
  case 'using_deis':
    $('.toctree-l1 > a:contains("Using Deis")').attr('state', 'open');
    break;
  case 'managing_deis':
    $('.toctree-l1 > a:contains("Managing Deis")').attr('state', 'open');
    break;
  case 'customizing_deis':
    $('.toctree-l1 > a:contains("Customizing Deis")').attr('state', 'open');
    break;
  case 'contributing':
    $('.toctree-l1 > a:contains("Contributing")').attr('state', 'open');
    break;
  case 'reference':
  case 'client':
  case 'server':
  case 'terms':
    $('.toctree-l1 > a:contains("Reference Guide")').attr('state', 'open');
    break;
  default:
    $('.toctree-l1 > a:contains("Version")').attr('state', 'close');
    break;
}
<|endoftext|>


<commit_before><commit_msg>modified conditions<commit_after><|endoftext|>


<commit_before>const _ = require('lodash');
const Promise = require('bluebird');
const errors = require('@tryghost/errors');
const logging = require('@tryghost/logging');
const tpl = require('@tryghost/tpl');

const settingsCache = require('./settings-cache');
const config = require('./config');

const messages = {
    errorMessage: 'The \\{\\{{helperName}\\}\\} helper is not available.',
    errorContext: 'The {flagName} flag must be enabled in labs if you wish to use the \\{\\{{helperName}\\}\\} helper.',
    errorHelp: 'See {url}'
};

// flags in this list always return `true`, allows quick global enable prior to full flag removal
const GA_FEATURES = [
];

// NOTE: this allowlist is meant to be used to filter out any unexpected
//       input for the "labs" setting value
const BETA_FEATURES = [
    'activitypub',
    'multipleProducts'
];

const ALPHA_FEATURES = [
    'oauthLogin',
    'membersActivity',
    'cardSettingsPanel',
    'urlCache',
    'beforeAfterCard',
    'tweetGridCard',
    'membersActivityFeed'
];

module.exports.GA_KEYS = [...GA_FEATURES];
module.exports.WRITABLE_KEYS_ALLOWLIST = [...BETA_FEATURES, ...ALPHA_FEATURES];

module.exports.getAll = () => {
    const labs = _.cloneDeep(settingsCache.get('labs')) || {};

    ALPHA_FEATURES.forEach((alphaKey) => {
        if (labs[alphaKey] && !(config.get('enableDeveloperExperiments') || process.env.NODE_ENV.startsWith('test'))) {
            delete labs[alphaKey];
        }
    });

    GA_FEATURES.forEach((gaKey) => {
        labs[gaKey] = true;
    });

    labs.members = settingsCache.get('members_signup_access') !== 'none';

    return labs;
};

/**
 * @param {string} flag
 * @returns {boolean}
 */
module.exports.isSet = function isSet(flag) {
    const labsConfig = module.exports.getAll();

    return !!(labsConfig && labsConfig[flag] && labsConfig[flag] === true);
};

/**
 *
 * @param {object} options
 * @param {string} options.flagKey the internal lookup key of the flag e.g. labs.isSet(matchHelper)
 * @param {string} options.flagName the user-facing name of the flag e.g. Match helper
 * @param {string} options.helperName Name of the helper to be enabled/disabled
 * @param {string} [options.errorMessage] Optional replacement error message
 * @param {string} [options.errorContext] Optional replacement context message
 * @param {string} [options.errorHelp] Optional replacement help message
 * @param {string} [options.helpUrl] Url to show in the help message
 * @param {string} [options.async] is the helper async?
 * @param {function} callback
 * @returns {Promise<Handlebars.SafeString>|Handlebars.SafeString}
 */
module.exports.enabledHelper = function enabledHelper(options, callback) {
    const errDetails = {};
    let errString;

    if (module.exports.isSet(options.flagKey) === true) {
        // helper is active, use the callback
        return callback();
    }

    // Else, the helper is not active and we need to handle this as an error
    errDetails.message = tpl(options.errorMessage || messages.errorMessage, {helperName: options.helperName});
    errDetails.context = tpl(options.errorContext || messages.errorContext, {
        helperName: options.helperName,
        flagName: options.flagName
    });
    errDetails.help = tpl(options.errorHelp || messages.errorHelp, {url: options.helpUrl});

    // eslint-disable-next-line no-restricted-syntax
    logging.error(new errors.DisabledFeatureError(errDetails));

    const {SafeString} = require('express-hbs');
    errString = new SafeString(`<script>console.error("${_.values(errDetails).join(' ')}");</script>`);

    if (options.async) {
        return Promise.resolve(errString);
    }

    return errString;
};

module.exports.enabledMiddleware = flag => (req, res, next) => {
    if (module.exports.isSet(flag) === true) {
        return next();
    } else {
        return next(new errors.NotFoundError());
    }
};
<commit_msg>Added alpha flag for Tier welcome pages<commit_after>const _ = require('lodash');
const Promise = require('bluebird');
const errors = require('@tryghost/errors');
const logging = require('@tryghost/logging');
const tpl = require('@tryghost/tpl');

const settingsCache = require('./settings-cache');
const config = require('./config');

const messages = {
    errorMessage: 'The \\{\\{{helperName}\\}\\} helper is not available.',
    errorContext: 'The {flagName} flag must be enabled in labs if you wish to use the \\{\\{{helperName}\\}\\} helper.',
    errorHelp: 'See {url}'
};

// flags in this list always return `true`, allows quick global enable prior to full flag removal
const GA_FEATURES = [
];

// NOTE: this allowlist is meant to be used to filter out any unexpected
//       input for the "labs" setting value
const BETA_FEATURES = [
    'activitypub',
    'multipleProducts'
];

const ALPHA_FEATURES = [
    'oauthLogin',
    'membersActivity',
    'cardSettingsPanel',
    'urlCache',
    'beforeAfterCard',
    'tweetGridCard',
    'membersActivityFeed',
    'tierWelcomePages'
];

module.exports.GA_KEYS = [...GA_FEATURES];
module.exports.WRITABLE_KEYS_ALLOWLIST = [...BETA_FEATURES, ...ALPHA_FEATURES];

module.exports.getAll = () => {
    const labs = _.cloneDeep(settingsCache.get('labs')) || {};

    ALPHA_FEATURES.forEach((alphaKey) => {
        if (labs[alphaKey] && !(config.get('enableDeveloperExperiments') || process.env.NODE_ENV.startsWith('test'))) {
            delete labs[alphaKey];
        }
    });

    GA_FEATURES.forEach((gaKey) => {
        labs[gaKey] = true;
    });

    labs.members = settingsCache.get('members_signup_access') !== 'none';

    return labs;
};

/**
 * @param {string} flag
 * @returns {boolean}
 */
module.exports.isSet = function isSet(flag) {
    const labsConfig = module.exports.getAll();

    return !!(labsConfig && labsConfig[flag] && labsConfig[flag] === true);
};

/**
 *
 * @param {object} options
 * @param {string} options.flagKey the internal lookup key of the flag e.g. labs.isSet(matchHelper)
 * @param {string} options.flagName the user-facing name of the flag e.g. Match helper
 * @param {string} options.helperName Name of the helper to be enabled/disabled
 * @param {string} [options.errorMessage] Optional replacement error message
 * @param {string} [options.errorContext] Optional replacement context message
 * @param {string} [options.errorHelp] Optional replacement help message
 * @param {string} [options.helpUrl] Url to show in the help message
 * @param {string} [options.async] is the helper async?
 * @param {function} callback
 * @returns {Promise<Handlebars.SafeString>|Handlebars.SafeString}
 */
module.exports.enabledHelper = function enabledHelper(options, callback) {
    const errDetails = {};
    let errString;

    if (module.exports.isSet(options.flagKey) === true) {
        // helper is active, use the callback
        return callback();
    }

    // Else, the helper is not active and we need to handle this as an error
    errDetails.message = tpl(options.errorMessage || messages.errorMessage, {helperName: options.helperName});
    errDetails.context = tpl(options.errorContext || messages.errorContext, {
        helperName: options.helperName,
        flagName: options.flagName
    });
    errDetails.help = tpl(options.errorHelp || messages.errorHelp, {url: options.helpUrl});

    // eslint-disable-next-line no-restricted-syntax
    logging.error(new errors.DisabledFeatureError(errDetails));

    const {SafeString} = require('express-hbs');
    errString = new SafeString(`<script>console.error("${_.values(errDetails).join(' ')}");</script>`);

    if (options.async) {
        return Promise.resolve(errString);
    }

    return errString;
};

module.exports.enabledMiddleware = flag => (req, res, next) => {
    if (module.exports.isSet(flag) === true) {
        return next();
    } else {
        return next(new errors.NotFoundError());
    }
};
<|endoftext|>


<commit_before>describe 'custom settings'
  should_behave_like('shared setup')

  it 'will show text during saving to server'
    stub($, 'ajax')
    this.edit({saving_text: 'Saving...'})
    this.sandbox.should.have_text "Saving..."
  end

  it 'should add params as additional parameters to post-url'
    var url
    stub($, 'ajax').and_return(function(options) { url = options.data; })
    this.edit({ params: 'foo=bar'})
    url.should.include 'foo=bar'
  end

  it 'can edit default text shown in empty editors'
    this.sandbox = $('
')
    this.enableEditor({ default_text: 'fnord' }).should.have_text 'fnord'
  end

  it 'should show an empty editor even if default_text was shown in the element'
    this.sandbox = $('
')
    this.enableEditor({ default_text: 'fnord' }).click().find(':input').should.have_text ''
  end

  it 'can show as textarea with specified rows and cols'
    var textarea = this.openEditor({
      field_type:'textarea',
      textarea_rows:23,
      textarea_cols:42
    })

    textarea.should.have_attr 'rows', 23
    textarea.should.have_attr 'cols', 42
  end

  it 'can show as input with specified size'
    var input = this.openEditor({
      field_type: 'text',
      text_size: '23'
    })

    input.should.have_attr 'size', 23
  end

  describe 'select fields'

    before
      this.selectOptions = function(overideOptions) {
        return $.extend({
          field_type:'select',
          select_text:'select_text',
          select_options:'first,second,third'
        }, overideOptions)
      }
      this.editorOptions = function(settings) {
        // get() makes the assertions output the dom instead of the last selector if they fail...
        return this.openEditor(this.selectOptions(settings)).find('option').get()
      }
    end

    it 'should show popup with custom values'
      var options = this.editorOptions({ select_options:'foo,bar' })
      options.should.have_length 3
      options[1].should.have_text 'foo'
      options[1].should.have_value 'foo'
      options[2].should.have_text 'bar'
      options[2].should.have_value 'bar'
    end

    it 'should have default value of "" for default value'
      var options = this.editorOptions({ select_text:'fnord' })
      options[0].should.have_text 'fnord'
      options[0].should.have_value ''
    end

    it 'should select item in popup which matches initial text'
      this.sandbox = $('
text
')
      var options = this.editorOptions({ select_options:'foo,text,bar' })
      options.should.have_length 4
      options[2].should.be_selected
    end

    it 'should allow select_options to specify different value and text as text:value'
      var options = this.editorOptions({ select_options:'text:value' })
      options[1].should.have_value 'value'
      options[1].should.have_text 'text'
    end

    it 'should not show spaces in popup specification in dom'
      var options = this.editorOptions({ select_options:'foo, bar, baz' })
      options.should.have_length 4
      options[2].should.have_text 'bar'
      options[2].should.have_value 'bar'
    end

    it 'should allow an array of strings for select values'
      var options = this.editorOptions({ select_options:['foo', 'bar'] })
      options.should.have_length 3
      options[1].should.have_text 'foo'
      options[1].should.have_value 'foo'
    end

    it 'should allow array of array of strings to specify selected value and text as ["text", "value"]'
      var options = this.editorOptions({ select_options:[['text', 'value']] })
      options.should.have_length 2
      options[1].should.have_text 'text'
      options[1].should.have_value 'value'
    end

    it 'should disable default choice in select'
      var options = this.editorOptions()
      options[0].should.be_disabled
    end

    it 'does not submit disabled default choice in select'
      $.should.not.receive 'ajax'
      this.edit(this.selectOptions({
        callback: function(unused, input) { return input; }
      }), '')
      this.sandbox.should.have_text "Some text"
    end

  end

  it 'should throw if unknown field_type is chosen'
    var _this = this;
    -{ _this.openEditor({ field_type: 'fnord' }) }.should.throw_error /Unknown field_type <fnord>/
  end

  it 'can set hover_class parameter to override directly setting colors'
    this.enableEditor({ hover_class: 'fnord'})
    this.sandbox.should.not.have_class 'fnord'
    this.sandbox.mouseenter().should.have_class 'fnord'
    this.sandbox.mouseleave().should.not.have_class 'fnord'
  end

  it 'should still commit if commit_if_nothing_was_changed is specified'
    $.should.receive 'ajax', 'once'
    this.openEditor({save_if_nothing_changed:true}).submit()
  end

  describe 'can override error_sink to get errors as callbacks'

    it 'can get empty value error'
      var sensor = null;
      var options = {
        value_required: true,
        error_sink: function(id, error){ sensor = error; }
      }
      this.edit(options, '')
      sensor.should.match "Error: You must enter a value to save this field"
    end

    it 'can get empty return value from callback error'
      var sensor = null;
      var options = {
        callback: function(){},
        error_sink: function(id, error) { sensor = error; }
      }
      this.edit(options, 'fnord')
      sensor.should.match "Error: Failed to save value: fnord"
    end

    it 'can get xhr submit errors'
      var sensor = null;
      stub($, 'ajax').and_return(function(options) { options.error({ responseText:'fnord' }); })
      var options = { error_sink: function(id, error) { sensor = error; } }
      this.edit(options, 'foo')
      sensor.should.match "fnord"
    end
  end

  it 'should not reset background color on submit if hover_class is specified'
    this.edit({ hover_class: 'fnord' })
    this.sandbox.css('background-color').should.be_within ['', 'inherit', 'transparent']
  end

  it 'should not reset background color on cancel if hover_class is specified'
    this.openEditor({hover_class: 'fnord'}).submit()
    this.sandbox.css('background-color').should.be_within ['', 'inherit', 'transparent']
  end

  it "should respect saving_animation_color (doesn't yet really test that the target color is reached though)"
    stub($, 'ajax').and_return($)
    this.edit({ saving_animation_color: '#002342' })
    // of course IE insists on returning those color values without spaces....
    var expectedColors = ['rgb(255, 255, 255)', 'rgb(255,255,255)']
    this.sandbox.css('backgroundColor').should.be_within expectedColors
    tick(200) // first animation not yet finished
    this.sandbox.css('backgroundColor').should.not.be_within expectedColors
    this.sandbox.is(':animated').should.be true
  end

  describe 'cancelling elements'

    it 'should not open the editor if the clicked element is a cancel element'
      var child = $('is bold')
      this.sandbox.append(child)
      this.enableEditor({ cancel: "em"})
      child.click()
      this.sandbox.should.not.have_tag ':input'
    end

    it 'should not open the editor if the clicked element is child of cancelled element'
      var child = $('is bold')
      this.sandbox.append(child)
      this.enableEditor({ cancel: "p"})
      child.click()
      this.sandbox.should.not.have_tag ':input'
    end

    it 'should open the editor if cancel is empty'
      this.openEditor({ cancel: ""})
      this.sandbox.should.have_tag ':input'
    end

    it 'should not open the editor even clicking on one of two cancel elements'
      this.openEditor({ cancel: "a, p"})
      this.sandbox.should.not.have_tag ':input'
    end

  end

  describe 'editor value interaction can use .html() to'

    before_each
      this.sandbox.html('fnord')
    end

    it 'set the value of the editor'
      this.openEditor({use_html:true}).should.have_value 'fnord'
    end

    it 'select default options for select field'
      this.openEditor({use_html:true, field_type:'select', select_options:['foo:fnord', 'bar:fnord']})
      this.sandbox.find(':input').should.have_value 'fnord'
    end

    it 'determines if nothing changed'
      $.should.receive('ajax')
      this.edit({use_html:true}, 'fnord')
    end

  end

  describe 'can map legacy preference names to new preference names'
    // TODO
  end

end
<commit_msg>fixed last ie test. another case of tag uppercaseritis<commit_after>describe 'custom settings'
  should_behave_like('shared setup')

  it 'will show text during saving to server'
    stub($, 'ajax')
    this.edit({saving_text: 'Saving...'})
    this.sandbox.should.have_text "Saving..."
  end

  it 'should add params as additional parameters to post-url'
    var url
    stub($, 'ajax').and_return(function(options) { url = options.data; })
    this.edit({ params: 'foo=bar'})
    url.should.include 'foo=bar'
  end

  it 'can edit default text shown in empty editors'
    this.sandbox = $('
')
    this.enableEditor({ default_text: 'fnord' }).should.have_text 'fnord'
  end

  it 'should show an empty editor even if default_text was shown in the element'
    this.sandbox = $('
')
    this.enableEditor({ default_text: 'fnord' }).click().find(':input').should.have_text ''
  end

  it 'can show as textarea with specified rows and cols'
    var textarea = this.openEditor({
      field_type:'textarea',
      textarea_rows:23,
      textarea_cols:42
    })

    textarea.should.have_attr 'rows', 23
    textarea.should.have_attr 'cols', 42
  end

  it 'can show as input with specified size'
    var input = this.openEditor({
      field_type: 'text',
      text_size: '23'
    })

    input.should.have_attr 'size', 23
  end

  describe 'select fields'

    before
      this.selectOptions = function(overideOptions) {
        return $.extend({
          field_type:'select',
          select_text:'select_text',
          select_options:'first,second,third'
        }, overideOptions)
      }
      this.editorOptions = function(settings) {
        // get() makes the assertions output the dom instead of the last selector if they fail...
        return this.openEditor(this.selectOptions(settings)).find('option').get()
      }
    end

    it 'should show popup with custom values'
      var options = this.editorOptions({ select_options:'foo,bar' })
      options.should.have_length 3
      options[1].should.have_text 'foo'
      options[1].should.have_value 'foo'
      options[2].should.have_text 'bar'
      options[2].should.have_value 'bar'
    end

    it 'should have default value of "" for default value'
      var options = this.editorOptions({ select_text:'fnord' })
      options[0].should.have_text 'fnord'
      options[0].should.have_value ''
    end

    it 'should select item in popup which matches initial text'
      this.sandbox = $('
text
')
      var options = this.editorOptions({ select_options:'foo,text,bar' })
      options.should.have_length 4
      options[2].should.be_selected
    end

    it 'should allow select_options to specify different value and text as text:value'
      var options = this.editorOptions({ select_options:'text:value' })
      options[1].should.have_value 'value'
      options[1].should.have_text 'text'
    end

    it 'should not show spaces in popup specification in dom'
      var options = this.editorOptions({ select_options:'foo, bar, baz' })
      options.should.have_length 4
      options[2].should.have_text 'bar'
      options[2].should.have_value 'bar'
    end

    it 'should allow an array of strings for select values'
      var options = this.editorOptions({ select_options:['foo', 'bar'] })
      options.should.have_length 3
      options[1].should.have_text 'foo'
      options[1].should.have_value 'foo'
    end

    it 'should allow array of array of strings to specify selected value and text as ["text", "value"]'
      var options = this.editorOptions({ select_options:[['text', 'value']] })
      options.should.have_length 2
      options[1].should.have_text 'text'
      options[1].should.have_value 'value'
    end

    it 'should disable default choice in select'
      var options = this.editorOptions()
      options[0].should.be_disabled
    end

    it 'does not submit disabled default choice in select'
      $.should.not.receive 'ajax'
      this.edit(this.selectOptions({
        callback: function(unused, input) { return input; }
      }), '')
      this.sandbox.should.have_text "Some text"
    end

  end

  it 'should throw if unknown field_type is chosen'
    var _this = this;
    -{ _this.openEditor({ field_type: 'fnord' }) }.should.throw_error /Unknown field_type <fnord>/
  end

  it 'can set hover_class parameter to override directly setting colors'
    this.enableEditor({ hover_class: 'fnord'})
    this.sandbox.should.not.have_class 'fnord'
    this.sandbox.mouseenter().should.have_class 'fnord'
    this.sandbox.mouseleave().should.not.have_class 'fnord'
  end

  it 'should still commit if commit_if_nothing_was_changed is specified'
    $.should.receive 'ajax', 'once'
    this.openEditor({save_if_nothing_changed:true}).submit()
  end

  describe 'can override error_sink to get errors as callbacks'

    it 'can get empty value error'
      var sensor = null;
      var options = {
        value_required: true,
        error_sink: function(id, error){ sensor = error; }
      }
      this.edit(options, '')
      sensor.should.match "Error: You must enter a value to save this field"
    end

    it 'can get empty return value from callback error'
      var sensor = null;
      var options = {
        callback: function(){},
        error_sink: function(id, error) { sensor = error; }
      }
      this.edit(options, 'fnord')
      sensor.should.match "Error: Failed to save value: fnord"
    end

    it 'can get xhr submit errors'
      var sensor = null;
      stub($, 'ajax').and_return(function(options) { options.error({ responseText:'fnord' }); })
      var options = { error_sink: function(id, error) { sensor = error; } }
      this.edit(options, 'foo')
      sensor.should.match "fnord"
    end
  end

  it 'should not reset background color on submit if hover_class is specified'
    this.edit({ hover_class: 'fnord' })
    this.sandbox.css('background-color').should.be_within ['', 'inherit', 'transparent']
  end

  it 'should not reset background color on cancel if hover_class is specified'
    this.openEditor({hover_class: 'fnord'}).submit()
    this.sandbox.css('background-color').should.be_within ['', 'inherit', 'transparent']
  end

  it "should respect saving_animation_color (doesn't yet really test that the target color is reached though)"
    stub($, 'ajax').and_return($)
    this.edit({ saving_animation_color: '#002342' })
    // of course IE insists on returning those color values without spaces....
    var expectedColors = ['rgb(255, 255, 255)', 'rgb(255,255,255)']
    this.sandbox.css('backgroundColor').should.be_within expectedColors
    tick(200) // first animation not yet finished
    this.sandbox.css('backgroundColor').should.not.be_within expectedColors
    this.sandbox.is(':animated').should.be true
  end

  describe 'cancelling elements'

    it 'should not open the editor if the clicked element is a cancel element'
      var child = $('is bold')
      this.sandbox.append(child)
      this.enableEditor({ cancel: "em"})
      child.click()
      this.sandbox.should.not.have_tag ':input'
    end

    it 'should not open the editor if the clicked element is child of cancelled element'
      var child = $('is bold')
      this.sandbox.append(child)
      this.enableEditor({ cancel: "p"})
      child.click()
      this.sandbox.should.not.have_tag ':input'
    end

    it 'should open the editor if cancel is empty'
      this.openEditor({ cancel: ""})
      this.sandbox.should.have_tag ':input'
    end

    it 'should not open the editor even clicking on one of two cancel elements'
      this.openEditor({ cancel: "a, p"})
      this.sandbox.should.not.have_tag ':input'
    end

  end

  describe 'editor value interaction can use .html() to'

    before_each
      this.sandbox.html('fnord')
    end

    it 'set the value of the editor'
      // of course IE has to insist un uppercasing the html-tags...
      this.openEditor({use_html:true}).val().toLowerCase().should.be 'fnord'
    end

    it 'select default options for select field'
      // of course IE has to insist un uppercasing the html-tags...
      this.openEditor({use_html:true, field_type:'select', select_options:['foo:fnord', 'bar:fnord', 'baz:fnord']})
      this.sandbox.find(':input').val().toLowerCase().should.be 'fnord'
    end

    it 'determines if nothing changed'
      $.should.receive('ajax')
      this.edit({use_html:true}, 'fnord')
    end

  end

  describe 'can map legacy preference names to new preference names'
    // TODO
  end

end
<|endoftext|>


<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

//******************************
// Class ContenuPrincipal
function ContenuPrincipal() {
  var self = this;
  var contenuSelector = null;
  var zoneContenuSelector = null;
  var detailSelector = null;
  var parent = null;

  var premierChargement;

  var messagePerso;

  var largeurEcran;
  var largeurVignette;
  var hauteurVignette;

  // constructeur
  this.initialise = function(_parent) {
    self.parent = _parent;
    self.contenuSelector = $('.mainContent');
    self.zoneContenuSelector = self.contenuSelector.find('.zoneContenu');
    self.detailSelector = $('#detailManager');

    self.premierChargement = true;

    self.largeurEcran = Math.floor(window.innerWidth * 0.9);
    self.largeurVignette = Math.floor(self.largeurEcran * 0.5);
    self.hauteurVignette = Math.floor(400 * self.largeurVignette / 300);

    //updateHeightInner();

    //charge affichage de la rubrique Actuelle;
    //this.chargeRubriqueActuelle();
  };

  this.chargeRubriqueActuelle = function(){
    //self.parent.menuNav.fermeMenu();
    //navigator.notification.loadingStart();
      //href data-tpl data-id
      var itemMenu = self.parent.menuNav.getItemMenu(rubriqueActuelle);

      var itemIndice = itemMenu.attr('data-indice');

      var templateAAfficher = "";
      var typeContenu = "";

      /*if((itemMenu.attr('data-tpl') == 'new')||(itemMenu.attr('data-tpl') == 'mes-infos')){
        templateAAfficher = itemMenu.attr('data-tpl')+'.html';
        typeContenu = itemMenu.attr('data-tpl');
      }else{
        templateAAfficher = 'liste.html';
        typeContenu = "liste";
      }*/

      templateAAfficher = entriesTpl[itemIndice]+'.html';
      typeContenu = entriesTpl[itemIndice];

      self.zoneContenuSelector.load('js/tpl/'+templateAAfficher, function(){
        //navigator.notification.loadingStop();
        contenuRempli(typeContenu);
      });

  };

  function contenuRempli(typeContenu){
    var rubriqueCherchee = ""+rubriqueActuelle;
    var itemMenu = self.parent.menuNav.getItemMenu(rubriqueActuelle);
    var itemIndice = itemMenu.attr('data-indice');

    var zoneTitre = "";
    if((typeContenu == "new")||(typeContenu == "liste"))
    {
      zoneTitre = self.zoneContenuSelector.find('.infoRubrique');
      zoneTitre.find('h1').html(entriesTitle[itemIndice]);
    }
    else if(typeContenu == "a-propos")
    {
      self.zoneContenuSelector.find('.appVersion').html(self.parent.getAppVersion());
      self.zoneContenuSelector.find('.dataVersion').html(self.parent.getDataVersion());
    }

    /*if(typeContenu == "mes-infos")
    {
      self.zoneContenuSelector.find('.envoyer a').bind('click', function(event){
        event.preventDefault();
        if($(this).hasClass('sms'))
        {
          envoiChoixParSMS();
        }else{
          ouvreChoixPartage(element,idElement);
        }
      });
    }*/

    var zoneCible = self.zoneContenuSelector.find('.visuels');
    //zoneCible.addClass('small');
    var html = "";
    var position = 0;
    for(var i = 0; i<donneesJson.length; i++)
    {
      var cat = donneesJson[i]['cat'];
      if($.inArray(rubriqueCherchee, cat) > -1)
      {
        html += insereVignette(donneesJson[i],i,position);
        position++;
      }
    }

    zoneCible.html(html);

    zoneCible.find('img').bind('click', function(){ clickSurVignette(this); });

    var zoneRetourMenu = self.zoneContenuSelector.find('#retourMenu a');
    zoneRetourMenu.bind('click', function(event){
      event.preventDefault();
      self.parent.menuNav.ouvreMenu();
    });

    contenuPret();
  }

  function insereVignette(elementVignette,indice,position){
    var html = "";
    //html+='';
    html+='';
    return html;
  }

  function lanceSubstitution(){

    var zoneCible = self.zoneContenuSelector.find('.visuels');
    zoneCible.find('img').each(function(){
      $(this).attr('src', cdn_visuel+'images/preview/'+donneesJson[$(this).attr('data-id')]["preview"]) ;
    });

  }

  function contenuPret(){
    //console.log("contenuPret");
    //self.zoneContenuSelector.scrollTop(0);

    if(self.premierChargement){
      self.premierChargement = false;

      // ajout de l'element iScroll pour gérer le contenu
      setTimeout(function () {
        myScroll = new iScroll('wrapper',{ zoom:true, bounce:false, hScrollbar:false, hScroll:false});
        updateHeightInner();
      }, 100);

      setTimeout(function () {
        // lance fermeture menu
        self.parent.menuNav.fermeMenu();
      }, 2000);

    }else{
      // mise à jour des dimensions + appel au iscroll refresh
      updateHeightInner();
      // lance fermeture menu
      self.parent.menuNav.fermeMenu();
    }

    lanceSubstitution();

  }

  function clickSurVignette(element){
    // à tester pour prévenir d'un click pendant le scroll
    //if (myScroll.moved) return;

    var vignette = $(element);
    /*if(!vignette.parent().hasClass('small'))
    {
      modePersonnalisation(element);
    }else{
      // click sur petite on agrandit
      vignette.parent().removeClass('small');
      deplaceScrollbar(element);
    } */
    modePersonnalisation(element);
  }

  function deplaceScrollbar(element)
  {
    var vignette = $(element);
    var decalage = 0;
    if(self.zoneContenuSelector.find('.messageWelcome').length > 0)
    {
      decalage = self.zoneContenuSelector.find('.messageWelcome').height();
    }
    var distance = (vignette.attr('data-position')*vignette.height()) + decalage;
    self.zoneContenuSelector.animate({'scrollTop':distance},500);

  }

  function modePersonnalisation(element){
    // désactive navigation
    self.parent.menuNav.desactiveMenu();

    var vignette = $(element);
    vignette.addClass('selected');
    self.detailSelector.load('js/tpl/detail.html', function(){
      // récuperation de la fiche de l'élément
      var idElement = vignette.attr('data-id');
      var elementVignette = donneesJson[idElement];

      var idShare = elementVignette["id"];

      var titre = elementVignette["texte"].split('
')[0];
      var reg=new RegExp("(
)", "g")
      self.messagePerso = "";//elementVignette["texte"].replace(reg, ' ');

      var imagePreview = cdn_visuel+'images/preview/'+elementVignette["preview"];
      var imageVierge = cdn_visuel+'images/image/'+elementVignette["preview"];

      // customisation de la fiche detail
      //self.detailSelector.find('.titre').html('
'+titre+'...
');
      self.detailSelector.find('.titre').html('

');
      self.detailSelector.find('.visuel').html('');

      // liaison des boutons
      self.detailSelector.find('.fermer a').bind('click', function(event){
        event.preventDefault();
        fermerDetail(element);
      });

      self.detailSelector.find('.envoyer a').bind('click', function(event){
        event.preventDefault();
        if($(this).hasClass('share'))
        {
          ouvreChoixPartage(element,idElement);
        }else if($(this).hasClass('share-sms'))
        {
          ouvreChoixPartage(element,idElement);
        }else if($(this).hasClass('share-mail'))
        {
          envoiChoixParMail(element,idElement);
        }else if($(this).hasClass('share-fb'))
        {
          ouvreChoixPartage(element,idElement);
        }else if($(this).hasClass('share-tw'))
        {
          ouvreChoixPartage(element,idElement);
        }

        $.ajax({
                  type: 'POST',
                  url: webservice_stats,
                  data: {id:idShare},
                  async:true
                })

      });

      self.detailSelector.addClass('affiche');
      self.detailSelector.height(window.innerHeight);
      self.detailSelector.animate({'opacity':1},500);
    });
  }

  function fermerDetail(element){
    // désactive navigation
    self.parent.menuNav.activeMenu();

    var vignette = $(element);
    vignette.removeClass('selected');

    self.detailSelector.animate({'opacity':0},500, function(){
      self.detailSelector.removeClass('affiche');

      self.detailSelector.find('.fermer a').unbind('click');

      //vide detail
      self.detailSelector.html('');
    });
  }

  function ouvreChoixPartage(element,idElement){
    var vignette = $(element);
    var elementVignette = donneesJson[idElement];

    var imageToShare = cdn_visuel+'images/preview/'+elementVignette["preview"];

        //window.plugins.socialsharing.share(null, null, imageToShare);
        var socialShare = window.plugins.socialsharing;
        socialShare.available(function(isAvailable) {
          if (isAvailable) {

            var imageToShare = cdn_visuel+'images/preview/'+elementVignette["preview"];

            self.messagePerso = '

Offrez, vous aussi, une bonne (ou mauvaise) résolution : wishit.freetouch.fr';
                    //"Offrez, vous aussi, une bonne (ou mauvaise) résolution";

            //share('message', 'sujet', 'image', 'site web');
            window.plugins.socialsharing.share(self.messagePerso, 'Bonne année et...', imageToShare, website_app);
          }
        });

  }

  function envoiChoixParSMS(){ //element,idElement){
    //var vignette = $(element);
    //var elementVignette = donneesJson[idElement];

    //var imageToShare = cdn_visuel+'images/preview/'+elementVignette["preview"];
    //var imageToShare = cdn_visuel+'images/preview/requin.jpg';
    //self.messagePerso, 'Meilleurs voeux 2014', imageToShare, website_app);
    //window.location.href = "sms:contactno?body=Meilleurs voeux 2014";
  }

  function envoiChoixParMail(element,idElement){
    var vignette = $(element);
    var elementVignette = donneesJson[idElement];

    var imageToShare = cdn_visuel+'images/preview/'+elementVignette["preview"];

    var mailShare = plugin.email;
    mailShare.isServiceAvailable(function(isAvailable) {
      if (isAvailable) {
        mailShare.open({
            to:      [],
            cc:      [],
            bcc:     [],
            subject: 'Bonne année et...',
            body:    '

Offrez, vous aussi, une bonne (ou mauvaise) résolution : wishit.freetouch.fr',
            isHtml:  true
        });
      }
    });

  }

  // à déplacer dans la partie gestion de contenu
  function updateHeightInner() {
    self.contenuSelector.height(window.innerHeight);
    self.contenuSelector.width((window.innerWidth - 10));
    self.contenuSelector.css('margin-left','10px');

    //self.zoneContenuSelector.height(window.innerHeight);

    $("#wrapper").height(window.innerHeight);

    myScroll.refresh();
    // remonte le scroll en 0, 0 en 0 ms
    myScroll.scrollTo(0, 0, 0);

  }
}<commit_msg>suppression test html dans partage<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

//******************************
// Class ContenuPrincipal
function ContenuPrincipal() {
  var self = this;
  var contenuSelector = null;
  var zoneContenuSelector = null;
  var detailSelector = null;
  var parent = null;

  var premierChargement;

  var messagePerso;

  var largeurEcran;
  var largeurVignette;
  var hauteurVignette;

  // constructeur
  this.initialise = function(_parent) {
    self.parent = _parent;
    self.contenuSelector = $('.mainContent');
    self.zoneContenuSelector = self.contenuSelector.find('.zoneContenu');
    self.detailSelector = $('#detailManager');

    self.premierChargement = true;

    self.largeurEcran = Math.floor(window.innerWidth * 0.9);
    self.largeurVignette = Math.floor(self.largeurEcran * 0.5);
    self.hauteurVignette = Math.floor(400 * self.largeurVignette / 300);

    //updateHeightInner();

    //charge affichage de la rubrique Actuelle;
    //this.chargeRubriqueActuelle();
  };

  this.chargeRubriqueActuelle = function(){
    //self.parent.menuNav.fermeMenu();
    //navigator.notification.loadingStart();
      //href data-tpl data-id
      var itemMenu = self.parent.menuNav.getItemMenu(rubriqueActuelle);

      var itemIndice = itemMenu.attr('data-indice');

      var templateAAfficher = "";
      var typeContenu = "";

      /*if((itemMenu.attr('data-tpl') == 'new')||(itemMenu.attr('data-tpl') == 'mes-infos')){
        templateAAfficher = itemMenu.attr('data-tpl')+'.html';
        typeContenu = itemMenu.attr('data-tpl');
      }else{
        templateAAfficher = 'liste.html';
        typeContenu = "liste";
      }*/

      templateAAfficher = entriesTpl[itemIndice]+'.html';
      typeContenu = entriesTpl[itemIndice];

      self.zoneContenuSelector.load('js/tpl/'+templateAAfficher, function(){
        //navigator.notification.loadingStop();
        contenuRempli(typeContenu);
      });

  };

  function contenuRempli(typeContenu){
    var rubriqueCherchee = ""+rubriqueActuelle;
    var itemMenu = self.parent.menuNav.getItemMenu(rubriqueActuelle);
    var itemIndice = itemMenu.attr('data-indice');

    var zoneTitre = "";
    if((typeContenu == "new")||(typeContenu == "liste"))
    {
      zoneTitre = self.zoneContenuSelector.find('.infoRubrique');
      zoneTitre.find('h1').html(entriesTitle[itemIndice]);
    }
    else if(typeContenu == "a-propos")
    {
      self.zoneContenuSelector.find('.appVersion').html(self.parent.getAppVersion());
      self.zoneContenuSelector.find('.dataVersion').html(self.parent.getDataVersion());
    }

    /*if(typeContenu == "mes-infos")
    {
      self.zoneContenuSelector.find('.envoyer a').bind('click', function(event){
        event.preventDefault();
        if($(this).hasClass('sms'))
        {
          envoiChoixParSMS();
        }else{
          ouvreChoixPartage(element,idElement);
        }
      });
    }*/

    var zoneCible = self.zoneContenuSelector.find('.visuels');
    //zoneCible.addClass('small');
    var html = "";
    var position = 0;
    for(var i = 0; i<donneesJson.length; i++)
    {
      var cat = donneesJson[i]['cat'];
      if($.inArray(rubriqueCherchee, cat) > -1)
      {
        html += insereVignette(donneesJson[i],i,position);
        position++;
      }
    }

    zoneCible.html(html);

    zoneCible.find('img').bind('click', function(){ clickSurVignette(this); });

    var zoneRetourMenu = self.zoneContenuSelector.find('#retourMenu a');
    zoneRetourMenu.bind('click', function(event){
      event.preventDefault();
      self.parent.menuNav.ouvreMenu();
    });

    contenuPret();
  }

  function insereVignette(elementVignette,indice,position){
    var html = "";
    //html+='';
    html+='';
    return html;
  }

  function lanceSubstitution(){

    var zoneCible = self.zoneContenuSelector.find('.visuels');
    zoneCible.find('img').each(function(){
      $(this).attr('src', cdn_visuel+'images/preview/'+donneesJson[$(this).attr('data-id')]["preview"]) ;
    });

  }

  function contenuPret(){
    //console.log("contenuPret");
    //self.zoneContenuSelector.scrollTop(0);

    if(self.premierChargement){
      self.premierChargement = false;

      // ajout de l'element iScroll pour gérer le contenu
      setTimeout(function () {
        myScroll = new iScroll('wrapper',{ zoom:true, bounce:false, hScrollbar:false, hScroll:false});
        updateHeightInner();
      }, 100);

      setTimeout(function () {
        // lance fermeture menu
        self.parent.menuNav.fermeMenu();
      }, 2000);

    }else{
      // mise à jour des dimensions + appel au iscroll refresh
      updateHeightInner();
      // lance fermeture menu
      self.parent.menuNav.fermeMenu();
    }

    lanceSubstitution();

  }

  function clickSurVignette(element){
    // à tester pour prévenir d'un click pendant le scroll
    //if (myScroll.moved) return;

    var vignette = $(element);
    /*if(!vignette.parent().hasClass('small'))
    {
      modePersonnalisation(element);
    }else{
      // click sur petite on agrandit
      vignette.parent().removeClass('small');
      deplaceScrollbar(element);
    } */
    modePersonnalisation(element);
  }

  function deplaceScrollbar(element)
  {
    var vignette = $(element);
    var decalage = 0;
    if(self.zoneContenuSelector.find('.messageWelcome').length > 0)
    {
      decalage = self.zoneContenuSelector.find('.messageWelcome').height();
    }
    var distance = (vignette.attr('data-position')*vignette.height()) + decalage;
    self.zoneContenuSelector.animate({'scrollTop':distance},500);

  }

  function modePersonnalisation(element){
    // désactive navigation
    self.parent.menuNav.desactiveMenu();

    var vignette = $(element);
    vignette.addClass('selected');
    self.detailSelector.load('js/tpl/detail.html', function(){
      // récuperation de la fiche de l'élément
      var idElement = vignette.attr('data-id');
      var elementVignette = donneesJson[idElement];

      var idShare = elementVignette["id"];

      var titre = elementVignette["texte"].split('
')[0];
      var reg=new RegExp("(
)", "g")
      self.messagePerso = "";//elementVignette["texte"].replace(reg, ' ');

      var imagePreview = cdn_visuel+'images/preview/'+elementVignette["preview"];
      var imageVierge = cdn_visuel+'images/image/'+elementVignette["preview"];

      // customisation de la fiche detail
      //self.detailSelector.find('.titre').html('
'+titre+'...
');
      self.detailSelector.find('.titre').html('

');
      self.detailSelector.find('.visuel').html('');

      // liaison des boutons
      self.detailSelector.find('.fermer a').bind('click', function(event){
        event.preventDefault();
        fermerDetail(element);
      });

      self.detailSelector.find('.envoyer a').bind('click', function(event){
        event.preventDefault();
        if($(this).hasClass('share'))
        {
          ouvreChoixPartage(element,idElement);
        }else if($(this).hasClass('share-sms'))
        {
          ouvreChoixPartage(element,idElement);
        }else if($(this).hasClass('share-mail'))
        {
          envoiChoixParMail(element,idElement);
        }else if($(this).hasClass('share-fb'))
        {
          ouvreChoixPartage(element,idElement);
        }else if($(this).hasClass('share-tw'))
        {
          ouvreChoixPartage(element,idElement);
        }

        $.ajax({
                  type: 'POST',
                  url: webservice_stats,
                  data: {id:idShare},
                  async:true
                })

      });

      self.detailSelector.addClass('affiche');
      self.detailSelector.height(window.innerHeight);
      self.detailSelector.animate({'opacity':1},500);
    });
  }

  function fermerDetail(element){
    // désactive navigation
    self.parent.menuNav.activeMenu();

    var vignette = $(element);
    vignette.removeClass('selected');

    self.detailSelector.animate({'opacity':0},500, function(){
      self.detailSelector.removeClass('affiche');

      self.detailSelector.find('.fermer a').unbind('click');

      //vide detail
      self.detailSelector.html('');
    });
  }

  function ouvreChoixPartage(element,idElement){
    var vignette = $(element);
    var elementVignette = donneesJson[idElement];

    var imageToShare = cdn_visuel+'images/preview/'+elementVignette["preview"];

        //window.plugins.socialsharing.share(null, null, imageToShare);
        var socialShare = window.plugins.socialsharing;
        socialShare.available(function(isAvailable) {
          if (isAvailable) {

            var imageToShare = cdn_visuel+'images/preview/'+elementVignette["preview"];

            //self.messagePerso = '

Offrez, vous aussi, une bonne (ou mauvaise) résolution : wishit.freetouch.fr';
            self.messagePerso = "Offrez, vous aussi, une bonne (ou mauvaise) résolution";

            //share('message', 'sujet', 'image', 'site web');
            window.plugins.socialsharing.share(self.messagePerso, 'Bonne année et...', imageToShare, website_app);
          }
        });

  }

  function envoiChoixParSMS(){ //element,idElement){
    //var vignette = $(element);
    //var elementVignette = donneesJson[idElement];

    //var imageToShare = cdn_visuel+'images/preview/'+elementVignette["preview"];
    //var imageToShare = cdn_visuel+'images/preview/requin.jpg';
    //self.messagePerso, 'Meilleurs voeux 2014', imageToShare, website_app);
    //window.location.href = "sms:contactno?body=Meilleurs voeux 2014";
  }

  function envoiChoixParMail(element,idElement){
    var vignette = $(element);
    var elementVignette = donneesJson[idElement];

    var imageToShare = cdn_visuel+'images/preview/'+elementVignette["preview"];

    var mailShare = plugin.email;
    mailShare.isServiceAvailable(function(isAvailable) {
      if (isAvailable) {
        mailShare.open({
            to:      [],
            cc:      [],
            bcc:     [],
            subject: 'Bonne année et...',
            body:    '

Offrez, vous aussi, une bonne (ou mauvaise) résolution : wishit.freetouch.fr',
            isHtml:  true
        });
      }
    });

  }

  // à déplacer dans la partie gestion de contenu
  function updateHeightInner() {
    self.contenuSelector.height(window.innerHeight);
    self.contenuSelector.width((window.innerWidth - 10));
    self.contenuSelector.css('margin-left','10px');

    //self.zoneContenuSelector.height(window.innerHeight);

    $("#wrapper").height(window.innerHeight);

    myScroll.refresh();
    // remonte le scroll en 0, 0 en 0 ms
    myScroll.scrollTo(0, 0, 0);

  }
}<|endoftext|>


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

    angular.module('scaleApp').service('jobTypeService', function ($http, $q, $resource, poller, pollerFactory, scaleConfig, jobService, JobType, JobTypeDetails, JobTypeStatus) {
        /*var totalJobTypes = 5;

        var getTotalJobTypes = function () {
            return totalJobTypes;
        };

        var setTotalJobTypes = function () {
            totalJobTypes = Math.floor(Math.random() * (20 - 1 + 1)) + 1;
        };

        setInterval(function () {
            setTotalJobTypes();
        }, 3100);*/

        var getJobTypeParams = function (page, page_size, started, ended, name, category, order) {
            return {
                page: page,
                page_size: page_size ? page_size : 1000,
                started: started,
                ended: ended,
                name: name,
                category: category,
                order: order ? order : ['title', 'version']
            };
        };

        var getJobTypeStatusParams = function (page, page_size, started, ended) {
            return {
                page: page,
                page_size: page_size ? page_size : 1000,
                started: started,
                ended: ended
            };
        };

        return {
            getJobTypes: function (params) {
                params = params || getJobTypeParams();
                // var params = {
                //     order: order || ['name','version']
                // };

                var jobTypesResource = $resource(scaleConfig.urls.apiPrefix + 'job-types/', params),
                    jobTypesPoller = pollerFactory.newPoller(jobTypesResource, scaleConfig.pollIntervals.jobTypes);

                return jobTypesPoller.promise.then(null, null, function (data) {
                    if (data.$resolved) {
                        /*var returnResult = {
                            $resolved: true,
                            job_types: []
                        };
                        for (var i = 1; i < getTotalJobTypes(); i++) {
                            returnResult.job_types.push(
                                {
                                    "is_system": true,
                                    "paused": null,
                                    "disk": 64.0,
                                    "id": i,
                                    "docker_image": null,
                                    "archived": null,
                                    "uses_docker": false,
                                    "priority": 10,
                                    "version": "1.0",
                                    "icon_code": scaleConfig.jobTypes[i - 1].code,
                                    "description": "Ingests a source file into a workspace",
                                    "mem": 64.0,
                                    "is_active": true,
                                    "cpus": 1.0,
                                    "last_modified": "2015-03-11T00:00:00Z",
                                    "max_tries": 3,
                                    "is_paused": false,
                                    "name": scaleConfig.jobTypes[i - 1].title,
                                    "created": "2015-03-11T00:00:00Z",
                                    "timeout": 1800,
                                    "is_long_running": false
                                }
                            )
                        }
                        result = returnResult;*/

                        data.results = JobType.transformer(data.results);
                        return data;
                    } else {
                        jobTypesPoller.stop();
                        return data;
                    }
                });
            },
            getJobTypesOnce: function (params) {
                params = params || getJobTypeParams();

                var d = $q.defer();

                $http({
                    url: scaleConfig.urls.apiPrefix + 'job-types/',
                    method: 'GET',
                    params: params
                }).success(function (data) {
                    data.results = JobType.transformer(data.results);
                    d.resolve(data);
                }).error(function (error) {
                    d.reject(error);
                });
                return d.promise;
            },
            getJobTypeStatus: function (params) {
                params = params || getJobTypeStatusParams();

                var jobTypeStatusResource = $resource(scaleConfig.urls.apiPrefix + 'job-types/status/', params),
                    jobTypeStatusPoller = pollerFactory.newPoller(jobTypeStatusResource, scaleConfig.pollIntervals.jobTypeStatus);

                return jobTypeStatusPoller.promise.then(null, null, function (data) {
                    if (data.$resolved) {
                        /*var returndata = {
                            $resolved: true,
                            job_type_stats: []
                        };
                        for (var i = 0; i < getTotalJobTypes(); i++) {
                            returndata.job_type_stats.push(
                                {
                                    "id": i,
                                    "icon_code": "",
                                    "name": "",
                                    "version": "",
                                    "num_completed": Math.floor(Math.random() * (20000 - 10000 + 1)) + 10000,
                                    "num_canceled": Math.floor(Math.random() * (100 - 20 + 1)) + 20,
                                    "num_error_DATA": Math.floor(Math.random() * (9000 - 20 + 1)) + 20,
                                    "num_error_SYSTEM": Math.floor(Math.random() * (9000 - 20 + 1)) + 20,
                                    "num_error_ALGORITHM": Math.floor(Math.random() * (9000 - 20 + 1)) + 20
                                }
                            )
                        }
                        data = returndata;*/

                        data.results = JobTypeStatus.transformer(data.results);
                    } else {
                        jobTypeStatusPoller.stop();
                    }
                    return data;
                });
            },
            getJobTypeStatusOnce: function (params) {
                var d = $q.defer();

                params = params || getJobTypeStatusParams();

                $http({
                    url: scaleConfig.urls.apiPrefix + 'job-types/status/',
                    method: 'GET',
                    params: params
                }).success(function (data) {
                    data.results = JobTypeStatus.transformer(data.results);
                    d.resolve(data);
                }).error(function (error) {
                    d.reject(error);
                });
                return d.promise;
            },
            getJobTypeDetails: function (id) {
                var d = $q.defer();
                $http.get(scaleConfig.urls.apiPrefix + 'job-types/' + id + '/').success(function (data) {
                    d.resolve(JobTypeDetails.transformer(data));
                }).error(function (error) {
                    d.reject(error);
                });
                return d.promise;
            },
            updateJobType: function (data){
                var updatedJobType = function(data){
                    return {
                        error_mappings: data.error_mappings,
                        is_paused: data.is_paused
                    };
                };
                var updatedData = updatedJobType(data);
                var d = $q.defer();

                $http({
                    url: scaleConfig.urls.apiPrefix + 'job-types/' + data.id + '/',
                    method: 'PATCH',
                    data: updatedData
                }).success(function (result) {
                    d.resolve(JobTypeDetails.transformer(result));
                }).error(function (error) {
                    d.reject(error);
                });
                return d.promise;
            }
        };
    });
})();
<commit_msg>modified jobTypesService to use API prefix override config<commit_after>(function () {
    'use strict';

    angular.module('scaleApp').service('jobTypeService', function ($http, $q, $resource, poller, pollerFactory, scaleConfig, jobService, JobType, JobTypeDetails, JobTypeStatus) {
        /*var totalJobTypes = 5;

        var getTotalJobTypes = function () {
            return totalJobTypes;
        };

        var setTotalJobTypes = function () {
            totalJobTypes = Math.floor(Math.random() * (20 - 1 + 1)) + 1;
        };

        setInterval(function () {
            setTotalJobTypes();
        }, 3100);*/

        var getJobTypeParams = function (page, page_size, started, ended, name, category, order) {
            return {
                page: page,
                page_size: page_size ? page_size : 1000,
                started: started,
                ended: ended,
                name: name,
                category: category,
                order: order ? order : ['title', 'version']
            };
        };

        var getJobTypeStatusParams = function (page, page_size, started, ended) {
            return {
                page: page,
                page_size: page_size ? page_size : 1000,
                started: started,
                ended: ended
            };
        };

        return {
            getJobTypes: function (params) {
                params = params || getJobTypeParams();
                // var params = {
                //     order: order || ['name','version']
                // };

                var jobTypesResource = $resource(scaleConfig.getUrlPrefix('job-types') + 'job-types/', params),
                    jobTypesPoller = pollerFactory.newPoller(jobTypesResource, scaleConfig.pollIntervals.jobTypes);

                return jobTypesPoller.promise.then(null, null, function (data) {
                    if (data.$resolved) {
                        /*var returnResult = {
                            $resolved: true,
                            job_types: []
                        };
                        for (var i = 1; i < getTotalJobTypes(); i++) {
                            returnResult.job_types.push(
                                {
                                    "is_system": true,
                                    "paused": null,
                                    "disk": 64.0,
                                    "id": i,
                                    "docker_image": null,
                                    "archived": null,
                                    "uses_docker": false,
                                    "priority": 10,
                                    "version": "1.0",
                                    "icon_code": scaleConfig.jobTypes[i - 1].code,
                                    "description": "Ingests a source file into a workspace",
                                    "mem": 64.0,
                                    "is_active": true,
                                    "cpus": 1.0,
                                    "last_modified": "2015-03-11T00:00:00Z",
                                    "max_tries": 3,
                                    "is_paused": false,
                                    "name": scaleConfig.jobTypes[i - 1].title,
                                    "created": "2015-03-11T00:00:00Z",
                                    "timeout": 1800,
                                    "is_long_running": false
                                }
                            )
                        }
                        result = returnResult;*/

                        data.results = JobType.transformer(data.results);
                        return data;
                    } else {
                        jobTypesPoller.stop();
                        return data;
                    }
                });
            },
            getJobTypesOnce: function (params) {
                params = params || getJobTypeParams();

                var d = $q.defer();

                $http({
                    url: scaleConfig.getUrlPrefix('job-types') + 'job-types/',
                    method: 'GET',
                    params: params
                }).success(function (data) {
                    data.results = JobType.transformer(data.results);
                    d.resolve(data);
                }).error(function (error) {
                    d.reject(error);
                });
                return d.promise;
            },
            getJobTypeStatus: function (params) {
                params = params || getJobTypeStatusParams();

                var jobTypeStatusResource = $resource(scaleConfig.getUrlPrefix('job-types') + 'job-types/status/', params),
                    jobTypeStatusPoller = pollerFactory.newPoller(jobTypeStatusResource, scaleConfig.pollIntervals.jobTypeStatus);

                return jobTypeStatusPoller.promise.then(null, null, function (data) {
                    if (data.$resolved) {
                        /*var returndata = {
                            $resolved: true,
                            job_type_stats: []
                        };
                        for (var i = 0; i < getTotalJobTypes(); i++) {
                            returndata.job_type_stats.push(
                                {
                                    "id": i,
                                    "icon_code": "",
                                    "name": "",
                                    "version": "",
                                    "num_completed": Math.floor(Math.random() * (20000 - 10000 + 1)) + 10000,
                                    "num_canceled": Math.floor(Math.random() * (100 - 20 + 1)) + 20,
                                    "num_error_DATA": Math.floor(Math.random() * (9000 - 20 + 1)) + 20,
                                    "num_error_SYSTEM": Math.floor(Math.random() * (9000 - 20 + 1)) + 20,
                                    "num_error_ALGORITHM": Math.floor(Math.random() * (9000 - 20 + 1)) + 20
                                }
                            )
                        }
                        data = returndata;*/

                        data.results = JobTypeStatus.transformer(data.results);
                    } else {
                        jobTypeStatusPoller.stop();
                    }
                    return data;
                });
            },
            getJobTypeStatusOnce: function (params) {
                var d = $q.defer();

                params = params || getJobTypeStatusParams();

                $http({
                    url: scaleConfig.getUrlPrefix('job-types') + 'job-types/status/',
                    method: 'GET',
                    params: params
                }).success(function (data) {
                    data.results = JobTypeStatus.transformer(data.results);
                    d.resolve(data);
                }).error(function (error) {
                    d.reject(error);
                });
                return d.promise;
            },
            getJobTypeDetails: function (id) {
                var d = $q.defer();
                $http.get(scaleConfig.getUrlPrefix('job-types') + 'job-types/' + id + '/').success(function (data) {
                    d.resolve(JobTypeDetails.transformer(data));
                }).error(function (error) {
                    d.reject(error);
                });
                return d.promise;
            },
            updateJobType: function (data){
                var updatedJobType = function(data){
                    return {
                        error_mappings: data.error_mappings,
                        is_paused: data.is_paused
                    };
                };
                var updatedData = updatedJobType(data);
                var d = $q.defer();

                $http({
                    url: scaleConfig.getUrlPrefix('job-types') + 'job-types/' + data.id + '/',
                    method: 'PATCH',
                    data: updatedData
                }).success(function (result) {
                    d.resolve(JobTypeDetails.transformer(result));
                }).error(function (error) {
                    d.reject(error);
                });
                return d.promise;
            }
        };
    });
})();
<|endoftext|>


<commit_before>/**
 * Автокомплит к поисковой строке
 * Author: CupIvan <mail@cupivan.ru>
 */

$(function()
{
	/** подготовка запроса к серверу */
	var prepareRequest = function(x)
	{
		x = x.replace(/([\.,])(\S)/,  '$1 $2'); // отделяем сокращения от слова
		x = x.replace(/([кдс])(\d)/g, '$1 $2').replace(/(\d)([кдс])/g, '$1 $2'); // 4к4 -> 4 к 4
		x = x.replace('пр-т', 'проспект');
		return x;
	}

	/** сокращатель полной формы адреса в читаемый вариант */
	var toShortName = function(x)
	{
		x = x.replace('дом ',      'д. ');
		x = x.replace('корпус ',   'к. ');
		x = x.replace('строение ', 'с. ');
		x = x.replace('улица ',    'ул. ');
		x = x.replace('город ',    'г. ');
		x = x.replace(/[^,]*?(край|область|Башкортостан|Татарстан), /, '');
		return x;
	}

	/** подсветка слов в результатах */
	var highlight = function(x, q)
	{
		var i;
		q = prepareRequest(q);
		q = q.replace(/[^а-яёa-z0-9]/ig, ' ').replace(/\s+/, ' ');
		q = q.replace(/[её]/g, '[её]'); // в запросе считаем е и ё одной буквой
		q = q.split(' ');
		for (i in q) if (q[i])
			x = x.replace(new RegExp('(\\s|^)('+q[i]+')', 'ig'), '$1$2');
		return x;
	}

	// подключаемся к поисковой строке
	$('#qsearch').autocomplete({
		source: function(request, response)
		{
			// запрос на сервер
			jQuery.ajax({
				url: '/api/autocomplete',
				dataType: 'json',
				minLength: 3,
				data: {
					q: prepareRequest(request.term),
					bbox: osm.map.getBounds().toBBoxString()
				},
				success: function(data)
				{
					if (data && data.find)
					response($.map(data.matches, function(item)
					{
						item.label = highlight(item.name, request.term);
						item.value = toShortName(item.display_name);
						return item;
					}));
					else $('#qsearch').autocomplete('close'); // ничего не найдено, закрываем подсказку
				}
			});
		},
		// при выборе варианта показываем метку на карте
		select: function(event, ui)
		{
			if (!ui.item) return;
			osm.leftpan.toggleItem('leftsearch', true); // открываем левую панельку поиска
			search.processResults({find: true, matches: [ui.item]}); // имитируем результат поиска с сервера
			search.enable(); // показываем результаты поиска
		}
	}).keyup(function(e){
		// закрываем подсказку по Enter
		if (e.keyCode == 13)
			$('#qsearch').autocomplete('close')
	})
	// рендерим строки подсказки с учетом тегов
	$('#qsearch').data("autocomplete")._renderItem = function(ul, item)
	{
		return $("
")
			.data("item.autocomplete", item)
			.append("" + item.label + "")
			.appendTo(ul);
	}
	//Увеличиваем z-index, что бы элементы панели не перекрывали
	$('#qsearch').data("autocomplete")._renderMenu = function(ul, items){
		$(ul).css({zIndex:2000})
	}
	// ставим шрифт в поисковой строке, такой же как у подсказок
	$('#qsearch').addClass('ui-widget');
});
<commit_msg>issue #241<commit_after>/**
 * Автокомплит к поисковой строке
 * Author: CupIvan <mail@cupivan.ru>
 */

$(function()
{
	/** подготовка запроса к серверу */
	var prepareRequest = function(x)
	{
		x = x.replace(/([\.,])(\S)/,  '$1 $2'); // отделяем сокращения от слова
		x = x.replace(/([кдс])(\d)/g, '$1 $2').replace(/(\d)([кдс])/g, '$1 $2'); // 4к4 -> 4 к 4
		x = x.replace('пр-т', 'проспект');
		return x;
	}

	/** сокращатель полной формы адреса в читаемый вариант */
	var toShortName = function(x)
	{
		x = x.replace('дом ',      'д. ');
		x = x.replace('корпус ',   'к. ');
		x = x.replace('строение ', 'с. ');
		x = x.replace('улица ',    'ул. ');
		x = x.replace('город ',    'г. ');
		x = x.replace(/[^,]*?(край|область|Башкортостан|Татарстан), /, '');
		return x;
	}

	/** подсветка слов в результатах */
	var highlight = function(x, q)
	{
		var i;
		q = prepareRequest(q);
		q = q.replace(/[^а-яёa-z0-9]/ig, ' ').replace(/\s+/, ' ');
		q = q.replace(/[её]/g, '[её]'); // в запросе считаем е и ё одной буквой
		q = q.split(' ');
		for (i in q) if (q[i])
			x = x.replace(new RegExp('(\\s|^)('+q[i]+')', 'ig'), '$1$2');
		return x;
	}

	// подключаемся к поисковой строке
	$('#qsearch').autocomplete({
		source: function(request, response)
		{
			// запрос на сервер
			jQuery.ajax({
				url: '/api/autocomplete',
				dataType: 'json',
				minLength: 3,
				data: {
					q: prepareRequest(request.term),
					bbox: osm.map.getBounds().toBBoxString()
				},
				success: function(data)
				{
					if (data && data.find)
					response($.map(data.matches, function(item)
					{
						item.label = highlight(item.name, request.term);
						item.value = toShortName(item.display_name);
						return item;
					}));
					else $('#qsearch').autocomplete('close'); // ничего не найдено, закрываем подсказку
				}
			});
		},
		// при выборе варианта показываем метку на карте
		select: function(event, ui)
		{
			if (!ui.item) return;
			osm.leftpan.toggleItem('leftsearch', true); // открываем левую панельку поиска
			search.processResults({find: true, matches: [ui.item]}); // имитируем результат поиска с сервера
			search.enable(); // показываем результаты поиска
		}
	}).keyup(function(e){
		// закрываем подсказку по Enter
		if (e.keyCode == 13)
			$('#qsearch').autocomplete('close')
	})
	// рендерим строки подсказки с учетом тегов
	$('#qsearch').data("autocomplete")._renderItem = function(ul, item)
	{
		return $("
")
			.data("item.autocomplete", item)
			.append("" + item.label + "")
			.appendTo(ul);
	}
	//Увеличиваем z-index, что бы элементы панели не перекрывали
	$('#qsearch').data("autocomplete")._renderMenu = function(ul, items){
		var that = this;
		$(ul).css({zIndex:2000})
		$.each(items, function(index, item) {
			that._renderItemData(ul, item);
		});
	}
	// ставим шрифт в поисковой строке, такой же как у подсказок
	$('#qsearch').addClass('ui-widget');
});
<|endoftext|>