Cannot delete post
-
I was trying to delete a post in a PM chain, so I can't link to the post affected, but for some reason, the delete button does nothing on my post.
Console has the following error:
Uncaught TypeError: Cannot read property 'apply' of undefined a @ VM672:579 r @ _vendor-cb7be21782ac642d67545fd3c9ee1618.js:27831 Discourse.View.extend.click @ _application-dfc130595a8812956ac015b5295fbeea.js:28669 i.default.extend.trigger @ _vendor-cb7be21782ac642d67545fd3c9ee1618.js:49032 r @ _vendor-cb7be21782ac642d67545fd3c9ee1618.js:27833 n.default.handleEvent @ _vendor-cb7be21782ac642d67545fd3c9ee1618.js:50077 m.default.extend.handleEvent @ _vendor-cb7be21782ac642d67545fd3c9ee1618.js:51630 s.run @ _vendor-cb7be21782ac642d67545fd3c9ee1618.js:10943 s.join @ _vendor-cb7be21782ac642d67545fd3c9ee1618.js:10966 l.join @ _vendor-cb7be21782ac642d67545fd3c9ee1618.js:26224 e.default.l.default.extend._bubbleEvent @ _vendor-cb7be21782ac642d67545fd3c9ee1618.js:46908 (anonymous function) @ _vendor-cb7be21782ac642d67545fd3c9ee1618.js:46860 J.event.dispatch @ _vendor-cb7be21782ac642d67545fd3c9ee1618.js:3365 g.handle @ _vendor-cb7be21782ac642d67545fd3c9ee1618.js:3365
-
Post to test outside PM chain
-
Can you delete it if you refresh first?
-
No; instead of doing nothing, now it flickers through deleted into not-deleted again, and my console says:
-
I don't get that particular issue; I do get the first one though
-
This post is deleted!
-
I can delete even before refreshing in this thread.
-
This post is deleted!
-
What @Yamikuronue said
-
I've talked about this before. It's the custom javascript we have for /t/1000 for deletes:
//prevent delete of posts in the 1000 thread $("document").ready( function(){( function(){ var b=Discourse.PostMenuView.prototype.clickDelete, a=function(a){ if(1E3==a.topic_id) return $("#discourse-modal #modal-alert") .html("<img style='padding:10px;' src='/uploads/default/8214/16c00f5bd6b57125.png'/>Press <kbd>ctrl + w</kbd> to delete anyway?"), $("#discourse-modal h3") .html("Please do not delete posts from the 1000 thread. Edit your post, or flag it for moderator attention to hide content. Thanks"), $("#discourse-modal").modal("show"),!1; b.apply(this,arguments) }; Discourse.PostMenuView.reopen({clickDelete:a}); Discourse.PostMenuView.prototype.clickDelete=a})() } );
It was in one place before, and this happened all the time (no delete before refresh). Then @riking suggested moving it to the
</body>
customization area, where discoinitialization should have already happened. That worked for like one beta cycle and we're back to where we were.I'm not sure where to go from here.
-
b.apply is only being called if it matches the right topic id, but my PM can't be t/1000 by virtue of it not being t/1000..... so clearly that check isn't quite right.
or I'm blind and it's a.apply() that's being called. fasting is a barrier to reading comprehension.
-
Yeah...I dunno. I didn't write the code, I just moved it around.
-
not sure if this will help, but i removed an unnecessary SEF, reduced the call to jquery.ready and unobfuscated what's happening in the case of /t/1k (the use of the comma operator is always a barrier to comprehension of code, more so when it's used because someone didn't add curly braces.
.... i don't think it fixes the issue but it stops my tail twitching looking at the code
//prevent delete of posts in the 1000 thread $(function() { var b = Discourse.PostMenuView.prototype.clickDelete, a = function(a) { if (1e3 == a.topic_id) { $("#discourse-modal #modal-alert").html("<img style='padding:10px;' src='/uploads/default/8214/16c00f5bd6b57125.png'/>Press <kbd>ctrl + w</kbd> to delete anyway?"); $("#discourse-modal h3").html("Please do not delete posts from the 1000 thread. Edit your post, or flag it for moderator attention to hide content. Thanks"); $("#discourse-modal").modal("show"); return false; } b.apply(this, arguments); }; Discourse.PostMenuView.reopen({ clickDelete: a }); Discourse.PostMenuView.prototype.clickDelete = a; });
-
-
reduced the call to jquery.ready
So now it runs directly? This seems counter productive, as the problem seems to be that it was running before Discourse got initialized or whatever.
-
Self Executing Function.
a function of the form
(function(){})()
evaluates to an anonymous function that executes itself.which is awesome but when it's of the form:
function(){(function(){})()}
the SEF is redundant so it might as well be justfunction(){}
-
So now it runs directly?
no, not that.
instead of calling
$("document").ready(fn)
it calls$(fn)
which has the same effect (in fact if you pull apart jquery you see it does exaclty the same thing as the first form.)
-
It should run directly,
Discourse.start()
was already called in</body>
. don't wait around for the ready event!</head>
- after JS bundles, before Discourse starts up and first paint</body>
- after Discourse.start(), after initializers, still first runloop so we're not painted yetdocument.ready
- ?????????
Actually, you want it unwrapped, in head.
-
Actually, you want it unwrapped, in head.
I'm not sure what this means with respect to the code I'm looking at. It looks like there are several layers there to my n00b js eyes. What should I be pasting into the text box?
-
I'd want @riking to confirm, but if i understand him right this script goes in head:
var b = Discourse.PostMenuView.prototype.clickDelete, a = function(a) { if (1e3 == a.topic_id) { $("#discourse-modal #modal-alert").html("<img style='padding:10px;' src='/uploads/default/8214/16c00f5bd6b57125.png'/>Press <kbd>ctrl + w</kbd> to delete anyway?"); $("#discourse-modal h3").html("Please do not delete posts from the 1000 thread. Edit your post, or flag it for moderator attention to hide content. Thanks"); $("#discourse-modal").modal("show"); return false; } b.apply(this, arguments); }; Discourse.PostMenuView.reopen({ clickDelete: a }); Discourse.PostMenuView.prototype.clickDelete = a;
-
Or, you know, we could pretend debugging is more valuable than a few bytes per request
var origFunc = Discourse.PostMenuView.prototype.clickDelete, wrapper = function(a) { if (1e3 == a.topic_id) { $("#discourse-modal #modal-alert").html("<img style='padding:10px;' src='/uploads/default/8214/16c00f5bd6b57125.png'/>Press <kbd>ctrl + w</kbd> to delete anyway?"); $("#discourse-modal h3").html("Please do not delete posts from the 1000 thread. Edit your post, or flag it for moderator attention to hide content. Thanks"); $("#discourse-modal").modal("show"); return false; } origFunc.apply(this, arguments); }; Discourse.PostMenuView.reopen({ clickDelete: wrapper }); Discourse.PostMenuView.prototype.clickDelete = wrapper;
-
Or, you know, we could pretend debugging is more valuable than a few bytes per request
a valid point, but take that up with the original creator of that JS. i've just been manipulating it into different forms this whole time.
;-)
-
Trying this now...
-
Nope...that gives the error even after a refresh. Reverted...
-
Whelp....digging in, I'm not seeing
clickDelete
onDiscourse.PostViewMenu.prototype
. So that won't work at all any more.
-
It's been renamed slightly:
Discourse.PostMenuView.prototype.clickDelete
-
Hooray for stable APIs
-
Ah, yes. Fuck.
-
inb4 this isn't an api
-
OK, I think it's fixed now.
-
I haven't been able to delete posts for a long time now.
But the last post I wanted to delete, @boomzilla said, nope.
-
If I said it I meant it. Possibly.
-
This post is deleted!
-
if this is here then it's broken
-
Test
Nope, still broken...
-
Fuck you discourse. I guess we need to do the unwrapping thing after all...too late tonight...maybe I'll test it tomorrow. Not on /t/1000.
-
not... COMPLETELY broken.... somehow....
-
getting race issues or something, dischorse's favorite.
why can't we just let dischorse choose its race and be who it wants to be?
-
ok, so if you load the main article list and then navigate and try to delete, you get the error.
if at any point you loaded a topic from scratch, the error doesn't happen.
hmm. the msg for 1k shows up for me though. it's only broken on non t/1k topics
because origFunc/b is somehow undefined still in that block, maybe delete function not exist on main topic list when it first sets it?
-
not... COMPLETELY broken.... somehow....
Yeah. I really did test it before and couldn't get it to break. I started playing with
setTimeout
to wait until the thing was initialized, but that was before I noticed that they changed the name of the fucking object.
-
Here's what I came up with. It seems to work:
<script> // prevent deletes in /t/1000 function init(){ var b=Discourse.PostMenuView.prototype.clickDelete; if( !b ){ setTimeout( 100, init ); return; } var a=function(a){ if(1E3==a.topic_id){ return $("#discourse-modal #modal-alert").html("<img style='padding:10px;' src='/uploads/default/8214/16c00f5bd6b57125.png'/>Press <kbd>ctrl + w</kbd> to delete anyway?"), $("#discourse-modal h3").html("Please do not delete posts from the 1000 thread. Edit your post, or flag it for moderator attention to hide content. Thanks"), $("#discourse-modal").modal("show"),!1; } Discourse.PostMenuView.prototype.clickDelete.apply( this, arguments ); }; Discourse.PostMenuView.reopen({clickDelete:a}); Discourse.PostMenuView.prototype.clickDelete=a; } init(); </script>
-
Close enough. But just in case, rename it to PreventT1000Deletes()
-
Yeah, that makes sense. But it looks like as of Beta 3, the clickDelete function doesn't get called.
-
OK, here's what I came up with that works now:
<script> // prevent deletes in /t/1000 function preventT1000Deletes(){ var b=Discourse.PostMenuView.prototype.clickDelete; if( !b ){ var id = setTimeout( preventT1000Deletes, 1000 ); return; } var a=function(a){ if(1E3==a.topic_id){ return $("#discourse-modal #modal-alert").html("<img style='padding:10px;' src='/uploads/default/8214/16c00f5bd6b57125.png'/>Press <kbd>ctrl + w</kbd> to delete anyway?"), $("#discourse-modal h3").html("Please do not delete posts from the 1000 thread. Edit your post, or flag it for moderator attention to hide content. Thanks"), $("#discourse-modal").modal("show"),!1; } b.apply( this, arguments ); }; Discourse.PostMenuView.reopen({clickDelete:a}); Discourse.PostMenuView.prototype.clickDelete=a; } setTimeout( preventT1000Deletes, 200 ); </script>
Basically, there's no PostMenuView.clickDelete until you go to a topic. So it tries back every second to see if it's there yet. That smells a bit, but is the easiest way I can think of.
-
Hmmm... might be a better way, shouldn't really add much overhead... I'll take a look at it later when I get home.
-
Hmm, what happens if you do this?
<script> // prevent deletes in /t/1000 (function() { var PostMenuView = Discourse.__container__.lookup("view:post-menu") PostMenuView.reopen(function(p) { if (1E3 == p.topic_id) { return $("#discourse-modal #modal-alert").html("<img style='padding:10px;' src='/uploads/default/8214/16c00f5bd6b57125.png'/>Press <kbd>ctrl + w</kbd> to delete anyway?"), $("#discourse-modal h3").html("Please do not delete posts from the 1000 thread. Edit your post, or flag it for moderator attention to hide content. Thanks"), $("#discourse-modal").modal("show"),!1; } else this._super(p); }); })(); </script>
-
Not sure you need to be preventing deletes on t1000 anymore, was working fine on a local copy.
-
It's more a discouragement thing, because people go for special numbers, and deleting posts messes that up
-
yeah we wouldnt prevent deletes just because it makes dischorse break.
we'd encourage it.
-
What happens if someone goes into t/1000 and deletes a post within the first second?
It won't be me since I have to go through MilwaukeePC and Discourse to get to the topic, and I'm lucky if it finishes loading before I finish lunch.