How Do I Convert Bookmarklet to KM Execute JavaScript?

I am trying to convert this bookmarklet to work from ‘run javascript’ in KM but it doesn’t seem to work.

I tried the original full bookmarklet and then also trimmed javascript: from it. It’s already a javascript snippet so I thought it would work. :frowning:

Not sure what I can do. Thank you for any help.

@nikivi, I moved your post to a new topic, since it is a new subject.

Please provide the macro you are working on, and the JavaScript you want to use. Also need an example URL of a web page where you want to use the JavaScript.

Keyboard Maestro “safari: go to initial commit” Macro

safari- go to initial commit.kmmacros (25 KB)

Is the github page for example : https://github.com/nikitavoloboev/learn-anything

That is not JavaScript code, it is a javascript: URL.

Decode the URL into JavaScript (this one should probably do - remove the “javascript:” from the front).

1 Like

Thank you a lot Peter. I bookmarked it. :slight_smile:

1 Like

Hi Peter, I think I'm in the same boat.

Here's the Javascript: URL

javascript:(function()%7Bfunction%20t(t)%7Bfunction%20e(t,e)%7Be=e%7C%7Cd,d.innerHTML=%22%22,e.appendChild(document.createTextNode(t))%7Dfunction%20i(t)%7Breturn%22%22+EmailThis.urlRoot+%22?token=%22+EmailThis.token+%22&url=%22+encodeURIComponent(window.location.href)+%22&title=%22+encodeURIComponent(window.document.title)+(t===!0?%22&format=full%22:%22%22)%7Dfunction%20n()%7Bvar%20t=document.createElement(%22img%22);t.setAttribute(%22id%22,%22emailthis-img%22),t.setAttribute(%22src%22,i()),t.style.display=%22none%22,d&&e(%22Saving...%22),a.appendChild(t);var%20n=setTimeout(function()%7Bvar%20t=document.createElement(%22p%22),n=document.createElement(%22a%22);e(%22Page%20could%20not%20be%20autosaved%20due%20to%20an%20error.%22,t),n.setAttribute(%22href%22,i(!0)),n.setAttribute(%22target%22,%22_blank%22),n.setAttribute(%22style%22,%22display:block;margin:10px%200;padding:0;color:white;text-decoration:underline;font-size:16px;font-weight:bold;font-family:sans-serif;text-align:center%22),e(%22Click%20here%20to%20save.%22,n),t.appendChild(n),d.appendChild(t)%7D,2e3);t.onload=function()%7Be(%22Saved!%22),setTimeout(function()%7Bd&&d.parentNode&&d.parentNode.removeChild(d)%7D,1500),clearTimeout(n)%7D,EmailThis.saved=!0%7Dvar%20o=document.createElement(%22script%22);o.setAttribute(%22type%22,%22text/javascript%22),o.setAttribute(%22charset%22,%22UTF-8%22),o.setAttribute(%22crossorigin%22,%22anonymous%22),o.setAttribute(%22src%22,t),o.onerror=function()%7BEmailThis.timedOut=!1,n()%7D,o.onload=function()%7BEmailThis.timedOut=!1;var%20t=o.readyState;t&&%22loaded%22!==t&&%22complete%22!==t%7C%7C(o.onload=o.onreadystatechange=null,EmailThis.init?EmailThis.init():n())%7D;var%20a=document.body%7C%7Cdocument.documentElement;a.appendChild(o);var%20d=document.createElement(%22div%22);d.setAttribute(%22style%22,%22position:fixed;z-index:16777270;top:0;margin:0;padding:10px;left:50%25;margin-left:-100px;width:200px;min-height:30px;line-height:1;background:black;color:white;font-size:16px;font-weight:bold;font-family:sans-serif;text-align:center;%22),e(%22Loading...%22),d.setAttribute(%22id%22,%22emailthis-script-loading-popup%22),a.appendChild(d),setTimeout(function()%7BEmailThis.timedOut===!0&&n()%7D,4e3)%7Dwindow.EmailThis?EmailThis.init():(window.EmailThis=%7BurlRoot:%22https://www.emailthis.me/api/save%22,token:%2242d4283b-f749-4498-ad15-a0425b930c24%22,timedOut:!0,saved:!1%7D,t(%22//external.emailthis.me/main.js%22))%7D)();

and here's the decoded version less the "javascript:"

(function(){function t(t){function e(t,e){e=e||d,d.innerHTML="",e.appendChild(document.createTextNode(t))}function i(t){return"" EmailThis.urlRoot "?token=" EmailThis.token "&url=" encodeURIComponent(window.location.href) "&title=" encodeURIComponent(window.document.title) (t===!0?"&format=full":"")}function n(){var t=document.createElement("img");t.setAttribute("id","emailthis-img"),t.setAttribute("src",i()),t.style.display="none",d&&e("Saving..."),a.appendChild(t);var n=setTimeout(function(){var t=document.createElement("p"),n=document.createElement("a");e("Page could not be autosaved due to an error.",t),n.setAttribute("href",i(!0)),n.setAttribute("target","_blank"),n.setAttribute("style","display:block;margin:10px 0;padding:0;color:white;text-decoration:underline;font-size:16px;font-weight:bold;font-family:sans-serif;text-align:center"),e("Click here to save.",n),t.appendChild(n),d.appendChild(t)},2e3);t.onload=function(){e("Saved!"),setTimeout(function(){d&&d.parentNode&&d.parentNode.removeChild(d)},1500),clearTimeout(n)},EmailThis.saved=!0}var o=document.createElement("script");o.setAttribute("type","text/javascript"),o.setAttribute("charset","UTF-8"),o.setAttribute("crossorigin","anonymous"),o.setAttribute("src",t),o.onerror=function(){EmailThis.timedOut=!1,n()},o.onload=function(){EmailThis.timedOut=!1;var t=o.readyState;t&&"loaded"!==t&&"complete"!==t||(o.onload=o.onreadystatechange=null,EmailThis.init?EmailThis.init():n())};var a=document.body||document.documentElement;a.appendChild(o);var d=document.createElement("div");d.setAttribute("style","position:fixed;z-index:16777270;top:0;margin:0;padding:10px;left:50%;margin-left:-100px;width:200px;min-height:30px;line-height:1;background:black;color:white;font-size:16px;font-weight:bold;font-family:sans-serif;text-align:center;"),e("Loading..."),d.setAttribute("id","emailthis-script-loading-popup"),a.appendChild(d),setTimeout(function(){EmailThis.timedOut===!0&&n()},4e3)}window.EmailThis?EmailThis.init():(window.EmailThis={urlRoot:"https://www.emailthis.me/api/save",token:"42d4283b-f749-4498-ad15-a0425b930c24",timedOut:!0,saved:!1},t("//external.emailthis.me/main.js"))})();

Pasted into an Execute JavaScript in Front Browser action

Doesn't work. It's a bookmarklet to send a webpage to the EmailThis service to get back the text from the page as an email (https://www.emailthis.me.)

Any help would be appreciated.

What happens if you open the console in Safari and then paste your javascript function in, does that work or does it give an error?

IF this is what you're asking, here's the output:

Yes, but you need to paste in the JavaScript function, not the javascript: URL.

Ok, returned this:

[Error] Unrecognized Content-Security-Policy directive 'worker-src'.

(This first error was there when I opened the js panel and before I pasted in the js function at https://www.google.com so the SyntaxError at the bottom seems to be the problem.)

 (function() {
   function t(t) {
     function e(t, e) {
       e = e || d, d.innerHTML = "", e.appendChild(document.createTextNode(
         t))
     }

     function i(t) {
       return ""
       EmailThis.urlRoot "?token="
       EmailThis.token "&url="
       encodeURIComponent(window.location.href)
       "&title="
       encodeURIComponent(window.document.title)(t === !0 ?
         "&format=full" :
         "")
     }

     function n() {
       var t = document.createElement("img");
       t.setAttribute("id", "emailthis-img"), t.setAttribute("src",
           i()), t.style
         .display = "none", d && e("Saving..."), a.appendChild(t);
       var n = setTimeout(function() {
         var t = document.createElement("p"),
           n = document.createElement("a");
         e("Page could not be autosaved due to an error.", t),
           n.setAttribute(
             "href", i(!0)), n.setAttribute("target", "_blank"),
           n.setAttribute(
             "style",
             "display:block;margin:10px 0;padding:0;color:white;text-decoration:underline;font-size:16px;font-weight:bold;font-family:sans-serif;text-align:center"
           ), e("Click here to save.", n), t.appendChild(n), d.appendChild(
             t)
       }, 2e3);
       t.onload = function() {
         e("Saved!"), setTimeout(function() {
           d && d.parentNode && d.parentNode.removeChild(d)
         }, 1500), clearTimeout(n)
       }, EmailThis.saved = !0
     }
     var o = document.createElement("script");
     o.setAttribute("type", "text/javascript"), o.setAttribute(
       "charset",
       "UTF-8"), o.setAttribute("crossorigin", "anonymous"), o.setAttribute(
       "src", t), o.onerror = function() {
       EmailThis.timedOut = !1, n()
     }, o.onload = function() {
       EmailThis.timedOut = !1;
       var t = o.readyState;
       t && "loaded" !== t && "complete" !== t || (o.onload = o.onreadystatechange =
         null, EmailThis.init ? EmailThis.init() : n())
     };
     var a = document.body || document.documentElement;
     a.appendChild(o);
     var d = document.createElement("div");
     d.setAttribute("style",
         "position:fixed;z-index:16777270;top:0;margin:0;padding:10px;left:50%;margin-left:-100px;width:200px;min-height:30px;line-height:1;background:black;color:white;font-size:16px;font-weight:bold;font-family:sans-serif;text-align:center;"
       ), e("Loading..."), d.setAttribute("id",
         "emailthis-script-loading-popup"), a.appendChild(d),
       setTimeout(
         function() {
           EmailThis.timedOut === !0 && n()
         }, 4e3)
   }
   window.EmailThis ? EmailThis.init() : (window.EmailThis = {
     urlRoot: "https://www.emailthis.me/api/save",
     token: "42d4283b-f749-4498-ad15-a0425b930c24",
     timedOut: !0,
     saved: !1
   }, t("//external.emailthis.me/main.js"))
 })();

 SyntaxError: Unexpected identifier 'EmailThis'.Expected a ';'
 following a
 return statement.
 evaluateWithScopeExtension
 _evaluateOn
 _evaluateAndWrap

I see that "return statements cease execution in a function and return a value to the caller." I do not know how to identify the caller in this script.

BTW, does the yellow highlighting indicate the Console's indicating the error it found?

No. That was due to you NOT posting the script properly.
All scripts should be posted using Code Block.
And in your case most of the code was on one or two lines.
I "beautified" it to make it more readable at this web site:
http://jsbeautifier.org/

Please use both in the future.

For these type questions, which really have nothing to do with KM, you are best off posting at stackoverflow.com, where there are many, many JavaScript experts ready to help.

Wow, aren't I the bull in the china shop!? Thanks @JMichaelTX for being generously gentle while I crash around breaking things as I learn. I certainly will use both going forward. As has been said, this forum is full of good generous people staying true to the intent of the forum. It's really a model that we'd all be better off for if carried behind the confines of this virtual space.

Thanks again and my hat off to you! You are a true gentleman.

And I will go over to stackoverflow.com to follow this up.

1 Like

Yep, I'm afraid you need to get the script working in Safari first, and then Keyboard Maestro can execute it.

It looks like an error with the JavaScript - does the bookmarklet work normally in Safari?

I'm afraid the issue is a bit beyon my JavaScript skills (maybe @ComplexPoint has an idea? Although it looks to be more a DOM issue of how to access or initialize the EmailThis function).

Good luck - when you get an answer on StackOverflow for what is wrong with the script, post it here too.

Thanks.

I was unable to clarify the issue in response to a request for how it fails and abandoned the request at StackOverflow. I've since found that Safari auto assigns a shortcut to the first several bookmarks and have used a "type keystroke" action with the bookmarklet's Safari assigned keystroke to get the macro to work.