The Wiert Corner – irregular stream of stuff

Jeroen W. Pluimers on .NET, C#, Delphi, databases, and personal interests

  • My badges

  • Twitter Updates

  • My Flickr Stream

  • Pages

  • All categories

  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 1,860 other subscribers

JavaScript Bookmarklet to enable Mastodon publishing for a WordPress.com post that is edited in the Classic Editor

Posted by jpluimers on 2023/07/02

I quickly hacked together this JavaScript Bookmarklet today, so it is without any checks and assumes you have enabled one Mastodon account for publishing, that you are hosting your blog on WordPress.com, and using the Classic Editor:

javascript:(function(){
  publicizeFormEditHref = document.getElementById('publicize-form-edit');
  publicizeFormEditHref.click();
  mastodonCheckboxes = document.getElementsByClassName('wpas-submit-mastodon');
  mastodonCheckboxes[0].checked = true;
  publicizeFormHideHref = document.getElementById('publicize-form-hide');
  publicizeFormHideHref.click();
  updateButtonHref = document.getElementById('publish');
  updateButtonHref.click();
})();

The above code is the state of [Wayback/Archive] JavaScript Bookmarklet for the WordPress classic editor which enables mastodon publishing (assuming you have one mastodon publishing account enabled … )  and due to be improved in a later blog post.

This will enable the currently edited post to be published to Mastodon, then update/publish the post.

On enabling one Mastodon account for publishing:

On my blog, I could enable Mastodon publishing by following either of these links on my WordPress.com blog (I found 5. and 6. manually; they will eventually redirect to 3.):

  1. jetpack.com/redirect/?source=jetpack-social-connections-classic-editor&site=wiert.me
  2. jetpack.com/redirect/?source=jetpack-social-connections-classic-editor
  3. wordpress.com/marketing/connections/wiert.me
  4. wordpress.com/marketing/connections/
  5. jetpack.com/redirect/?source=jetpack-social-connections-classic-editor&site=wiert.wordpress.com
  6. wordpress.com/marketing/connections/wiert.wordpress.com

If you have multiple blogs, then likely 2. and 4. are not enough and you will need to use specific domain names.

If your blog runs on a different domain not hosted by WordPress.com, then likekly you need to alter the domain names above.

If you have more than one Mastodon account configured then you will need to create a loop walking the array. I might implement that at a later stage.

Now is also a good time to check which sharing buttons you have enabled for your blog entries and add Mastodon to them.

For that I had to follow wordpress.com/marketing/sharing-buttons/wiert.me.

Code

The code currently is very straightforward and has no checks. This means that if an element being searched for does not exist, errors will occur.

In the future I will try to improve the code.

Via

[Wayback/Archive] Jeroen Wiert Pluimers: “@rulesbyrosita ik ben nog wat verder gegaan en een Bookmarklet gemaakt.Check gaarne of dit bij je werkt; ik wil nog kijken of ik over het resultaat van getElementsByClassName kan loopen.” – Mastodon

[Wayback/Archive] JavaScript Bookmarklet for the WordPress classic editor which enables mastodon publishing (assuming you have one mastodon publishing account enabled under https://jetpack.com/redirect/?source=jetpack-social-connections-classic-editor / https://wordpress.com/marketing/connections/)

References

More references will follow as I update this post to loop over the 'wpas-submit-mastodon' entries and try to keep the published/pending review/draft/schedules status into account.

  • [Wayback/Archive] Document: getElementsByClassName() method – Web APIs | MDN

    The getElementsByClassName method of Document interface returns an array-like object of all child elements which have all of the given class name(s).

    When called on the document object, the complete document is searched, including the root node. You may also call getElementsByClassName() on any element; it will return only elements which are descendants of the specified root element with the given class name(s).

    Parameters

    names
    A string representing the class name(s) to match; multiple class names are separated by whitespace.

    Return value

    A live HTMLCollection of found elements.

  • [Wayback/Archive] Why Twitter Auto-Sharing Is Coming to an End – WordPress.com News

    For WordPress.com and [Wayback/Archive] Jetpack users, Twitter will no longer be part of Jetpack Social. However, we’re adding Instagram and Mastodon very soon. In the meantime, auto-sharing to Tumblr, Facebook, and LinkedIn still works as expected, and you can continue sharing your blog post links on Twitter manually through their app or desktop site.

  • My future blog post (mid September 2023): XPath based bookmarklets for Archive.is: more JavaScript fiddling!
  • My blog post Some JavaScript bookmarklets for WordPress published pages centered around navigation and IDs.
  • [Wayback/Archive] Document: querySelectorAll() method – Web APIs | MDN

    The Document method querySelectorAll() returns a static (not live) NodeList representing a list of the document’s elements that match the specified group of selectors.

    Parameters

    selectors
    A string containing one or more selectors to match against. This string must be a valid CSS selector string; if it’s not, a SyntaxError exception is thrown. See Locating DOM elements using selectors for more information about using selectors to identify elements. Multiple selectors may be specified by separating them using commas.

    Return value

    A non-live NodeList containing one Element object for each element that matches at least one of the specified selectors or an empty NodeList in case of no matches.

    Once the NodeList of matching elements is returned, you can examine it just like any array. If the array is empty (that is, its length property is 0), then no matches were found.

    Otherwise, you can use standard array notation to access the contents of the list. You can use any common looping statement, such as:

    const highlightedItems = userList.querySelectorAll(".highlighted");
    
    highlightedItems.forEach((userItem) => {
      deleteUser(userItem);
    });

  • [Wayback/Archive] javascript – Iterating over result of getElementsByClassName using Array.forEach – Stack Overflow (thanks [Wayback/Archive] Steve Claridge, [Wayback/Archive] briosheje, [Wayback/Archive] Tim Down, and [Wayback/Archive] isherwood):

    Q

    I want to iterate over some DOM elements, I’m doing this:
    document.getElementsByClassName( "myclass" ).forEach( function(element, index, array) {
      //do stuff
    });
    
    but I get an error:
    document.getElementsByClassName(“myclass”).forEach is not a function

    A

    If you’re in the happy position of being able to use ES6 (i.e. you can safely ignore Internet Explorer or you’re using an ES5 transpiler), you can use Array.from:
    Array.from(els).forEach((el) => {
        // Do stuff here
        console.log(el.tagName);
    });
    
  • [Wayback/Archive] javascript – Is if(document.getElementById(‘something’)!=null) identical to if(document.getElementById(‘something’))? – Stack Overflow (thanks [Wayback/Archive] Malik Daud Ahmad Khokhar and [Wayback/Archive] Pointy)

    Q

    When I want to check if an element exists in a page. Are these two checks the same? Is there a better more compact way to check the existence?
    What if I want to check if the value == ''. Can this be included in this check as well?

    A

    what getElementById returns will either be an element reference, or null. Thus if the element is in the DOM, the return value will be an object reference, and all object references are true in an if () test. If the element is not in the DOM, the return value would be null, and null is always false in an if () test.

  • [Wayback/Archive] javascript – How to loop through selected elements with document.querySelectorAll – Stack Overflow (thanks [Wayback/Archive] Hadi Mostafapour, [Wayback/Archive] aboutaaron and [Wayback/Archive] clem):

    Q

    I am trying loop on selected elements that queried with document.querySelectorAll, but how?
    For example I use:
    var checkboxes = document.querySelectorAll('.check');
    for( i in checkboxes) {
      console.log(checkboxes[i]);
    }
    
    Output:
    <input id="check-1" class="check" type="checkbox" name="check">
    <input id="check-2" class="check" type="checkbox" name="check">
    <input id="check-3" class="check" type="checkbox" name="check">
    <input id="check-4" class="check" type="checkbox" name="check">
    <input id="check-5" class="check" type="checkbox" name="check">
    <input id="check-6" class="check" type="checkbox" name="check">
    <input id="check-7" class="check" type="checkbox" name="check">
    <input id="check-8" class="check" type="checkbox" name="check">
    <input id="check-9" class="check" type="checkbox" name="check">
    <input id="check-10" class="check" type="checkbox" name="check" checked="">
    
    10
    item()
    namedItem()
    
    My problem is that at the end this method returns 3 extra items. How can I properly do it?

    A

    It looks like Firefox 50+, Chrome 51+ and Safari 10+ now all support the .forEach function for NodeList objects. Note—.forEach is not supported in Internet Explorer, so consider one of the approaches above or use a polyfill if IE support is required.
    const paragraphs = document.querySelectorAll('p');
    paragraphs.forEach(p => console.log(p));
    <p>paragraph 1</p>
    <p>paragraph 2</p>
    <p>paragraph 3</p>
    <p>paragraph 4</p>
    <p>paragraph 5</p>

  • [Wayback/Archive] NodeList: forEach() method – Web APIs | MDN

    The forEach() method of the NodeList interface calls the callback given in parameter once for each value pair in the list, in insertion order.

    Parameters

    callback
    A function to execute on each element of someNodeList. It accepts 3 parameters:

    currentValue
    The current element being processed in someNodeList.
    currentIndex Optional
    The index of the currentValue being processed in someNodeList.
    listObj Optional
    The someNodeList that forEach() is being applied to.
    thisArg Optional
    Value to use as this when executing callback.

    Example

    JSCopy to Clipboard

    const node = document.createElement("div");
    const kid1 = document.createElement("p");
    const kid2 = document.createTextNode("hey");
    const kid3 = document.createElement("span");
    
    node.appendChild(kid1);
    node.appendChild(kid2);
    node.appendChild(kid3);
    
    const list = node.childNodes;
    
    list.forEach(function (currentValue, currentIndex, listObj) {
      console.log(`${currentValue}, ${currentIndex}, ${this}`);
    }, "myThisArg");
    

    The above code results in the following:

    [object HTMLParagraphElement], 0, myThisArg
    [object Text], 1, myThisArg
    [object HTMLSpanElement], 2, myThisArg
    
  • [Wayback/Archive] if…else – JavaScript | MDN (since I always forget if a block statement with curly braces is mandatory in the “then” or else clause):

    Syntax

    if (condition)
      statement1
    
    // With an else clause
    if (condition)
      statement1
    else
      statement2

Queries:

–jeroen

Initial versions

Version 1: plain script

Version 2: initial Bookmarklet

Most recent version


javascript:(function(){
publicizeFormEditHref = document.getElementById('publicize-form-edit'); // "edit" href
if(publicizeFormEditHref) {
publicizeFormEditHref.click();
}
mastodonCheckboxes = document.getElementsByClassName('wpas-submit-mastodon'); // any Mastodon checkboxes (one can have zero or more accounts configured)
Array.from(mastodonCheckboxes).forEach((mastodonCheckbox) => {
mastodonCheckbox.checked = true;
});
publicizeFormHideHref = document.getElementById('publicize-form-hide'); // "OK" button disguised as href
if (publicizeFormHideHref) {
publicizeFormHideHref.click();
}
savePostButton = document.getElementById('save-post'); // button exists when post has status "draft"
if (savePostButton) {
savePostButton.click();
}
else {
updateButton = document.getElementById('publish'); // button exists when post has status "draft", "scheduled", or "published"; when "draft" a click() will either "schedule" or "publish" depending on the schedule timestamp being in the future or past
if (updateButton) {
updateButton.click();
}
}
})();

 

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.