Looking through the ESLint code, I can't find where this sort of stuff is implemented:
':function': (node: TSESTree.Node) => {
onEnterFunction(node as TSESTree.FunctionLike);
},
':function:exit'(node: TSESTree.Node) {
onLeaveFunction(node as TSESTree.FunctionLike);
},
'*'(node: TSESTree.Node) {
if (nestingNodes.has(node)) {
nesting++;
}
},
'*:exit'(node: TSESTree.Node) {
if (nestingNodes.has(node)) {
nesting--;
nestingNodes.delete(node);
}
},
Specifically the "matcher" keys like *:exit, and I've seen much more complicated CSS-selector-like expressions. Where in the ESLint source is the handler for these implemented?
I would like to see how it's implemented to implement on my own.
It looks like it is implemented in esquery.
function matches(node, selector, ancestry, options) {
if (!selector) { return true; }
if (!node) { return false; }
if (!ancestry) { ancestry = []; }
switch(selector.type) {
case 'wildcard':
return true;
case 'identifier':
return selector.value.toLowerCase() === node.type.toLowerCase();
case 'field': {
const path = selector.name.split('.');
const ancestor = ancestry[path.length - 1];
return inPath(node, ancestor, path);
}
case 'matches':
for (const sel of selector.selectors) {
if (matches(node, sel, ancestry, options)) { return true; }
}
return false;
case 'compound':
for (const sel of selector.selectors) {
if (!matches(node, sel, ancestry, options)) { return false; }
}
return true;
case 'not':
for (const sel of selector.selectors) {
if (matches(node, sel, ancestry, options)) { return false; }
}
return true;
case 'has': {
const collector = [];
for (const sel of selector.selectors) {
const a = [];
estraverse.traverse(node, {
enter (node, parent) {
if (parent != null) { a.unshift(parent); }
if (matches(node, sel, a, options)) {
collector.push(node);
}
},
leave () { a.shift(); },
keys: options && options.visitorKeys,
fallback: options && options.fallback || 'iteration'
});
}
return collector.length !== 0;
}
case 'child':
if (matches(node, selector.right, ancestry, options)) {
return matches(ancestry[0], selector.left, ancestry.slice(1), options);
}
return false;
case 'descendant':
if (matches(node, selector.right, ancestry, options)) {
for (let i = 0, l = ancestry.length; i < l; ++i) {
if (matches(ancestry[i], selector.left, ancestry.slice(i + 1), options)) {
return true;
}
}
}
return false;
case 'attribute': {
const p = getPath(node, selector.name);
switch (selector.operator) {
case void 0:
return p != null;
case '=':
switch (selector.value.type) {
case 'regexp': return typeof p === 'string' && selector.value.value.test(p);
case 'literal': return `${selector.value.value}` === `${p}`;
case 'type': return selector.value.value === typeof p;
}
throw new Error(`Unknown selector value type: ${selector.value.type}`);
case '!=':
switch (selector.value.type) {
case 'regexp': return !selector.value.value.test(p);
case 'literal': return `${selector.value.value}` !== `${p}`;
case 'type': return selector.value.value !== typeof p;
}
throw new Error(`Unknown selector value type: ${selector.value.type}`);
case '<=': return p <= selector.value.value;
case '<': return p < selector.value.value;
case '>': return p > selector.value.value;
case '>=': return p >= selector.value.value;
}
throw new Error(`Unknown operator: ${selector.operator}`);
}
case 'sibling':
return matches(node, selector.right, ancestry, options) &&
sibling(node, selector.left, ancestry, LEFT_SIDE, options) ||
selector.left.subject &&
matches(node, selector.left, ancestry, options) &&
sibling(node, selector.right, ancestry, RIGHT_SIDE, options);
case 'adjacent':
return matches(node, selector.right, ancestry, options) &&
adjacent(node, selector.left, ancestry, LEFT_SIDE, options) ||
selector.right.subject &&
matches(node, selector.left, ancestry, options) &&
adjacent(node, selector.right, ancestry, RIGHT_SIDE, options);
case 'nth-child':
return matches(node, selector.right, ancestry, options) &&
nthChild(node, ancestry, function () {
return selector.index.value - 1;
}, options);
case 'nth-last-child':
return matches(node, selector.right, ancestry, options) &&
nthChild(node, ancestry, function (length) {
return length - selector.index.value;
}, options);
case 'class':
switch(selector.name.toLowerCase()){
case 'statement':
if(node.type.slice(-9) === 'Statement') return true;
// fallthrough: interface Declaration <: Statement { }
case 'declaration':
return node.type.slice(-11) === 'Declaration';
case 'pattern':
if(node.type.slice(-7) === 'Pattern') return true;
// fallthrough: interface Expression <: Node, Pattern { }
case 'expression':
return node.type.slice(-10) === 'Expression' ||
node.type.slice(-7) === 'Literal' ||
(
node.type === 'Identifier' &&
(ancestry.length === 0 || ancestry[0].type !== 'MetaProperty')
) ||
node.type === 'MetaProperty';
case 'function':
return node.type === 'FunctionDeclaration' ||
node.type === 'FunctionExpression' ||
node.type === 'ArrowFunctionExpression';
}
throw new Error(`Unknown class name: ${selector.name}`);
}
throw new Error(`Unknown selector type: ${selector.type}`);
}
Related
I want to debounce on all key presses excluding return. I have tried the following but it doesn't debounce.
some_stream.flatMap((event) => {
if(event.keyCode == 13){
return Kefir.stream(emitter => {
emitter.emit(event.target.value);
});
}else{
const debounced_stream = Kefir.stream(emitter => {
emitter.emit(event.target.value);
}).debounce(1000)
return debounced_stream;
}
})
I was able to solve this with the code block below which debounces on every keyCode except 13:
const search_stream = Kefir.fromEvents(self.search_keyword._tag.input, 'keyup');
const debounced_search_stream = search_stream
.filter((event) => {
return event.keyCode != 13;
})
.map((event) => {
return event.target.value;
})
.debounce(1000);
const not_debounced_search_stream = search_stream
.filter((event) => {
return event.keyCode == 13;
})
.map((event) => {
return event.target.value;
})
Kefir.merge([debounced_search_stream, not_debounced_search_stream]).onValue(keyword => {
if(keyword !== null){
if (keyword) {
//do something
}
}
})
I'm working with ActionScript3.0 on a basic movement engine. When I try to test my code, I get this error:
MovementClass.as, Line 44, Column 22 1084: Syntax error: expecting rightparen before colon.
I get this for lines 44, 52, 60, and 68 of the following code; these are the lines reading heroGoing<direction>(e:TimerEvent);
package {
import flash.display.*;
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
import flash.utils.Timer;
import flash.events.TimerEvent;
import flash.events.TimerEvent;
public class MovementClass extends MovieClip {
var reference:Reference = new Reference();
var hero:Hero = new Hero();
var enemy:Enemy = new Enemy();
var wall:Wall = new Wall();
//Timer
var moveTimer:Timer = new Timer(25, 10)
//Booleans
var movingHeroRight:Boolean = false;
var movingHeroLeft:Boolean = false;
var movingHeroUp:Boolean = false;
var movingHeroDown:Boolean = false;
public function MovementClass() {
hero.x = stage.stageWidth * .5;
hero.y = stage.stageHeight * .5;
addChild(hero);
startEngine();
}
public function startEngine():void {
stage.addEventListener(KeyboardEvent.KEY_DOWN, movementHandler);
stage.addEventListener(KeyboardEvent.KEY_UP, stopHandler);
}
public function movementHandler(keyDown:KeyboardEvent):void {
if (keyDown.keyCode == 39) {
if (movingHeroLeft == true, movingHeroUp == true, movingHeroDown == true) {
return;
} else {
heroGoingRight(e:TimerEvent);
movingHeroRight = true;
moveTimer.start;
}
} else if (keyDown.keyCode == 37) {
if (movingHeroRight == true, movingHeroUp == true, movingHeroDown == true) {
return;
} else {
heroGoingLeft(e:TimerEvent);
movingHeroLeft = true;
moveTimer.start;
}
} else if (keyDown.keyCode == 38) {
if (movingHeroLeft == true, movingHeroRight == true, movingHeroDown == true) {
return;
} else {
heroGoingUp(e:TimerEvent);
movingHeroUp = true;
moveTimer.start;
}
} else if (keyDown.keyCode == 40) {
if (movingHeroLeft == true, movingHeroUp == true, movingHeroRight == true) {
return;
} else {
heroGoingDown(e:TimerEvent);
movingHeroDown = true;
moveTimer.start;
}
}
//moveTimer.start();
}
function heroGoingUp(eUp:TimerEvent):void {
if (movingHeroUp == true) {
reference.y += 5;
}
}
function heroGoingDown(eDown:TimerEvent):void {
if (movingHeroDown == true) {
reference.y -= 5;
}
}
function heroGoingLeft(eLeft:TimerEvent):void {
if (movingHeroLeft == true) {
reference.x += 5;
}
}
function heroGoingRight(eRight:TimerEvent):void {
if (movingHeroRight == true) {
reference.x -= 5;
}
}
public function stopHandler(keyUp:KeyboardEvent):void {
if (movingHeroRight == true) {
movingHeroRight = false;
} else if (movingHeroLeft == true) {
movingHeroLeft = false;
} else if (movingHeroUp == true) {
movingHeroUp = false;
} else if (movingHeroDown == true) {
movingHeroDown = false;
}
}
}
}
What am I doing wrong?
The problem is with the first heroMoving call:
heroGoingRight(e:TimerEvent);
The compiler thinks you're trying to declare a variable in situ. Declare e:TimerEvent appropriately, before you use it, and you should be fine.
I got JqGrid with modified cellEdit ( full up-down-left-right cell navigation ).
Here is bits of jqgrid.src:
if (e.keyCode === 37) {
if(!$t.grid.hDiv.loading ) {
{$($t).jqGrid("prevCell",iRow,iCol);} //left
} else {
return false;
}
}
if (e.keyCode === 39) {
if(!$t.grid.hDiv.loading ) {
{$($t).jqGrid("nextCell",iRow,iCol);} //right
} else {
return false;
}
}
if (e.keyCode === 38) {
if(!$t.grid.hDiv.loading ) {
{$($t).jqGrid("prevRow",iRow,iCol);} //up
} else {
return false;
}
}
if (e.keyCode === 40) {
if(!$t.grid.hDiv.loading ) {
{$($t).jqGrid("nextRow",iRow,iCol);} //down
} else {
return false;
}
}
and others
nextCell : function (iRow,iCol) {
return this.each(function (){
var $t = this, nCol=false, i;
if (!$t.grid || $t.p.cellEdit !== true) {return;}
// try to find next editable cell
for (i=iCol+1; i<$t.p.colModel.length; i++) {
if ($t.p.colModel[i].editable ===true && $t.p.colModel[i].hidden !== true ) {
//alert($t.p.colModel[i-1].hidden);
nCol = i; break;
}
}
if(nCol !== false) {
$($t).jqGrid("editCell",iRow,nCol,true);
} else {
if ($t.p.savedRow.length >0) {
$($t).jqGrid("saveCell",iRow,iCol);
}
}
});
},
prevCell : function (iRow,iCol) {
return this.each(function (){
var $t = this, nCol=false, i;
if (!$t.grid || $t.p.cellEdit !== true) {return;}
// try to find next editable cell
for (i=iCol-1; i>=0; i--) {
if ($t.p.colModel[i].editable ===true && $t.p.colModel[i].hidden !== true ) {
nCol = i; break;
}
}
if(nCol !== false) {
$($t).jqGrid("editCell",iRow,nCol,true);
} else {
if ($t.p.savedRow.length >0) {
$($t).jqGrid("saveCell",iRow,iCol);
}
}
});
},
prevRow : function (iRow,iCol) {
return this.each(function (){
var $t = this, nCol=false, i;
if (!$t.grid || $t.p.cellEdit !== true) {return;}
// try to find next editable cell
iRow--;
iCol++;
for (i=iCol-1; i>=0; i--) {
if ( $t.p.colModel[i].editable ===true) {
nCol = i; break;
}
}
if(nCol !== false) {
$($t).jqGrid("editCell",iRow,nCol,true);
} else {
if ($t.p.savedRow.length >0) {
$($t).jqGrid("saveCell",iRow,iCol);
}
}
});
},
nextRow : function (iRow,iCol) {
return this.each(function (){
var $t = this, nCol=false, i;
if (!$t.grid || $t.p.cellEdit !== true) {return;}
// try to find next editable cell
iRow++;
iCol++;
for (i=iCol-1; i>=0; i--) {
if ( $t.p.colModel[i].editable ===true) {
nCol = i; break;
}
}
if(nCol !== false) {
$($t).jqGrid("editCell",iRow,nCol,true);
} else {
if ($t.p.savedRow.length >0) {
$($t).jqGrid("saveCell",iRow,iCol);
}
}
});
}
Also i got autocomplete working with JqGrid event afterEditCell:
getautocompl = function(rowid,cellname,value,iRow,iCol){
setTimeout(function() { $("#"+iRow+"_"+cellname).select().focus();},10);
if(cellname!=='date_factory' || cellname!=='date_otgr_factory' || cellname!=='date_shipment' || cellname!=='date_sklad' || cellname!=='kolinkor'
|| cellname!=='kolkor' || cellname!=='kol_quantity' || cellname!=='description') {
$("#"+iRow+"_"+cellname).autocomplete({
source:"../../phpmon/autocomplete.php?fname="+cellname,
delay:250,
minLength: 2});
}
}
Problem here is that i cant manage autocomplete hotkeys to work, when i hit "down" button it just goes to next cell, rather then to any of the autocomplete options.
you could suppress jqgrid navigation when autocomplete element is visible. something like:
$(document).keydown(function( fn ){
var key = fn.keyCode;
if( $("#autocomplete") && key == 40)
/* your autocomplete action*/
});
Its not quite what i needed, but it helped me to make it.
I just modified jqgrid source code like this :
if (e.keyCode === 40) {
if(!$t.grid.hDiv.loading ) {
if ($('.ui-menu-item').length < 1) {
{$($t).jqGrid("nextRow",iRow,iCol);} //down
}
} else {
return false;
}
}
Where .ui-menu-item is class of autocomplete widget.
thk a lot
I trying to update code from extjs2 to extjs4. But I have a some problem with load event in Ext.data.DataProxy.
Ext.define('App.data.DwrProxy', {
extend: 'Ext.data.DataProxy',
constructor: function(config){
App.data.DwrProxy.superclass.constructor.call(this);
this.invoker = config.invoker;
},
load: function(params, reader, callback, scope, arg) {
if (this.fireEvent("beforeload", this, params) !== false) {
if (!this.invoker) {
alert("'invoker' property is not specified");
return;
}
this.reader = reader;
this.callback = callback;
this.scope = scope;
this.arg = arg;
params.gridState = params.gridState || {};
if (params.sort != null)
params.gridState.sortField = params.sort;
if (params.dir == 'ASC')
params.gridState.descendingOrder = false;
if (params.dir == 'DESC')
params.gridState.descendingOrder = true;
if (params.start != null) {
params.gridState.pageNo = Math.floor(params.start / params.limit);
if (isNaN(params.gridState.pageNo))
params.gridState.pageNo = 0;
}
if (params.limit != null)
params.gridState.pageSize = params.limit;
this.invoker.call(
scope || this,
params,
arg,
{
callback: Ext.bind(this.success, this),
errorHandler: Ext.bind(this.failure, this)
}
);
} else {
callback.call(scope || this, null, arg, false);
}
}
});
As I know, Ext.data.DataProxy load event don't support in extjs4. So, how to use this function?
I used read instead and it worked for me.
I have asked a question like this before, and the answer was great but the more I looked at my code the more confused I got, and after 10hrs my brain is shot and I'm in need of help. So all my content is loaded dynamically via Jquery's $.post and loaded into #content-container. Now I included my entire Jquery file to show you why I am getting so confused as how to get this to work without re-writing all the code. As you can see, and what I'm thinking, is that the history plugins such as BBQ, and history.js seem to be out of the question because I don't use anchor tags and the multitude of .live('click', funcition() { I have use different classes and id's for various reasons. I also believe that rules out using the hash and linking it to a single class via .trigger(), executing the AJAX(hope that makes sense). The only option I have left is actually kinda my question. Would it be possible to load the dynamic content into #content-container still using the $.post with $.load() or window.location and actually have the previous content loaded when the browser back button is clicked.
I greatly appreciate the help, really.....
$(document).ready(function() {
$(window).load(function () {
});
$('#map').hide();
$('#informational-container').hide();
$('.clickable').click(function(){
$('#map').hide();
});
function getTotalDealCount() {
$.post('../service/service.getTotalDealCount.php', {}, function(data) {
if(data.success) $('#deal-counter').append(data.results);
}, 'json');
return false;
}
function loadMap(lat, lon) {
var latlng = new google.maps.LatLng(lat, lon);
var myOptions = {
zoom: 15,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById('map'), myOptions);
var marker = new google.maps.Marker({
position: latlng,
map: map
});
}
function getLatLon(address, zipcode) {
$.post('../service/service.getLatLon.php', { address: address, zipcode: zipcode }, function(data) {
if(data.success) {
var res = data.results;
var coordinates = res.split('_');
loadMap(coordinates[0], coordinates[1]);
} else {
return false;
}
}, 'json');
return false;
}
function getAddressZipcode(id) {
$.post('../service/service.getAddressZipcode.php', { id: id }, function(data) {
if(data.success) {
var res = data.results;
var location = res.split('_');
getLatLon(location[0], location[1]);
} else {
return -1;
}
}, 'json');
return false;
}
$('#how-it-works').live('click', function() {
$('#content-container').load('../module/module.string.php #string-m1');
});
$('#why-post-a-deal').live('click', function() {
$('#content-container').load('../module/module.string.php #string-m2');
});
$('#who-are-we').live('click', function() {
$('#content-container').load('../module/module.string.php #string-m3');
});
$('#contact-us').live('click', function() {
$('#content-container').load('../module/module.string.php #string-m4');
});
$('#post-deal-img').live('click', function() {
$('#content-container').load('post.php');
});
$('.post-deal-inputs').live('click', function() {
$('.post-deal-inputs').live('click', function(e) {
$(this).val('');
$(this).removeClass('post-deal-inputs')
.addClass('post-deal-inputs-clicked');
});
});
$('#df5').live('click', function() {
$('#df7').val('');
$('#df7').hide();
});
$('#df6').live('click', function() {
$('#df7').show();
});
$('#post-how-to-link').live('click', function() {
apprise();
});
$('#terms').live('click', function() {
$('#content-container').load('../module/module.string.php #string-m5');
});
$('#disclaimer').live('click', function() {
$('#content-container').load('../module/module.string.php #string-m6');
});
$('#post-deal-button').live('click', function() {
var dealForm = $('#deal-form').serialize();
var company = $('#df1').val();
var description = $('#df2').val();
var zipcode = $('#df4').val();
var starts = $('#df7').val();
var ends = $('#df8').val();
if(company == '' || company == 'Company') {
apprise('A company name is required!');
return false;
}
if(description == '' || description == 'Deal') {
apprise('A deal is required!');
return false;
}
var swear = swearFilter(description);
if(swear != false) {
apprise('Please remove the naughty word `' + swear + '` from your deal.');
return false;
}
if(zipcode == '' || zipcode == 'Zipcode') {
apprise('A zipcode is required!');
return false;
}
if($('#df7').is(':visible') && typeof(ends) != 'undefined') {
var res = validateDate(starts);
if(res == false) {
apprise('Please select a valid start date!');
return false;
}
}
if(typeof(ends) != 'undefined') {
var res = validateDate(ends);
if(res == false) {
apprise('Please select a valid end date!');
return false;
}
}
if(ends == '') {
apprise('A deal end date is required!');
return false;
}
if($('#df7').is(':visible') && $('#df7').val() == '') {
apprise('If its not a one day sale a start date is required!');
return false
}
$.post('../service/service.postDeal.php', { dealForm: dealForm }, function(data) {
if(data.success == true) {
apprise('Your deal has been posted, thank you!');
window.location = '../root/index.php';
return true;
}
if(data.success == false) {
if(data.fail == 1) {
apprise('An error has occured and your deal has not been posted. ' +
'The error has been emailed to our support department to have the issue fixed, we apologize :(');
return false;
}
if(data.fail == 2) {
apprise('The zipcode you supplied was not in our database. Please enter the city ' +
'and state/province in the following prompts to add your location.' , {'confirm':true}, function() {
insertNewLocation(zipcode);
});
}
if(data.fail == 3) {
apprise('A zipcode is required!');
}
}
}, 'json');
return false;
});
function validateDate(string) {
if(string.toLowerCase().indexOf('-') >= 0) {
var dateArray = string.split('-');
var year = dateArray[0], month = dateArray[1], day = dateArray[2];
if(year.length == 4 && month.length == 2 && day.length == 2) return true;
else return false;
}
return false;
}
function swearFilter(string) {
var ret = false;
var filter = [];
var stringArray = string.split(' ');
for(var i = 0; i < stringArray.length; i++) {
if(jQuery.inArray(stringArray[i], filter) > -1) {
ret = stringArray[i];
break;
}
}
return ret;
}
function insertNewLocation(zipcode) {
var city = '';
var state = '';
if (/[^a-zA-Z 0-9]+/g.test(zipcode)) {
apprise('The zipcode should contain only numbers, letters or both!');
return false;
}
apprise('Enter the name of the city:', {'input':true}, function(_city_) {
if(/[^a-zA-Z]+/g.test(_city_)) {
apprise('The city should contain only letters!');
return false;
}
city = _city_;
apprise('Enter the state in 2 letter abbreviated format:', {'input':true}, function(_state_) {
if (/[^a-zA-Z]+/g.test(_state_)) {
apprise('The state should contain only letters');
return false;
}
if(_state_.length > 2) {
apprise('The state should only be 2 letters in length');
}
state = _state_;
$.post('../service/service.insertNewLocation.php', { city: city, state: state, zipcode: zipcode }, function(data) {
if(data.success == true) {
apprise('Thank you, you may now submit you deal!');
return true;
}
if(data.success == false) {
if(data.fail == 1) {
apprise('An error has occured and your location has not been added to our database. ' +
'The error has been emailed to our support department to have the issue fixed, we apologize :(');
return false;
}
if(data.fail == 2) {
apprise('A zipcode is required!');
return false;
}
}
}, 'json');
return false;
});
});
}
$('#search-type-button').live('click', function() {
var search = $('#search-type-text').val();
var keyword = $('#keyword-type-text').val();
if(search == '') {
apprise('A zipcode or city and state combo to search for deals in your area!');
return false;
}
if(keyword == 'Keyword') {
apprise('If you want to add a keyword to you deal, make sure its unique!');
return false;
}
$.post('../service/service.loadDealsByCityOrZipcode.php', { search: search, keyword: keyword }, function(data) {
if(data.success) {
$('#content-container').html(data.results);
return true;
}
if(data.success == false) {
if(data.fail == 1) {
apprise('An error has occured locating the deals. ' +
'The error has been emailed to our support department to have the issue fixed, we apologize :(');
return false;
}
if(data.fail == 2) {
apprise('There are no deals within the zipcode you provided, be the first to add one!');
return false;
}
if(data.fail == 3) {
apprise('There are no deals matching the tag you supplied!');
return false;
}
if(data.fail == 4) {
apprise('A zipcode or city and state combo to search for deals in your area!');
return false;
}
}
}, 'json');
return false;
});
$('.deals-queried-deal').live('click', function() {
var id = this.id;
$('#comment-link').show();
$.post('../service/service.loadDealDescription.php', { id: id }, function(data) {
if(data.success == true) {
$('#content-container').html(data.results);
var res = getAddressZipcode(id);
if(res != -1) $('#map').show();
}
if(data.success == false) {
if(data.fail == 1) {
apprise('An error has occured loading the deal you selected. ' +
'The error has been emailed to our support department to have the issue fixed, we apologize :(');
} else if(data.fail == 2) {
apprise('The deal you selected does not exist! ' +
'The error has been emailed to our support department to have the issue fixed, we apologize :(');
} else if(data.fail == 3) {
apprise('An error has occured loading the deal you selected. ' +
'The error has been emailed to our support department to have the issue fixed, we apologize :(');
}
}
}, 'json');
return false;
});
$('.vote-down').live('click', function() {
var id = this.id;
var vote = 0;
$.post('../service/service.tallyVote.php', { id: id, vote: vote }, function(data) {
if(data.success == true) {
apprise('Thank you for your vote!');
return true;
}
if(data.success == false) {
if(data.fail == 1) {
apprise('An error has occured when voting for this deal. ' +
'The error has been emailed to our support department to have the issue fixed, we apologize :(');
return false;
}
if(data.fail == 2) {
apprise('You have already voted for this deal!');
return false;
}
}
}, 'json');
return false;
});
$('.vote-up').live('click', function() {
var id = this.id;
var vote = 1;
$.post('../service/service.tallyVote.php', { id: id, vote: vote }, function(data) {
if(data.success == true) {
apprise('Thank you for your vote!');
return true;
}
if(data.success == false) {
if(data.fail == 1) {
apprise('An error has occured when voting for this deal. ' +
'The error has been emailed to our support department to have the issue fixed, we apologize :(');
return false;
}
if(data.fail == 2) {
apprise('You have already voted for this deal!');
return false;
}
}
}, 'json');
return false;
});
$('#email-button').live('click', function() {
var emailAddress = $('.email-textbox').val();
var from = $('#from-textbox').val();
var message = $('#email-div').html();
var atpos = emailAddress.indexOf("#");
var dotpos = emailAddress.lastIndexOf(".");
if (atpos < 1 || dotpos < atpos + 2 || dotpos + 2 >= emailAddress.length) {
apprise('Please enter a valid email address!');
return false;
}
if(emailAddress == '') {
apprise('An email address is required!');
return false;
}
if(from == '') {
apprise('Your name is required!');
return false;
}
$.post('../service/service.emailDeal.php', { emailAddress: emailAddress, from: from, message: message}, function(data) {
if(data.success == true) {
apprise('The deal has been sent, we hope they enjoy it!');
return true;
}
if(data.success == false) {
if(data.fail == 1) {
apprise('An error has occured sending the email. ' +
'The error has been emailed to our support department to have the issue fixed, we apologize :(');
return false;
}
if(data.fail == 2) {
apprise('An email address is required!');
return false;
}
}
}, 'json');
return false;
});
$('.comment-link').live('click', function() {
var id = this.id;
$.post('../service/service.loadComments.php', { id: id }, function(data) {
if(data.success == true) {
$('#content-container').html(data.results);
return true;
}
if(data.success == false) {
apprise('An error has occured retrieving the comments for this deal. ' +
'The error has been emailed to our support department to have the issue fixed, we apologize :(');
return false;
}
}, 'json');
return false;
});
$('.post-comment-button').live('click', function() {
var id = this.id;
var comment = $('#comment-textarea').val();
var author = $('#post-comment-whois').val();
var swear = swearFilter(comment);
if(swear == true) {
apprise('Please remove the word "' + swear + '" from your comment.');
return false;
}
if(comment == '') {
apprise('Please fill out a comment first!');
return false;
}
$.post('../service/service.postComment.php', { id: id, comment: comment, author: author }, function(data) {
if(data.success == true) {
$.post('../service/service.loadComments.php', { id: id }, function(data) {
if(data.success == true) {
$('#content-container').html(data.results);
return true;
}
if(data.success == false) {
apprise('An error has occured retrieving the comments for this deal. ' +
'The error has been emailed to our support department to have the issue fixed, we apologize :(');
return false;
}
}, 'json');
return false;
}
if(data.success == false) {
if(data.fail == 1) {
apprise('An error has occured while attempting to post your comment. ' +
'The error has been emailed to our support department to have the issue fixed, we apologize :(');
return false;
}
if(data.fail == 2) {
apprise('Please fill out a comment first!');
return false;
}
}
}, 'json');
return false;
});
});`
Use history.js to pushState and then window.history.back()