<?xml version="1.0" encoding="utf-8" ?><rss version="2.0" xmlns:tt="http://teletype.in/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>Eugene Fox</title><generator>teletype.in</generator><description><![CDATA[Software developer. Making guides, tips &amp; tricks on .NET and Web development]]></description><image><url>https://img3.teletype.in/files/61/67/6167b188-ca71-4881-a245-6d0bbfae0457.png</url><title>Eugene Fox</title><link>https://blog.xfox111.net/</link></image><link>https://blog.xfox111.net/?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=xfox111</link><atom:link rel="self" type="application/rss+xml" href="https://teletype.in/rss/xfox111?offset=0"></atom:link><atom:link rel="next" type="application/rss+xml" href="https://teletype.in/rss/xfox111?offset=10"></atom:link><atom:link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></atom:link><pubDate>Tue, 07 Apr 2026 19:45:12 GMT</pubDate><lastBuildDate>Tue, 07 Apr 2026 19:45:12 GMT</lastBuildDate><item><guid isPermaLink="true">https://blog.xfox111.net/tabs-aside-3-0</guid><link>https://blog.xfox111.net/tabs-aside-3-0?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=xfox111</link><comments>https://blog.xfox111.net/tabs-aside-3-0?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=xfox111#comments</comments><dc:creator>xfox111</dc:creator><title>Finally, Tabs aside 3.0 is here!</title><pubDate>Wed, 30 Jul 2025 12:29:22 GMT</pubDate><media:content medium="image" url="https://img2.teletype.in/files/1c/78/1c782fb3-f591-48a0-bbd1-74b4e0c7c1f0.png"></media:content><category>My projects</category><description><![CDATA[<img src="https://img2.teletype.in/files/58/0b/580b16cb-6413-4dd6-aba4-c1205b592e9c.png"></img>Long waited release of the Tabs aside extension is finally here: new UI, new features and new bugfixes!]]></description><content:encoded><![CDATA[
  <p id="PxaJ">Long waited release of the Tabs aside extension is finally here: new UI, new features and new bugfixes!</p>
  <figure id="grXP" class="m_original">
    <img src="https://img2.teletype.in/files/58/0b/580b16cb-6413-4dd6-aba4-c1205b592e9c.png" width="1280" />
    <figcaption>Tabs aside: Bookmarks redefined.</figcaption>
  </figure>
  <p id="wC0B">2 years and 6 months since the planned release date, countless hours of work... Several times the work had to be started from scratch... It&#x27;s been a long way, but it&#x27;s finally ready. I am proud to announce one of my biggest open-source updates yet: Tabs aside 3.0!</p>
  <figure id="OmJF" class="m_column">
    <img src="https://img3.teletype.in/files/67/51/675103c4-86c6-4b6a-8404-f6f45067d595.jpeg" width="1878" />
    <figcaption>Time truly flies by, doesn&#x27;t it?</figcaption>
  </figure>
  <p id="4XjD">This update is not just a re-skin of the original extension: every aspect of it was re-worked from the ground up with new logic, new features and, of course, new design. </p>
  <p id="bgD8">Let&#x27;s take a look on some new changes:</p>
  <h2 id="8v2h">And first, new UI!</h2>
  <p id="h4AK">This UI now fully embraces Microsoft&#x27;s Fluent UI design language which makes it look fresh and fancy on any modern browser: simple yet powerful. As everything should be.</p>
  <figure id="KPVH" class="m_column">
    <img src="https://img4.teletype.in/files/3a/8c/3a8c9d03-fa9f-4a1b-b87c-abc3890c4350.png" width="2880" />
    <figcaption>Tabs aside with a new look (Microsoft Edge)</figcaption>
  </figure>
  <figure id="3mYr" class="m_column">
    <img src="https://img3.teletype.in/files/a6/16/a616135c-9c9e-46b2-b3b0-795aadc360a2.png" width="2880" />
    <figcaption>List view</figcaption>
  </figure>
  <p id="Oxee">Now let&#x27;s talk features.</p>
  <h2 id="mUin">Customize <em>anything</em>!</h2>
  <p id="l5ym">Starting from 3.0 collection list&#x27;s home is now browser&#x27;s side panel. This was done to improve consistency of the user experience, since panel is now independent from page&#x27;s content (in earlier versions the panel could appear either inside of the webpage, or in a separate tab, if the page was &quot;special&quot;)</p>
  <p id="bU54">Do not like it? You can move it to a popup or a tab (pinned, or closable). The choice is yours.</p>
  <p id="p8Ua">You can also change what the extension&#x27;s button does: it can show your collections or save them instead!</p>
  <figure id="mIrB" class="m_column">
    <img src="https://img2.teletype.in/files/54/e9/54e996a6-e5c7-410f-9809-90bebbf7ab66.png" width="1788" />
    <figcaption>Collection list is in a popup</figcaption>
  </figure>
  <figure id="cDHu" class="m_column">
    <img src="https://img3.teletype.in/files/e3/04/e3044e51-709a-495b-8a6d-7f8c858148b8.png" width="2880" />
    <figcaption>And now it&#x27;s in a pinned tab</figcaption>
  </figure>
  <p id="hJ4F">You can change how your collections look, what actions you prefer to be you default ones, and so on.</p>
  <p id="IxQj">Also, you can now change colors of collections!</p>
  <figure id="2tO7" class="m_column">
    <img src="https://img4.teletype.in/files/30/da/30da0905-3a4b-4913-852a-d46755cecab5.png" width="1140" />
    <figcaption>Give collections a proper look</figcaption>
  </figure>
  <h2 id="PyBz">Tab groups!</h2>
  <p id="Imig">What is better than saving tabs? Correct! Saving groups of tabs!</p>
  <figure id="3YgO" class="m_column">
    <img src="https://img2.teletype.in/files/1a/5d/1a5d0d67-1a34-4aa1-bbb9-6366ba6f9972.gif" width="2880" />
    <figcaption>Saving and restoring tab groups</figcaption>
  </figure>
  <p id="rEIE">And of course, you can customize groups just like collections!</p>
  <section style="background-color:hsl(hsl(0, 0%, var(--autocolor-background-lightness, 95%)), 85%, 85%);">
    <p id="mlld"><strong>Important note for Firefox users:</strong></p>
    <p id="ss5d">You have to use Firefox 139 or above to receive this update, since earlier versions of Firefox do not support tab groups</p>
  </section>
  <h2 id="932M">More ways to save tabs</h2>
  <p id="Wvxf">The philosophy of previous versions was that it was supposed to be only a temporary storage for your tabs: You need a pause? You set aside your opened tabs. And sometime later you open them and pick up where you left off.</p>
  <p id="n4j1">Slogan for Tabs aside 3.0 is &quot;Bookmarks redefined&quot;. This is why now you have much more options to save, organize and open your tabs and collections!</p>
  <ul id="3iJ8">
    <li id="SpIr">You can save all tabs</li>
    <li id="3jn3">You can save only selected tabs</li>
    <li id="xuCz">You can save and close all or selected tabs</li>
    <li id="L82t">You can straight up create a new empty collection</li>
    <li id="cy64">You can add tabs to existing collections</li>
    <li id="Eg9n">You can create empty groups and add tabs to them</li>
    <li id="jg8c">You can... I think you get it :)</li>
  </ul>
  <p id="gY53">Of course, you can also export your collections to your browser&#x27;s bookmarks.</p>
  <figure id="zNyE" class="m_column">
    <img src="https://img3.teletype.in/files/aa/ca/aaca5b9b-bcc3-44a4-99df-3078132fe5e0.gif" width="960" />
    <figcaption>Create new collections from scratch</figcaption>
  </figure>
  <p id="Wmwf">And last but not least:</p>
  <h2 id="ljZA">You can reorder everything!</h2>
  <p id="NZAj">This is one of the most anticipated features (and the one that brought the most troubles during development) - you can now drag and drop collections, groups and tabs however you like!</p>
  <figure id="1pL5" class="m_column">
    <img src="https://img4.teletype.in/files/38/1a/381a6042-e7a6-4458-a17f-b763f30cb220.gif" width="960" />
    <figcaption>Hold and drag a tab, group, or collection to move it to another place</figcaption>
  </figure>
  <h2 id="iU9n">One more thing...</h2>
  <p id="qKkF">During the development I have revised my approach to development and maintenance processes of my projects. This is why, starting from this version, the extension will be receiving regular updates to keep everything up and running.</p>
  <p id="u0sW">These updates will include bugfixes, security and feature updates, and will be distributed on a monthly basis. This way, I will make sure that you get the best experience I am able to provide.</p>
  <h2 id="j8uv">Available now!</h2>
  <p id="WlXY">The update is live! You can either check for extension updates on your browser to download the latest version or, if you want to download it for the first time, you can head to one of the available stores:</p>
  <ul id="eS8t">
    <li id="nomC"><a href="https://microsoftedge.microsoft.com/addons/detail/tabs-aside/kmnblllmalkiapkfknnlpobmjjdnlhnd" target="_blank">Microsoft Edge Add-ons</a></li>
    <li id="3Dbp"><a href="https://addons.mozilla.org/firefox/addon/ms-edge-tabs-aside/" target="_blank">Firefox Add-ons</a></li>
    <li id="uuND"><a href="https://chromewebstore.google.com/detail/tabs-aside/mgmjbodjgijnebfgohlnjkegdpbdjgin" target="_blank">Chrome web store</a></li>
    <li id="1iWb"><a href="https://github.com/xfox111/TabsAsideExtension/releases/latest" target="_blank">GitHub</a> (for sideloading and testing)</li>
  </ul>
  <h2 id="EQnS">Afterthoughts</h2>
  <p id="ORfP">Of course, there&#x27;re quite a few more features to this update, but these were the most notable ones. You can find a full list of changes below, at the end of the article.</p>
  <p id="S5lx">Again, this is a big update for this project and for me personally. The project started as a mere replica of an old retired feature of an old retired Microsoft Edge. But this update signifies a new era for me, and for this project, that now has its own path.</p>
  <figure id="jCdM" class="m_column">
    <img src="https://img2.teletype.in/files/d9/74/d974e8e1-69c0-49af-8a55-fdaa43b0aeef.png" width="2880" />
    <figcaption>Tabs aside. Version 1.0</figcaption>
  </figure>
  <p id="flMb">As I saw the number of users growing (by the way, we are at 15k of weekly users now!), and all your feedback and support... This is what kept me going. And I will do my best to keep it that way.</p>
  <p id="aHF4">Thank you ❤️</p>
  <p id="aqAD">Cheers,<br />Eugene Fox</p>
  <figure id="VzRk" class="m_column">
    <img src="https://img2.teletype.in/files/16/ae/16ae94c3-bd08-4e38-828d-fa38f3fc3bb7.png" width="1500" />
    <figcaption>Follow me on Bluesky: <a href="https://bsky.app/profile/xfox111.net" target="_blank">@xfox111.net</a></figcaption>
  </figure>
  <hr />
  <h2 id="qilv">Full changelog</h2>
  <h3 id="ByFx">General</h3>
  <ul id="ZaOn">
    <li id="ADRQ">Migrated extension to MV3</li>
    <li id="bZUb">Update is available on Firefox only for versions 139 and above</li>
    <li id="wE55">New UI/UX based on Microsoft&#x27;s <code>@fluentui</code> library</li>
    <li id="OjEt">Collections are now displayed in multiple columns on wide screens when in &quot;List view&quot;</li>
    <li id="Syiy">Added ability to search and filter collections</li>
    <li id="Etj2">Added ability to sort collections by creation date or alphabetically</li>
    <li id="pbWx">Added ability to reorder collections and items using drag and drop</li>
    <li id="YmgA">Default collection list location was moved to browser&#x27;s sidebar</li>
    <li id="EbeN">Added ability to save tabs without closing them</li>
    <li id="r7an">Ability to set aside selected tabs is now reflected in the UI</li>
    <li id="Ypwj">Added Ukrainian locale</li>
  </ul>
  <h3 id="7BRV">Collections</h3>
  <ul id="jK9P">
    <li id="5QOK">Added ability to change collection&#x27;s color</li>
    <li id="g7iL">Added ability to open collection in a new window</li>
    <li id="Czck">Added ability to open collection in a private window (requires permission to work with private windows)</li>
    <li id="7YS9">Added ability to export collection to bookmarks</li>
    <li id="2VHt">Added ability to add selected tabs to an existing collection</li>
    <li id="QYnJ">If collection has a color and doesn&#x27;t have any sub-groups, it will be opened as a tab group</li>
  </ul>
  <h3 id="wKRo">Groups</h3>
  <ul id="qogh">
    <li id="02Ie">Added ability to save and open tab groups</li>
    <li id="Q5Oh">Groups can be customized</li>
    <li id="4ZXK">Pinned tabs are now saved into a &quot;Pinned&quot; group inside a collection</li>
  </ul>
  <h3 id="IPyn">Settings &amp; storage</h3>
  <ul id="u7DK">
    <li id="BUFk">Added ability to import/export extension&#x27;s data</li>
    <li id="dzpm">Added ability to choose default save action (just save tabs, or save and close them)</li>
    <li id="zGj4">Added ability to choose default restore action for collections (just open a collection, or open it and remove from storage)</li>
    <li id="QRgH">Added ability to change collections list location (sidebar, popup, separated tab, or pinned tab)</li>
    <li id="VkQJ">(Chromium-only) Added ability to change extension icon action to show context menu</li>
    <li id="IBOU">Added ability to force toolbars to be always visible</li>
    <li id="2i05">Added ability to hide collection counter badge</li>
    <li id="c6gq">Added ability to turn on notification when saving tabs from context menu (or extension icon action)</li>
  </ul>
  <h3 id="ePyB">Addressed issues</h3>
  <ul id="RthV">
    <li id="C1Q8">Efficiency and resilience of cloud storage was greatly improved</li>
    <li id="pNn2">Added multiple safeguards around cloud storage to make sure that user data can&#x27;t be lost</li>
    <li id="WO3R">Added ability to disable cloud storage for collections (extension settings will still use cloud storage)</li>
    <li id="sJuI">Tab thumbnails now use Opengraph previews as well as tab captures as a fallback</li>
    <li id="UR5I">Addressed several issues regarding saved or opened tabs being blank</li>
  </ul>

]]></content:encoded></item><item><guid isPermaLink="true">https://blog.xfox111.net/XRC-bHdZCNJ</guid><link>https://blog.xfox111.net/XRC-bHdZCNJ?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=xfox111</link><comments>https://blog.xfox111.net/XRC-bHdZCNJ?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=xfox111#comments</comments><dc:creator>xfox111</dc:creator><title>Setting up CI/CD for Web-browser extension with GitHub Actions</title><pubDate>Sat, 31 Jul 2021 13:27:37 GMT</pubDate><media:content medium="image" url="https://img2.teletype.in/files/1a/00/1a003730-78e4-489a-9ce5-4ada86bcb62c.png"></media:content><category>Software Developement</category><description><![CDATA[<img src="https://img1.teletype.in/files/0a/3e/0a3e9c02-5f9a-4a5f-a9c2-97b20d6e1907.png"></img>Reupload of my posts from Blogspot from 3-Nov-20]]></description><content:encoded><![CDATA[
  <figure id="8lR6" class="m_original">
    <img src="https://img1.teletype.in/files/0a/3e/0a3e9c02-5f9a-4a5f-a9c2-97b20d6e1907.png" width="2736" />
    <figcaption>Bottom text</figcaption>
  </figure>
  <blockquote id="hzVA">Reupload of my posts from Blogspot from 3-Nov-20</blockquote>
  <p id="RY4Z">Hi there!</p>
  <p id="I7n6">Last time I&#x27;ve told you <a href="https://blog.xfox111.net/h8fe86m_oGO" target="_blank">how to debug web extensions with VS Code</a>. This time I going to show you some tools which help you to automate your extension development workflow. I&#x27;m talking about continuous integration and delivery</p>
  <h3 id="ZJ5P">So, what CI/CD exactly is?</h3>
  <p id="6Kf3">Continuous integration and delivery allow you to automate some parts of a development workflow like building, testing, packaging and distributing. So, everything you need here is to push your code into your repository and the rest will be done by computer</p>
  <h3 id="lSSP">Cool, how can I opt-in?</h3>
  <p id="SBBG">Of course! All you need is to set up your CI/CD pipeline. But actually, it&#x27;s not that simple if you try to do it yourself since there&#x27;re a lot of underwater rocks. So that is why I&#x27;m doing this article</p>
  <p id="xGMZ">Today I&#x27;ll cover set-ups of CI/CD pipelines for Chrome and Firefox extension webstores</p>
  <h2 id="2v7x">Prerequisites</h2>
  <p id="zyQ3">So, all you need right now is your WebExtension source code saved in GitHub repo. I will use for reference my latest and greatest <a href="https://blog.xfox111.net/7cZOt9zD71x" target="_blank">Password generator</a> extension. You can also check it out later to see how it is done there</p>
  <p id="aU1e">Note that your project <strong>has to have at least one submission to selected stores</strong> to be automated</p>
  <h2 id="jSUu">Workflow file setup</h2>
  <p id="xkDt">So, first thing we need to do is create our workflow file. These files contain instructions for computer on what and how it should integrate and deliver your extension. Usually, WFs have a <code>.yaml</code> file extension. So, GitHub Actions WF is not an exclusion</p>
  <p id="tRtd">Navigate to your repository root folder and create a <code>.yaml</code> file on <code>/.github/workflows/your_workflow_file_name.yaml</code>. Name of the file can be anything you want</p>
  <p id="LrRp">So, here I&#x27;ve created a file on the exact folder path (you shouldn&#x27;t push your file for now though)</p>
  <p id="6KfZ"><strong>[Insert image here]</strong></p>
  <p id="Mmsu">Next thing, we need to fill our file with base instructions which we will use no matter where we will publish our project</p>
  <pre data-lang="yaml" id="HbDi">name: CI	# Name of your workflow

on:
  workflow_dispatch:	# Allows you to manually trigger workflow
  push:
    # Triggers workflow only if code is pushed to master/main branch
    branches: [ master, main ]
    paths:
      # Triggers workflow only if manifest content is changed
      - &#x27;manifest.json&#x27;

jobs:</pre>
  <p id="w3OB">Here we&#x27;ve set some triggers: conditions in which pipeline will be started</p>
  <p id="1D8J">Here our triggers are set to fire only if we changed extension manifest on master/main branch. We did it because of several reasons:</p>
  <ul id="3DhC">
    <li id="dzyQ">Here our triggers are set to fire only if we changed extension manifest on master/main branch. We did it because of several reasons:</li>
    <li id="NPHy">We don&#x27;t want our changes from development branch be published as a major update</li>
    <li id="VDWf">Every time we submit new extension version, we have to change its version in manifest, so every push to master/main we want to publish has to contain this change</li>
  </ul>
  <blockquote id="4HOO"><strong>Note</strong> that YAML file syntax is indetation-sensitive. Make sure you didn&#x27;t mess with tabs and spaces. More information about workflow file syntax you can find <a href="https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-syntax-for-github-actions" target="_blank">here</a></blockquote>
  <p id="SF1c">Now we need to make sure we have GitHub Actions turned on for our repository</p>
  <p id="Pov5">To do that we need to navigate to <code>Settings -&gt; Actions</code> of the repo (<a href="https://github.com/%username%/%repository%/settings/actions" target="_blank"><code>https://github.com/%username%/%repository%/settings/actions</code></a>) and make sure we have checked anything but <code>Disable Actions</code></p>
  <p id="MtRj"><strong>[Insert image here]</strong></p>
  <p id="mYDm">Here ends general preparation of the workflow and now we will move to store-specific actions</p>
  <h2 id="Birr">Setting up Firefox webstore submission</h2>
  <h3 id="Jxv6">Obtain API credential</h3>
  <p id="Gxd4">Since we deal with some sensitive data here, we need to make sure everything is secured and nobody can sabotage our release process. So we need to obtain some access keys which will authorize our pipelines.</p>
  <p id="Tjo9">First thing, we need to go to <a href="https://addons.mozilla.org/developers/addon/api/key" target="_blank">Firefox Add-in API management page</a>, generate and copy <code>JWT issuer</code> value (that will be our client ID value) and <code>JWT secret</code> (client secret)</p>
  <blockquote id="HgzP"><strong>Note:</strong> do not share these values with anyone else! Especially, <strong>DO NOT put these values into your workflow file as a plain text!</strong></blockquote>
  <p id="dXI0"><strong>[Put Image here]</strong></p>
  <p id="rsOF">Navigate to the repository&#x27;s secrets page (<code>Settings -&gt; Secrets</code> or <a href="https://github.com/%username%/%repository%/settings/secrets" target="_blank"><code>https://github.com/%username%/%repository%/settings/secrets</code></a>) and create two new secrets:</p>
  <ul id="sgpn">
    <li id="GpYy"><code>FIREFOX_API_KEY</code> - Paste here your <code>JWT issuer</code> token</li>
    <li id="LzyZ"><code>FIREFOX_CLIENT_SECRET</code> - Put your <code>JWT secret</code> token here</li>
  </ul>
  <p id="7Gmb"><strong>[Put Image here]</strong></p>
  <p id="LcJ8">You can use any other names for your secrets&#x27; variables</p>
  <p id="RTCr">This is a safe storage for sensitive data. No one will be able to values stored here. Even you won&#x27;t be able to see them</p>
  <h3 id="dyW3">Update the workflow file</h3>
  <p id="wlby">Now we need to add a new job to our workflow which will push our extension to the webstore</p>
  <p id="cE8j">Open your workflow YAML file and add a new job:</p>
  <pre data-lang="yaml" id="p8Yw">jobs:
  Firefox:	# Job name
    runs-on: ubuntu-latest	# specify required OS for deployment machine

    steps:
    - uses: actions/checkout@v2	# Download your source code to the DM

    - name: Build Extension for Firefox
      id: web-ext-build
      uses: kewisch/action-web-ext@v1
      with:
        cmd: build

    - name: &#x27;Sign &amp; publish&#x27;
      id: web-ext-sign
      uses: kewisch/action-web-ext@v1
      with:
        cmd: sign
        channel: listed
        source: ${{ steps.web-ext-build.outputs.target }}
        apiKey: ${{ secrets.FIREFOX_API_KEY }}
        apiSecret: ${{ secrets.FIREFOX_CLIENT_SECRET }}

    - name: Drop artifacts
      uses: actions/upload-artifact@v2
      with:
        name: &#x27;Firefox Artefacts&#x27;
        path: ${{ steps.web-ext-sign.outputs.target }}</pre>
  <p id="I58T">Here we have 4 tasks in our job:</p>
  <ol id="uX3Q">
    <li id="22Sg"><a href="https://github.com/marketplace/actions/checkout" target="_blank">actions/checkout@v2</a> clones our source code to a deployment machine</li>
    <li id="GYnD"><a href="https://github.com/marketplace/actions/web-ext-action-for-firefox-add-ons" target="_blank">kewisch/action-web-ext@v1</a> with <code>cmd: build</code> packs our extension source code into XPI file which will be published to the webstore</li>
    <li id="DWge"><a href="https://github.com/marketplace/actions/web-ext-action-for-firefox-add-ons" target="_blank">kewisch/action-web-ext@v1</a> with <code>cmd: sign</code> signs the package (confirms that this package is legit and derived from official source) and publishes it to the webstore</li>
    <li id="j5Fg"><a href="https://github.com/marketplace/actions/upload-a-build-artifact" target="_blank">actions/upload-artifact@v2</a> drops our XPI file to workflow artifacts and makes it available for us to download for sideloading and testing purposes (optional task)</li>
  </ol>
  <p id="7qfB">In third sigining task we have to provide some parameters to publish our extension correctly:</p>
  <ul id="huNR">
    <li id="HfUx"><code>cmd: sign</code>: The command to run. This command signs and submits our extension to Firefox servers for verification</li>
    <li id="NVBi"><code>source</code>: path to our XPI package file. Here we use <code>${{ steps.web-ext-build.outputs.target }}</code> since it is an environmental variable</li>
    <li id="DnLq"><code>channel</code>: Once verification is complete, our extension will become available for everybody in the webstore (<code>listed</code>) or it will become available for <em>self-distribution</em> and won&#x27;t become visible through the webstore (unlisted). Leave it <code>channel: listed</code></li>
    <li id="JhO3"><code>apiKey</code>: our JWT issuer token required for legit publishing. We can use here our secret variables - <code>${{ secrets.VARIABLE_NAME }}</code>. In our case it&#x27;s <code>${{ secrets.FIREFOX_API_KEY }}</code></li>
    <li id="zeds"><code>apiSecret</code>: JWT secret token</li>
  </ul>
  <p id="d2X7">More info on workflow variables can be found on <a href="https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-syntax-for-github-actions#example-6" target="_blank">official GitHub documentation</a>. If you click on links from actions list above, you can find out more about specific action and its documentation</p>
  <h2 id="j5ng">Setting up Google Chrome webstore submission</h2>
  <h3 id="FRS0">Obtain API credential</h3>
  <p id="ZJoe">For Chrome webstore a process of obtaining credential is a bit tricky and requires a lot of explanations. So, instead of making another article I just leave a link to <a href="https://github.com/DrewML/chrome-webstore-upload/blob/master/How%20to%20generate%20Google%20API%20keys.md" target="_blank">a guideline which covers the case</a></p>
  <p id="jCqc">All we need here is to obtain <code>client ID</code>, <code>client secret</code> and <code>refresh token</code>. For more information what is it and how to live with it you cand find by googling an &#x27;<a href="https://www.bing.com/search?q=oauth2" target="_blank">OAuth2</a>&#x27; topic</p>
  <p id="AE7M"><strong>[Put Image Here]</strong></p>
  <h3 id="QUN4">Update the workflow file</h3>
  <p id="SXPT">Same as setting up Firefox workflow, we now need to add a new job to our pipeline:</p>
  <pre data-lang="yaml" id="32ga">jobs:
  Chrome:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v2

    - name: Pack extension
      uses: TheDoctor0/zip-release@0.4.1
      with:
      	filename: ./Package.zip
      	exclusions: &#x27;.git/* .vscode/* .github/* *.md&#x27;

    - name: Publish to Chrome Webstore
      uses: SebastienGllmt/chrome-addon@v3
      with:
      	extension: yourextensionidhere
      	zip: ./Package.zip
      	client-id: ${{ secrets.CHROME_CLIENT_ID }}
      	client-secret: ${{ secrets.CHROME_CLIENT_SECRET }}
      	refresh-token: ${{ secrets.CHROME_REFRESH_TOKEN }}

    - name: Drop artifacts
      uses: actions/upload-artifact@v2
      with:
      	name: &#x27;Chrome Artifacts&#x27;
      	path: ./Package.zip</pre>
  <p id="kmNS">As you can see, there&#x27;re some major differences between Firefox and Chrome jobs. Here&#x27;s some key points:</p>
  <ul id="cc6V">
    <li id="XMi9">We don&#x27;t have to pack our extension with special format. Everything we need is to create a zip archive of our file with manifest in the root</li>
    <li id="EmHi">We don&#x27;t have to sign our package. Everything will be done after submission</li>
    <li id="OGMM">We need to specify extension ID and provide a refresh token since we will publish our extension using &quot;3d party&quot; (technically, our) application</li>
  </ul>
  <p id="effz">Everything else is pretty much the same as it is on the Firefox job, so I see no reason to stay on it anymore</p>
  <p id="5PaN">More information about used actions you can find their marketplace pages:</p>
  <ul id="rvZe">
    <li id="KfOA"><a href="https://github.com/marketplace/actions/checkout" target="_blank">actions/checkout@v2</a></li>
    <li id="PQgg"><a href="https://github.com/marketplace/actions/zip-release" target="_blank">TheDoctor0/zip-release@0.4.1</a></li>
    <li id="hRwo"><a href="https://github.com/marketplace/actions/chrome-extension-publish-action" target="_blank">SebastienGllmt/chrome-addon@v3</a></li>
    <li id="vBOw"><a href="https://github.com/marketplace/actions/upload-a-build-artifact" target="_blank">actions/upload-artifact@v2</a></li>
  </ul>
  <hr />
  <p id="fBYJ">So, here&#x27;s our complete workflow file:</p>
  <figure>
    <script src="https://gist.github.com/XFox111/99f7925c98b81fbeb18fa12342ce0f4c.js"></script>
  </figure>
  <p id="P0wS">So, that&#x27;s it. All we have to do now is to push our updated workflow file to the repo and trigger our workflow and make sure everything is up and running</p>
  <h2 id="dwDw">Wait, and how do I set up CI/CD for Safari/Microsoft Edge/etc. extensions?</h2>
  <p id="0A1e">You can&#x27;t. Unfortunately, neither Apple nor Microsoft didn&#x27;t make action tasks for automatic deployment of their browsers&#x27; extensions. And while it&#x27;s understandable for the former one, since Safari has a different architecture of extensions and different submission processes, it&#x27;s unclear for Microsoft not doing this, since new MS Edge is basically modified Google Chrome and it has same architecture and same submission processes as Chrome</p>
  <p id="Wty8">Other browsers either aren&#x27;t just popular enough or are based on different architecture</p>
  <h2 id="ExFG">Conclusion</h2>
  <p id="sTIU">Hope this article will help you with your own project. If you still have any questions left, feel free to ask them in the comment section below. You can also leave a topic suggestion for my next article in the comment section as well</p>
  <p id="Amlr">If you like ❤️ this, you can <a href="https://buymeacoff.ee/xfox111" target="_blank">Buy Me a Coffee ☕</a> or follow me on <a href="https://twitter.com/xfox111" target="_blank">Twitter 🗨</a>. Thanks for your time ;)</p>
  <p id="Sg0e">Cheers,<br />XFox 🦊</p>

]]></content:encoded></item><item><guid isPermaLink="true">https://blog.xfox111.net/7cZOt9zD71x</guid><link>https://blog.xfox111.net/7cZOt9zD71x?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=xfox111</link><comments>https://blog.xfox111.net/7cZOt9zD71x?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=xfox111#comments</comments><dc:creator>xfox111</dc:creator><title>Password generator extension: High security in one click!</title><pubDate>Sat, 31 Jul 2021 12:20:25 GMT</pubDate><media:content medium="image" url="https://img1.teletype.in/files/8c/ac/8cac6561-b08e-43f5-a1bc-02e78abbe068.png"></media:content><description><![CDATA[<img src="https://img1.teletype.in/files/4d/93/4d935519-814b-41b7-a3c0-54503eb4eac7.png"></img>Reupload of my posts from Blogspot from 6-Oct-20]]></description><content:encoded><![CDATA[
  <figure id="THnQ" class="m_original">
    <img src="https://img1.teletype.in/files/4d/93/4d935519-814b-41b7-a3c0-54503eb4eac7.png" width="1920" />
    <figcaption>Password generator extension for Chromium and Firefox</figcaption>
  </figure>
  <blockquote id="i3cy">Reupload of my posts from Blogspot from 6-Oct-20</blockquote>
  <p id="w0w2">Extension for web browsers which helps you to easily generate strong passwords in one click</p>
  <p id="j2fC">This is my second browser extension and I hope, you&#x27;ll find it useful. Be sure to check my first extension which <a href="https://blog.xfox111.net/3QehjeKA8tL" target="_blank">brings &quot;Tabs aside&quot; feature from Microsoft Edge to all web-browsers</a></p>
  <figure id="f6P6" class="m_original">
    <img src="https://img2.teletype.in/files/5e/43/5e43ce3d-9eb4-4072-83b4-574ccf184472.gif" width="1920" />
    <figcaption>Quick demo of how is it work</figcaption>
  </figure>
  <h2 id="C7GK">Features</h2>
  <ul id="IomY">
    <li id="NGXK">Create strong passwords in one click</li>
    <li id="vRNt">Customizable generator</li>
    <li id="IR2b">Clean and simple UI</li>
    <li id="Cxaz">Dark mode</li>
  </ul>
  <h2 id="yMvh">Download</h2>
  <ul id="5aYM">
    <li id="hUp8"><a href="https://chrome.google.com/webstore/detail/jnjobgjobffgmgfnkpkjfjkkfhfikmfl" target="_blank">Google Chrome Webstore</a></li>
    <li id="vpRR"><a href="https://microsoftedge.microsoft.com/addons/detail/manimdhobjbkfpeeehlhhneookiokpbj" target="_blank">Microsoft Edge Add-ons Webstore</a></li>
    <li id="sshE"><a href="https://addons.mozilla.org/en-US/firefox/addon/easy-password-generator" target="_blank">Mozilla Firefox Add-ons Webstore</a></li>
    <li id="82yD"><a href="https://github.com/xfox111/PasswordGeneratorExtension/releases/latest" target="_blank">GitHub Releases</a></li>
  </ul>
  <h2 id="f34P">And yes, it&#x27;s an open-source project!</h2>
  <p id="cjGz">That means that anybody can contribute to the project, make own awesome features. Check out <a href="https://xfox111.net/PasswordGenerator" target="_blank">project&#x27;s GitHub repository</a> to get started</p>
  <figure id="KV6W" class="m_original">
    <img src="https://img4.teletype.in/files/75/26/752695cc-d757-431a-86e9-189af9c2adb4.png" width="2272" />
    <figcaption>Password generator v2.0 is out now!</figcaption>
  </figure>

]]></content:encoded></item><item><guid isPermaLink="true">https://blog.xfox111.net/h8fe86m_oGO</guid><link>https://blog.xfox111.net/h8fe86m_oGO?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=xfox111</link><comments>https://blog.xfox111.net/h8fe86m_oGO?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=xfox111#comments</comments><dc:creator>xfox111</dc:creator><title>Developing browser extensions with Visual Studio Code</title><pubDate>Sat, 31 Jul 2021 12:09:44 GMT</pubDate><media:content medium="image" url="https://img3.teletype.in/files/a2/b1/a2b12e8c-e939-479a-8283-b2dbb4be1d4e.png"></media:content><category>Software Developement</category><description><![CDATA[<img src="https://img1.teletype.in/files/cd/0e/cd0ec05e-6ea5-4602-adba-9b70a3071edb.png"></img>Reupload of my posts from Blogspot from 10-Sep-20]]></description><content:encoded><![CDATA[
  <figure class="m_original">
    <img src="https://img1.teletype.in/files/cd/0e/cd0ec05e-6ea5-4602-adba-9b70a3071edb.png" width="2736" />
    <figcaption>Developing browser extensions with Visual Studio Code</figcaption>
  </figure>
  <blockquote>Reupload of my posts from Blogspot from 10-Sep-20</blockquote>
  <p><code>Hello, World!</code><br />Not so far ago I wrote <a href="https://blog.xfox111.net/nVbdSgoKkJ7" target="_blank">an article about making a Chromium extension</a>. And now I&#x27;d like to tell you about debugging tools which I use to do this. Besides it seems that there&#x27;re just few articles about the topic and none about developing in VS Code</p>
  <p>So, let&#x27;s dive in</p>
  <h2>Prerequisites</h2>
  <p>First of all, further in the article I will assume that you already know about concepts of WebExtension development and have at least a prototype of one since this is a post about not coding but debugging</p>
  <p>So, what we&#x27;ll need:</p>
  <ul>
    <li><a href="https://code.visualstudio.com" target="_blank">Visual Studio Code Editor</a></li>
    <li>WebExtension or Chrome extension project</li>
    <li><a href="https://www.mozilla.org/firefox" target="_blank">Firefox browser</a></li>
  </ul>
  <p>Now you&#x27;ll probably going to ask: &quot;Can I use Google Chrome or any other browser&quot;. The answer is: &quot;No, you cannot&quot;. Unfortunately, Google Chrome debugging tools for VS Code currently don&#x27;t support extensions debugging. But honestly, if they even do, I&#x27;d still recommend you to use Firefox at least because it has more flexible built-in developer&#x27;s console</p>
  <p>So, that&#x27;s it. Let&#x27;s move to the setup</p>
  <h2>Environment setup</h2>
  <p>Let&#x27;s open our project&#x27;s workspace. This step is optional and can be done anytime but let&#x27;s just do it now</p>
  <p>So, your editor should be looking like this:</p>
  <figure class="m_column">
    <img src="https://img1.teletype.in/files/4e/e1/4ee10c9f-62b6-487b-8f5d-36bb6599d93a.png" width="2736" />
    <figcaption>VS code default environment</figcaption>
  </figure>
  <p>Now we need to open &quot;Extensions&quot; tab and install &quot;Debugger for Firefox&quot;. Just type into the search bar &quot;Firefox&quot; and it will be the first one on the list</p>
  <figure class="m_column">
    <img src="https://img3.teletype.in/files/2e/8d/2e8d03e3-4996-4268-b7ef-43c70286c382.png" width="2736" />
    <figcaption>Search for &quot;Firefox&quot; extension</figcaption>
  </figure>
  <p>Now we need to open &quot;Extensions&quot; tab and install &quot;Debugger for Firefox&quot;. Just type into the search bar &quot;firefox&quot; and it will be the first one on the list</p>
  <figure class="m_column">
    <img src="https://img2.teletype.in/files/10/5b/105bcccb-b125-4ab1-a3f9-49eb60e8c490.png" width="1892" />
    <figcaption>Install the extension</figcaption>
  </figure>
  <p>Just click &quot;Install&quot; and wait for a few seconds</p>
  <figure class="m_column">
    <img src="https://img3.teletype.in/files/e7/d5/e7d59b60-0691-4fc7-b943-77cbfc793aba.png" width="1874" />
    <figcaption>Verify that extension has been installed</figcaption>
  </figure>
  <p>Environment is now set up. Let&#x27;s move to configuration</p>
  <p>Navigate to debug tab and hit &quot;create a launch json file&quot;</p>
  <figure class="m_column">
    <img src="https://img1.teletype.in/files/84/11/84117365-05fa-4bc7-9717-bcfa1c39882d.png" width="1120" />
    <figcaption>Create a debug configuration file</figcaption>
  </figure>
  <p>After some initialization work VS will ask you to choose your environment. Select &quot;Firefox&quot;</p>
  <figure class="m_column">
    <img src="https://img3.teletype.in/files/a5/25/a525b03f-c65a-42fd-ac2a-64ef15ce31e8.png" width="917" />
    <figcaption>Select &quot;Firefox&quot; as your debug environment</figcaption>
  </figure>
  <p>This action will create debug configuration file <code>launch.json</code> with several pre-defined configurations: <code>Launch index.html</code>, <code>Launch localhost</code>, etc.</p>
  <p>If you want, you can remove all configurations but <code>Launch WebExtension</code> since it&#x27;s the only configuration we will use in the project</p>
  <figure class="m_column">
    <img src="https://img3.teletype.in/files/24/53/24530a0c-f6f2-44b1-b04c-63413e7b2200.png" width="2736" />
    <figcaption>Debug configuration file</figcaption>
  </figure>
  <p>Now if we go back to Debug tab, we&#x27;ll see that it now has standard debugging sections</p>
  <figure class="m_column">
    <img src="https://img3.teletype.in/files/6a/1c/6a1cc90c-dda7-4552-a1d3-3d131a9c8766.png" width="2736" />
    <figcaption>Debug panel in VS Code</figcaption>
  </figure>
  <p>Now we&#x27;re ready to go!</p>
  <h2>Debugging</h2>
  <p>Let&#x27;s try to launch debugger. Make sure you&#x27;ve set &quot;Launch WebExtension&quot; as a default launch task and press &quot;Start Debugging&quot; (or press F5 on your keyboard)</p>
  <figure class="m_column">
    <img src="https://img2.teletype.in/files/10/56/10563594-de9e-44c5-ace5-6abd9a739be8.png" width="848" />
    <figcaption>Select &quot;Launch WebExtension&quot; and click &quot;Run&quot;</figcaption>
  </figure>
  <p>You&#x27;ll see now debugging tools being launched and Firefox browser being launched in debug mode. This mode suggests that the browser runs in some sort of container and any changes won&#x27;t affect your actual environment</p>
  <figure class="m_original">
    <img src="https://img1.teletype.in/files/ca/04/ca04f766-6c4c-471a-b11a-168ad1beeb64.png" width="2736" />
    <figcaption>VS Code debug session</figcaption>
  </figure>
  <p>Now let&#x27;s put some breakpoints, add a watch statement and some <code>console.log()</code> functions and relaunch debugging session. And when your breakpoint is hit, you&#x27;ll see all data available at the moment to debug</p>
  <figure class="m_original">
    <img src="https://img2.teletype.in/files/9c/55/9c553537-1f8d-4dff-8bbb-0faea7621b82.png" width="2736" />
    <figcaption>Debug session inspection on breakpoint</figcaption>
  </figure>
  <p>So that&#x27;s it. Now you can use all power of Visual Studio Code for extensions development</p>
  <h2>Conclusion</h2>
  <p>Hope this article will help you with your own project. If you still have any questions left, feel free to ask them in the comment section below. You can also leave a topic suggestion for my next article in the comment section as well</p>
  <p>Next time I&#x27;ll write about configuring a CI/CD pipeline for WebExtension with GitHub Actions</p>
  <p>If you like ❤️ this, you can <a href="https://buymeacoff.ee/xfox111" target="_blank">Buy Me a Coffee ☕</a> or follow me on <a href="https://twitter.com/xfox111" target="_blank">Twitter 🗨</a>. Thanks for your time ;)</p>
  <p>Cheers,<br />XFox 🦊</p>

]]></content:encoded></item><item><guid isPermaLink="true">https://blog.xfox111.net/nVbdSgoKkJ7</guid><link>https://blog.xfox111.net/nVbdSgoKkJ7?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=xfox111</link><comments>https://blog.xfox111.net/nVbdSgoKkJ7?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=xfox111#comments</comments><dc:creator>xfox111</dc:creator><title>Embedding panel into webpage with WebExtension</title><pubDate>Fri, 30 Jul 2021 10:33:40 GMT</pubDate><media:content medium="image" url="https://img3.teletype.in/files/e5/79/e579e06d-d8c7-4587-8117-2b3ac02e7075.png"></media:content><category>Software Developement</category><description><![CDATA[<img src="https://img2.teletype.in/files/da/e1/dae1ba87-93ba-4671-9d6f-7c0ecede669d.png"></img>Reupload of my posts from Blogspot from 5-Jul-20]]></description><content:encoded><![CDATA[
  <figure class="m_original">
    <img src="https://img2.teletype.in/files/da/e1/dae1ba87-93ba-4671-9d6f-7c0ecede669d.png" width="2736" />
    <figcaption>Add panel to your Web extension</figcaption>
  </figure>
  <blockquote>Reupload of my posts from Blogspot from 5-Jul-20</blockquote>
  <p>Hi</p>
  <p>Recently I&#x27;ve <a href="https://blog.xfox111.net/3QehjeKA8tL" target="_blank">made a chrome extension</a> which acts like Tabs Aside feature from legacy Microsoft Edge. Today I&#x27;d like to tell you how I integrate such elements into website pages.</p>
  <p>Let&#x27;s jump in</p>
  <blockquote><strong>Note:</strong> it is advised to check the <a href="https://developer.chrome.com/extensions" target="_blank">extensions development tutorial</a></blockquote>
  <h2>Prerequisites</h2>
  <p>First, let&#x27;s create some essential files:</p>
  <ul>
    <li><code>background.js</code> - JavaScript file which will catch user&#x27;s input and manage panes&#x27; states</li>
    <li><code>inject-script.js</code> - will initialize/close pane on specific page</li>
    <li><code>manifest.json</code> - standard Chromium extension manifest</li>
    <li><code>pane.html</code> - our pane&#x27;s HTML layout</li>
  </ul>
  <p>Let&#x27;s navigate to the manifest file and add insert those strings:</p>
  <pre data-lang="jsx">{
	&quot;web_accessible_resources&quot;: [ &quot;*&quot; ],
	&quot;background&quot;:
	{
		&quot;scripts&quot;: [ &quot;background.js&quot; ],
		&quot;persistent&quot;: false
	}
}</pre>
  <p>First entry allows us to access any file from extension resources (like CSS, JS, images, etc.) from any webpage. The second one declares that the extension should have script running in background. &lt;code&gt;persistent&lt;/code&gt; key should be presented but it doesn&#x27;t bring any difference since in any way the background script will be running indefinitely because of set event listeners</p>
  <blockquote>For more information about the manifest see <a href="https://developer.chrome.com/extensions/manifest" target="_blank">Manifest File Format</a></blockquote>
  <h2>Listening to button clicks</h2>
  <p>Now let&#x27;s open background script and write some code:</p>
  <figure>
    <script src="https://gist.github.com/XFox111/b9bddca128ffc07d4e2e94a2d65a5ce8.js"></script>
  </figure>
  <p>At first, we retrieve the pane&#x27;s URL (which depends on extension&#x27;s ID assigned by your browser) and store it into a variable to prevent typos in future</p>
  <p>Next part requires some explanation: not every webpage allows us to do what we want (inject something into it). For example, we can&#x27;t inject out pane into settings page or new tab page or another extension&#x27;s page. Instead, we can open our pane as standalone webpage (of course if you need to open it anyway). So, for these cases we need to check if it&#x27;s a system page or not. All system pages have special protocol (e.g. <code>edge://</code> for Microsoft Edge) and regular pages use <code>http</code> or <code>https</code> protocols. So, we check if the target page has right protocol</p>
  <p>The next thing is that there&#x27;re some websites which also doesn&#x27;t allow to inject anything. Those are <a href="https://chrome.google.com/webstore" target="_blank">Google Chrome Webstore</a> and <a href="https://microsoftedge.microsoft.com/addons" target="_blank">Microsoft Edge add-ons Webstore</a>. So, we also exclude them</p>
  <p><strong>Note:</strong> There&#x27;s a high probability that there&#x27;re more websites with such restriction. So, some additional research is advised</p>
  <p>So, if page meets all this conditions, that means that we can run our script which will inject or close our pane. In other case, we should either open the pane in new tab or close this tab if it&#x27;s already opened</p>
  <p>We can also set up listeners to close standalone panes if they lost focus</p>
  <h2>Pane layout</h2>
  <p>Let&#x27;s jump into <code>pane.html</code> and set up basic pane layout:</p>
  <figure>
    <script src="https://gist.github.com/XFox111/a80165a9a9ca063bfbfb0e1d52a32adf.js"></script>
  </figure>
  <p>As you can see, it&#x27;s the most common layout for any webpage. You can customize this page whatever you want. However, we&#x27;ve also added a CSS selector which will collapse our pane&#x27;s width to 40% if it&#x27;s embedded into page to make it look like it&#x27;s a real sidebar pane. Also, we&#x27;ve included <code>inject-script.js</code> into the bottom of the page to make it run after pane is loaded</p>
  <h2>Pane initialization</h2>
  <p>Now let&#x27;s write initialization script which will load our pane. Instead of injecting our pane as a <code>div</code> and having to deal with CSS conflicts, we just insert our pane via <code>iframe</code></p>
  <figure>
    <script src="https://gist.github.com/XFox111/afbcae5ab14e16818336888a901271bf.js"></script>
  </figure>
  <p>First, we are checking if the script is running on the standalone pane or on an embedded one. If it&#x27;s not, then that means that we need to show or hide the pane from webpage. To do that we trying to get our pane&#x27;s <code>iframe</code>. If we can&#x27;t retrieve any that means that the pane isn&#x27;t opened yet. So, we create new <code>iframe</code> settings some styles to make it look right and navigating it to our pane&#x27;s HTML file. If we found the <code>iframe</code> that means that the pane is already opened, and we just delete the <code>iframe</code> from the DOM</p>
  <p>If the script is running on the standalone page or inside an &lt;code&gt;iframe&lt;/code&gt;, we try to initialize the pane. But at first, we must check presence of the pane and if there&#x27;s no - end script execution. We need to do this because <code>chrome.tabs.executeScript</code> we call on the background script, runs our initialization script on the active tab <strong>including</strong> its iframes</p>
  <p>Then if it&#x27;s an embedded pane we add an <code>embedded</code> attribute to it to trigger the CSS selector mentioned above. After that we can perform the rest of our initialization</p>
  <p><strong>Note:</strong> in extensions usually, we cannot use inline JavaScript (for security reasons) as well as set up inline event listeners. Consider this while developing</p>
  <h2>Conclusion</h2>
  <p>Hope this article will help you with your own project. If you still have any questions left, feel free to ask them in the comment section below. You can also leave a topic suggestion for my next article in the comment section as well</p>
  <p>Hope this article will help you with your own project. If you still have any questions left, feel free to ask them in the comment section below. You can also leave a topic suggestion for my next article in the comment section as well</p>
  <p>If you like ❤️ this, you can <a href="https://buymeacoff.ee/xfox111" target="_blank">Buy Me a Coffee ☕</a> or follow me on <a href="https://twitter.com/xfox111" target="_blank">Twitter 🗨</a>. Thanks for your time ;)</p>
  <p>Cheers,<br />XFox 🦊</p>

]]></content:encoded></item><item><guid isPermaLink="true">https://blog.xfox111.net/3QehjeKA8tL</guid><link>https://blog.xfox111.net/3QehjeKA8tL?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=xfox111</link><comments>https://blog.xfox111.net/3QehjeKA8tL?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=xfox111#comments</comments><dc:creator>xfox111</dc:creator><title>Tabs Aside extension for chromium-based browsers</title><pubDate>Fri, 30 Jul 2021 09:45:22 GMT</pubDate><media:content medium="image" url="https://img4.teletype.in/files/ff/84/ff845c59-167b-48f9-98ee-b7b32fd8d803.png"></media:content><description><![CDATA[<img src="https://img3.teletype.in/files/24/9b/249b5ab6-7b51-478b-b8eb-3147cfa7cb79.png"></img>Reupload of my posts from Blogspot from 5-Jul-20]]></description><content:encoded><![CDATA[
  <figure id="iuEL" class="m_column">
    <img src="https://img3.teletype.in/files/24/9b/249b5ab6-7b51-478b-b8eb-3147cfa7cb79.png" width="1920" />
    <figcaption>Tabs aside for Chromium</figcaption>
  </figure>
  <blockquote id="9u35">Reupload of my posts from Blogspot from 5-Jul-20</blockquote>
  <p id="WqBz">If you’re like me, you often find yourself with a bunch of open tabs. You’d like to get those tabs out of the way sometimes, but they’re maybe not worth saving as actual bookmarks.</p>
  <p id="Xkei">In the Edge browser, Microsoft has introduced a new feature called &quot;Tabs aside&quot; (or Tab groups) which lets you set tabs aside in a sort of temporary workspace so that you can call them back up later.</p>
  <p id="rgsr">Unfortunately, in new Chromium-based Microsoft Edge, the devs decided not to implement this must-have-feature. So, I&#x27;ve decided to create a browser extension which replicates this awesome feature in Chromium-based browsers</p>
  <figure id="8bpn" class="m_column">
    <iframe src="https://www.redditmedia.com/r/MicrosoftEdge/comments/hcigvg/ive_made_a_tabs_aside_extension_for_chromiumbased/?ref_source=embed&ref=share&embed=true"></iframe>
  </figure>
  <h2 id="pnXJ">Features</h2>
  <ul id="kvJV">
    <li id="2T6n">Familiar UI inherited from legacy Microsoft Edge with some improvements</li>
    <li id="l38i">Auto Dark mode</li>
    <li id="1Mw0">Now you can restore one tab from collection without removing</li>
  </ul>
  <h2 id="gdxs">Download</h2>
  <ul id="m0DG">
    <li id="O6jM"><a href="https://chrome.google.com/webstore/detail/tabs-aside/mgmjbodjgijnebfgohlnjkegdpbdjgin" target="_blank">Google Chrome Webstore</a></li>
    <li id="pTDZ"><a href="https://microsoftedge.microsoft.com/addons/detail/kmnblllmalkiapkfknnlpobmjjdnlhnd" target="_blank">Microsoft Edge Add-ons Webstore</a></li>
    <li id="Dv9L"><strong>UPD:</strong> <a href="https://addons.mozilla.org/en-US/firefox/addon/ms-edge-tabs-aside" target="_blank">Mozilla Firefox Add-ons Webstore</a>!</li>
    <li id="jgwP"><a href="https://github.com/xfox111/TabsAsideExtension/releases/latest" target="_blank">GitHub Releases</a></li>
  </ul>
  <h2 id="ZRif">And yes, it&#x27;s an open-source project!</h2>
  <p id="cKHx">That means that anybody can contribute to the project, make own awesome features. Check out <a href="https://github.com/xfox111/TabsAsideExtension" target="_blank">project&#x27;s GitHub repository</a> to get started</p>

]]></content:encoded></item></channel></rss>