I am creating a chrome javascript bookmarklet with reference to:
this question
My code:
javascript:(function NoOverrideAction(t){this.currentWindow=t,this.urlMatchPattern=/https:\/\/.*visual\.force\.com\/apex\/.*/,this.urlMatchPattern1=/https:\/\/.*visualforce\.com\/apex\/.*/,null!=this.currentWindow.location.toString().match(this.urlMatchPattern)||null!=this.currentWindow.location.toString().match(this.urlMatchPattern1)?this.isPageValid=!0:this.isPageValid=!1,this.recordId} NoOverrideAction.prototype={getId:function(){this.currentWindow.location.search.substr(1).split("&").forEach(function(t){var i=t.split("=");"id"==i[0]&&(this.recordId=i[1])},this)},run:function(){this.getId(),console.log(this),this.isPageValid&&void 0!==this.recordId&&(this.currentWindow.location.href="https://"+this.currentWindow.location.hostname+"/"+this.recordId+"?nooverride=1")}};var noAction=new NoOverrideAction(window);noAction.run();)();
However, I get following error:
Uncaught SyntaxError: Unexpected identifier
This works well in console but not as a bookmarklet.
I am trying to verify the URL of my current page and replace the URL
Part I.
Several reasons why js-code might work in console, but not work as a bookmarklet.
1 - You don't use the established way of making bookmarklets, i.e. IIFE-functions.
javascript:(function(){
alert('hi');
/*code here*/
})();
2 - If you do use this structure, there might be the problem with comments.
Use /*multi-line comment*/ instead of //single-line comment (because bookmarklet is a one-liner, so you cannot close your comment)
3 - Some problems with semicolons ;.
Don't confuse statements (need semicolon) and assignments (do not need them).
Console has its "automatic semicolon insertion", but it is a problem for a one-lined bookmarklet.
You should read a bit more here: https://stackoverflow.com/a/2717956/5410914
Part II
Since there is no HTML-code to test, it might be hard to check. Moreover, you could have made it easier to read by making it multi-lined (it will still work as a bookmarklet when you paste it as a bookmark). But anyway.
The main reason it might not work is that you don't use IIFE-format (Immediately Invoked Function Expression).
Your code has function NoOverrideAction(t) and, moreover, there is };var noAction=new NoOverrideAction(window);noAction.run();)(); at the end. It is not IIFE.
Read more: https://developer.mozilla.org/ru/docs/Glossary/IIFE
To debug a bookmarklet on your own, since there is no HTML provided, you might try to make your code simplier (even with alert('hi'); at first, and verify the reason it won't start) and then make it more complicated once you figure out that it works.
Related
Occasionally when I update some code in my controller and then check it in chrome it will throw a controller not registered error and also a syntax error. When I look at the chrome source files the controller in question will have a “?” prepended to it. It won’t go away with a hard reset either.
In the past to fix the error I have added ? marks to the beginning of it and then hard refreshed until the chrome source file updated. However today that did not work so I removed the IIFE the controller was wrapped in and hard refreshed and that worked. I actually think the IIFE isn’t useful for this controller because it’s used like below but I’m not 100% sure.
(function (){
angular.controller(“controllerName”, [“dependencies”,
function (dependencies) {
$scope.code = 1;
}])
)();
Sorry for the bad formatting I’m on my phone...
Thus never really touching the global scope, so I removed it from the IIFE and then updated and it finally worked without the ? mark prepend being present.
Thanks for any help or tips.
However, I’m wondering what can cause this error. We only use chrome so other browsers are not a problem if it is browser related.
The problem was because the code was being shared with people off shores. They were using a different character set than UTF-8 on their keyboard!
I'm learning v8 now, but I have encountered some problems.
How to set a breakpoint a method's start address in memory if I want to debug a method's C++ implementation.
e.g. var a= new Array(0,1); a.indexOf(1) ; I want to set a breakpoint at slice's beginning, or are there other ways to track the assembler code ?
There are a lot of functions will be complied and writed into a file named snapshot.bin. so I can't set a breakpoint at the beginning of these functions.
You need to check the source code and find the implementation of slice. Then set a gdb/lldb break point in that .cc file: byiltins-typedarray.cc
A lot of functions are defined as builtin or runtime functions.
It depends on the kind of function you want to inspect.
You can compile without snapshot to get around snapshot-related debugging difficulties (at the cost of making startup quite a bit slower: several seconds in Debug mode).
You can modify the respective code generator to emit a break instruction at the beginning of the function. For the example of Array.indexOf, that's probably the easiest solution; the CodeStubAssembler instruction is called DebugBreak().
You can break somewhere else using GDB, find your way to the function in question (e.g. via isolate->builtins), and set a breakpoint on the address of its entry. (This requires a bit of V8 knowledge and/or code reading skills, but it's not difficult.)
You can use various --print-*-code flags to print code to stdout (without breaking on it).
I'm working on a moderately-complex Bookmarklet that works just fine in Chrome, but I can't get it to work in Firefox. When I run my Bookmarklet in Firefox it redirects to a new page that only says true on it.
I've narrowed the cause down to a very specific thing: Firefox doesn't seem to like when you expose new functions to the global namespace.
If this is the case, might you know more about it? Is this documented anywhere, such that I can learn more about it? Resources on the nuances of bookmarklet-building seem scarce, and I can't find anything relevant. A second question would be if there are there any known workarounds.
And for some examples (remember, to test them simply copy these lines of code into a bookmarklet in Firefox. Then run them on any page).
Redirecting bookmarklets
javascript:!function(){window.okay={test:function(){}}}();
The project I'm working on
A Non-redirecting bookmarklet
javascript:!function(){window.okay={test:!0}}();
Any thoughts? Thanks!
For now, I plan to use manual subscriptions in Knockout to get the functionality I need. It'd still be nice to know the answer to this question, though.
It has nothing to do with exposing globals. It has everything to do with the final evaluated value of your bookmarklet.
Any JS code that is evaluated always returns a value which comes from the last line of code or the last block.
For me, in Firefox, both of your examples redirect because both return true. You can test this by pasting the code directly into Firefox console.
Furthermore...
javascript:!function(){...}();
This is weird. I've never seen this pattern.
This is the most common bookmarklet pattern these days:
javascript:(function(){...})();
As long as you don't end that anonymous function with a return, that pattern evaluates to undefined, and no redirect happens.
The older way of achieving the same result was to always use void(0); as the last line of code. That evaluates to undefined also, and if it is the last line, then the entire script evaluates to undefined, and no redirect happens.
I'm working on a bookmarklet which is using the replaceText plugin to wrap all words (and extraneous spaces/punctuation) on a page in span tags. That plugin traverses all the text nodes on a page and allows me to call a function to manipulate the contents of each one without breaking any other HTML formatting on the page. (None of this is the problem, I'm pretty sure, but I felt like the context might be useful). My call of the function looks like this, for your reference:
$("body *").replaceText(/\S+\s*/g, spanWrap);
The problem is that the best regular expression I've found for separating these words for my purposes -- /\S+\s*/g -- contains the characters for the end of a block comment ("*/"). If I add the opening of a block comment a few lines before it in the .js file in Notepad++, I can see that the syntax highlighter is reading it as that.
When I run my bookmarklet, most sites seem to have no problem with this issue and the bookmarklet works as intended. However, some sites, for reasons I can't predict, throw up an "Uncaught SyntaxError: Unexpected token <" error and the bookmarklet breaks/stops running. If I change the regular expression I'm using in the replaceText function to one I had been using in an earlier version of the bookmarklet -- /\b(\S+?)\b/g -- while changing absolutely nothing else in the bookmarklet, these sites stop giving the error and the bookmarklet works just fine, so I have to believe that it's the presence of the block comment closure that's causing it.
For the purposes of what I'm trying to do with the bookmarklet, though, the expression with that comment closure in it --/\S+\s*/g-- works much, much better than the other one, which doesn't catch punctuation and white space. However, I'd also really like it if my bookmarklet didn't break on certain sites.
So, is there either a way to fix the regular expression that I have so that it's not being read as a comment or can you suggest one that can do the same job maybe with a different syntax or something? (If it's not obvious from my question, I have the barest understanding of how regular expressions work and have gotten the ones I'm using in this example by copying them from other Stack Overflow questions/answers)
Use the long version:
var regex = new RegExp("\\S+\\s*", "g");
$("body *").replaceText(regex, spanWrap);
(EDIT: Escaped the backslashes in the string)
So, is there either a way to fix the regular expression that I have so that it's not being read as a comment
I can't think of anything sane. (You could get the effect by using the RegExp constructor and breaking the regex up into two strings and then concatenating them back together for the regex. I wouldn't call that sane though.)
I'd use a series of line comments // instead of a block comment.
I just spent half an one our to find out what caused the Error-Message "Ci is not defined" in my JavaScript code. I finally found the reason:
It should be (jQuery):
$("asd").bla();
It was:
("asd").bla();
(Dollar sign gone missing)
Now after having fixed the problem I'd like to understand the message itself: What does Firefox mean when it tells me that "Ci" is not defined. What's "Ci"?
Update:
I'm using the current version of Firefox (3.0.3).
To reproduce, just use this HTML code:
<html><head><title>test</title>
<script>
("asd").bla();
</script>
</head><body></body></html>
To make it clear: I know what caused the error message. I'd just like to know what Firefox tries to tell me with "Ci"...
I don't know which version of FF you are using, but regardless, the message is probably referring to the fact that bla() is not a function available on the String object. Since you were missing the $, which means you were missing a function, ("asd") would evaluate to a string, and then the JavaScript interpreter would try to call bla() on that object. So, if you had the following code in your project:
String.prototype.bla = function() {};
// now this next line will execute without any problems:
("asd").bla();
So, it is possible that Ci is some internal Firefox symbol that simply refers to the idea of a function. That is my guess, I imagine you are going to need someone that knows something about Firefox's internals to get a better answer to this question...
UPDATE: I am running your example code in the exact same version of FF as you are, but it reports the error as:
Error: "asd".bla is not a function
Source File: file:///C:/test.html
Line: 3
Perhaps you have an extension/plug-in running that does something with this? Maybe some Greasemonkey script or something?
Jason seems to be right. Many plugins (e.g. Firebug, Geode) use Ci as a shortcut:
const Ci = Components.interfaces;
So the plugins seem to cause that strange error message.
Assuming it's CodeIngiter, it can't find the js file.