#currentwindow
Explore tagged Tumblr posts
ellenpbritton · 8 years ago
Photo
Tumblr media Tumblr media Tumblr media Tumblr media Tumblr media
Caventou; Biomimetic, sustainable design
Current Window is a modern version of stained glass — using current technologies. The coloured pieces of glass are generating electricity from daylight, and can even harness diffused sunlight. This electricity can be used to power a whole range of electrical appliances. The glass pieces are made of ‘Dye Sensitised Solar Cells’, which use the properties of colour to create an electrical current — just like photosynthesis in plants. Similarly to the various shades of green chlorophyll absorbing light, the coloured window panes harness energy. Plug in your devices through integrated USB ports in the window ledge. The greater the surface exposed, the more energy will be collected. Imagine these windows in churches, schools, and workplaces! Current Window offers us an example of energy-harvesting in a natural and aesthetic way, for our future.
Caventou was founded by Marjan van Aubel and Peter Krige. Marjan’s research process blends scientific precision with sensory responsiveness to develop aesthetic solutions for the future. Her objects make tangible the potential of technology and energy-harvesting for the benefit of the living environment. Intuitive and inquisitive, she believes interdisciplinary practice is the way forward for design. Peter is an experienced designer and engineer who has developed several successful products such as Beeline, Bare Conductive’s Touch Board and MOOn from concept stage to full scale production. Together they are re-defining solar technology and making it part of everyday life. 
These objects, the window and table, integrate solar technology naturally into our daily lives, turning everyday objects into independent power sources that live and breathe energy. This is the kind of biomimicry in design which I really admire, the benefits are tangible and the execution is elegant and seamless. This work captured my imagination when I first happened upon it last year, and has remained in my mind. This is the kind of project I’d love to aspire to looking forward into my final year.  
0 notes
eightyonekilograms · 7 years ago
Text
This is a long shot, but has anyone here developed a browser extension? Do you know how to get the url/title of the current tab if you're only requesting the activeTab permission? If you request tabs it's easy: browser.tabs.query({ active: true, currentWindow: true }), but I'm trying to restrict myself to the minimum permissions needed, and if you do that than browser.tabs.query() no longer seems to work.
Browser extensions punish you for doing the right thing ¯\_(ツ)_/¯
3 notes · View notes
holytheoristtastemaker · 5 years ago
Link
Introduction Browser extensions are programs which can modify and enhance your browsing experience. From small UI enhancements to automation, extensions can be used and built for a wide array of use cases. In this article we will look at a step by step guide to build a chrome extension. What are we building? Well our extension will have two jobs, first will be to fetch IMDb details of any movie from the context menu (right click menu), like this :
Tumblr media
Second will be demonstrating interaction with web pages and hence fetching IMDb ratings on Rotten Tomatoes home page when we click on extension button and will look like this :
Tumblr media
Notice how all movie titles are appended with ({imdbRating}) after we click on extension icon. The reason for the dual purpose is to demonstrate how to build background extensions (background scripts), extensions which interact with active web page (content scripts) and how to communicate between the two (message passing). You can find the complete code here.
Setup
Every chrome extension requires a manifest.json file. Think of it as configuration file which will tell chrome how to treat this extension. Lets just create a basic manifest file with :
{ "name": "IMDb Lookup", "description": "Display IMDb rating from context menu and on rotten tomatoes", "version": "0.1", "manifest_version": 2 "background": { "scripts": ["background.js"] }, "browser_action": { "default_icon": "icon.png" }, }
name and description are self descriptive and will be same on the chrome web store when you publish your extension. Background scripts are the javascript files which will be running in the background across all pages. They don't have access to current web page and hence can't access DOM for reading or manipulations but they do have access to all chrome APIs. As we need to create a new entry in the context menu of chrome, we will be using a background script. browser_action is used to put icons in the main Google Chrome toolbar, to the right of the address bar. You will have to add some icon.png file to your working directory.
manifest_version 1 is deprecated by chrome and hence should start with 2.
With our manifest ready, lets create a background.js file to test if things are working :
//background.js alert("Did it work?")
Running the extension
To run the extension we have built so far, go to chrome://extensions/ and toggle the Developer mode mode on. Click on Load unpacked and browse to the directory containing the extension.
Tumblr media
It worked ! Every time you make some changes to the code, just click on reload button on your extension card and chrome will incorporate all the changes.
Building the background extension
Our use case here is that when we highlight any text and right click, the context that appears should have a new menu saying fetch IMDb details for selected text or something and when you click on this menu you should see the IMDb details like rating and year on a popup. To do this we will be using chrome's context menu API. First we will have to require its permission by adding it in our manifest.json by adding this :
"permissions": ["contextMenus"],
Then we can add the following to our background.js file.
//create a context menu chrome.contextMenus.create({ //string to display on menu 'title': 'Search IMDB for "%s"', //contexts here is selection as we want to extract the highlighted text. 'contexts': ['selection'], //the event handler 'onclick': (context) => { const name = context.selectionText; alert(`Highlighted texts is : ${name}`) } });
Reload your extension and test it out!
Tumblr media
So we are now able to get the highlighted text to our event handler and are free to make API calls. We are going to use OMDb API for fetching IMDb details. Make the following changes to your background.js :
//create a context menu chrome.contextMenus.create({ //string to display on menu 'title': 'Search IMDB for "%s"', //contexts here is selection as we want to extract the highlighted text. 'contexts': ['selection'], //the event handler 'onclick': async (context) => { const name = context.selectionText; const response = await fetch(`https://www.omdbapi.com/?t=${name}&apikey=e48e70b4`) const { Title, Year, Runtime, Genre, Actors, imdbRating } = await response.json() const newLine = "\r\n" let message = `Title : ${Title}` message += newLine message += `Year : ${Year}` message += newLine message += `Runtime : ${Runtime}` message += newLine message += `Genre : ${Genre}` message += newLine message += `Actors : ${Actors}` message += newLine message += `IMDb Rating : ${imdbRating}` alert(message) } });
I am putting my own OMDb's api key here so that you can follow the tutorial with least friction. However if this breaks the internet 🤞and this api key usage reaches the limit, you can claim your free api key from here.
We are making a simple GET call using fetch and then displaying the result. Lets try this out.
Tumblr media
Thats it. We have successfully completed the first part of the tutorial.
Interacting with webpages
Lets look at our next use case, i.e. displaying IMDb rating next to movie titles on homepage of Rotten Tomatoes. We wont be able to do this inside our background.js file as it doesn't have access to active webpage and hence its DOM. To do this we will have to write content scripts. Content scripts are files that run in the context of web pages. They will have access to DOM and can read and manipulate it. Add the following to your manifest.json
"content_scripts": [{ "matches": [ "https://www.rottentomatoes.com/*" ], "js": ["content.js"] }],
This piece of configuration tells chrome to load content.js file into the webpage whenever the current webpage's URL matches https://www.rottentomatoes.com/*. As a result of this we will have access to webpage's DOM inside our content.js file. Create a content.js file and add the following lines :
//content.js alert("Did it work?")
Lets check if this works.
Tumblr media
It did work. The alert will only come when we are at rotten tomato website and not on any other website.
Building the content script
As we need to manipulate DOM, we might as well use jQuery. While not necessary at all, its a good idea to know how to use libraries inside chrome extensions. To do this download a version of jQuery from the jQuery CDN and put it in your extension’s directory. To load it, add it to manifest.json before content.js. Your final manifest.json should look like this:
{ "name": "IMDb Lookup", "description": "Display IMDb rating from context menu and on rotten tomatoes", "version": "0.1", "manifest_version": 2, "background": { "scripts": ["background.js"] }, "browser_action": { "default_icon": "icon.png" }, "permissions": ["contextMenus"], "content_scripts": [{ "matches": [ "https://www.rottentomatoes.com/*" ], "js": ["jquery-2.2.4.min.js", "content.js"] }] }
Now we can do the following in our content.js
const fetchRatings = () => { $(".media-lists__td-title").map(async function () { const name = this.innerText; const response = await fetch(`https://www.omdbapi.com/?t=${name}&apikey=e48e70b4`) const {imdbRating} = await response.json() this.innerText = `${name} (${imdbRating})` }) } fetchRatings();
Its some jQuery magic and the same OMDb API call to fetch rating. Lets test this out.
Tumblr media
Voila! We are now able to see IMDb rating on Rotten Tomatoes. But wait, this is not what we wanted. The DOM was supposed to be manipulated only when we click on our extension's icon on the toolbar and NOT by default. We have a problem now. Clicking on extension's icon is a Chrome event and hence our content.js wont have access to it and hence wont be able to trigger the fetchRatings function. Our background.js file will have access to the chrome event but it doesn't have access to DOM and hence cant manipulate it. If we can find some way to trigger content.js from background.js we will be able to achieve the desired behavior.
Message Passing
Message Passing is way of communicating between background scripts and content scripts. It allows us to fire events from background scripts and apply event listeners on content scripts and vice versa. We first fire an event whenever our extension's icon is clicked on tool bar. We will use chrome's Browser Action API to listen to clicks and then fire our event. Add the following in background.js :
// Called when the user clicks on extension icon chrome.browserAction.onClicked.addListener(function (tab) { chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) { const activeTab = tabs[0]; // Send a message to the active tab chrome.tabs.sendMessage(activeTab.id, { "message": "start_fetching_ratings" }); }); });
We listening to browserAction.onClicked and then firing a payload to active tab where our content.js is running. Lets replace content.js with an event listener :
chrome.runtime.onMessage.addListener( function (request, sender, sendResponse) { if (request.message === "start_fetching_ratings") { alert("Message Received!") } } );
Reload the extension and test it out.
Tumblr media
Message received ! So we have found way to pass on trigger from background to foreground. The final flow becomes chrome event> background.js > content.js. Finally we can incorporate our logic inside the event handler so our final content.js becomes :
chrome.runtime.onMessage.addListener( function (request, sender, sendResponse) { if (request.message === "start_fetching_ratings") { fetchRatings() } } ); const fetchRatings = () => { $(".media-lists__td-title").map(async function () { const name = this.innerText; const response = await fetch(`https://www.omdbapi.com/?t=${name}&apikey=e48e70b4`) const {imdbRating} = await response.json() this.innerText = `${name} (${imdbRating})` }) }
Lets test our final product.
Tumblr media
This is it. We have built the extension we wanted.
Conclusion
Browser extensions are extremely powerful and can change the way we browse internet. Some really successfully companies today started out as an extension. In this article we learnt how to build a background extension, how to build an extension which manipulates UI and how to build hybrid extension by communicating between the two. The complete code can be found here.
0 notes
mbaljeetsingh · 6 years ago
Text
Intro to Electron.js - Part 2: Todo App
Over in the first part of this introduction to Electron.js, we just got Electron setup with our bundling scripts and a local window. With the foundations out of the way, we can get started with the more interesting functionality of our app.
Passing Data Between Client and Server
Since we’re not setup with a database yet, the todo functionality is almost the same as any vanilla JavaScript todo app. The only difference being we’ll first use ipcRenderer.send to send an event to our server with our data, which we can listen for with ipcMain.on, then do whatever we need to with the data (like save it to our database), and send it back to the client to be rendered if successful.
script.js
const electron = require('electron') const { ipcRenderer } = electron const form = document.querySelector('form') const item = document.querySelector('input') const list = document.querySelector('ul') // Render Items to Screen const render = item => { const li = document.createElement('li') li.innerHTML = item list.appendChild(li) } // Get All Items After Starting window.addEventListener('load', () => ipcRenderer.send('loadAll')) ipcRenderer.on('loaded', (e, items) => items.forEach(item => render(item.item))) // Send Item to the server and clear the form form.addEventListener('submit', e => { e.preventDefault() ipcRenderer.send('addItem', { item: item.value }) form.reset() })
Next we just need to start a new database with Datastore and use some mongoose-like methods when we catch our events from the client.
Instead of a method on ipcMain, as you may expect, we need to use webcontents.send on the window we want it applied to. Later this will also allow us to send events from our menu without destructuring anything from electron.
NeDB gives us many of the same options as Mongoose does for manipulating and querying our data. I strongly recommend looking at the docs since there are some differences between Nedb and Mongoose.
The main methods that we need just take an object with the properties you want the return item to match, and a callback function for when it’s complete.
insert Takes the new item as an object and adds it to the database.
remove Takes the query, and object of options, and removes from the database.
find Takes the query and returns the objects.
update Takes the query and an object of properties you want updated.
app.js
const db = new Datastore({ filename: './items.db', autoload: true }) // Get all items from db and send them to the client ipcMain.on('loadAll', () => db.find({}, (err, items) => mainWindow.webContents.send('loaded', items))) // Saves item and returns it to client ipcMain.on('addItem', (e, item) => { db.insert(item, err => { if (err) throw new Error(err) }) mainWindow.webContents.send('added', item) })
Menu Bar
Now we can start adding some more interesting functionality into our menu bar. For every object in our array we have a few options to customize it.
label Set the name shown on the menu bar
submenu Sets and array of objects as a sub directory, these can go on infinitely.
click Sets an onClick handler, takes in itself and the current focused window.
accelerator Sets any keyboard shortcuts, we can use process.platform to check what OS is being used, since Mac and Windows have a few different keys.
type Set menu item as one of electrons preset formats; normal, separator, checkbox, and radio.
Along with our file menu, we’re going to add the option to toggle the dev tools to help debug our application.
MenuBar.js
const menuBar = [ { label: 'file', submenu: [ { label: 'Clear All', accelerator: process.platform == 'darwin' ? 'Command+C' : 'Ctrl+C', click(item, currentWindow) { currentWindow.webContents.send('clearAll') } } ] }, { label: 'DevTools', accelerator: process.platform == 'darwin' ? 'Command+I' : 'Ctrl+I', click(item, mainWindow) { mainWindow.toggleDevTools() } } ]
With the cleared event being sent, we can clear our ul.
script.js
// Catches ClearAll from menu, sends the event to server to clear the db. ipcRenderer.on('clearAll', () => ipcRenderer.send('clearAll')) ipcRenderer.on('cleared', () => list.innerHTML = '')
app.js
// Clears database and send event to client if successful ipcMain.on('clearAll', () => { // Without multi being set to true only the first matching item with be removed. db.remove({}, { multi: true }, (err) => { if (err) throw new Error(err) mainWindow.webContents.send('cleared') }) })
Bundling
Before we can bundle our new app we need some icons to go with it, but they need to be in the right formats for their operating system. icns for Mac and Linux and ico for Windows. I recommend using Cloud Convert to do this.
When they’re all in the correct locations you can just run their script from our package.json file and a new release-builds folder should be created. In your OS’s folder you can find your new application ready to run natively on your machine.
$ npm run package-mac $ npm run package-win $ npm run package-linux
Conclusion
While this may have been a bit of a lengthy process, I hope that you found this helpful in understanding the fundamentals of building your own desktop apps using Electron. You can find the full repo for this example here.
via Alligator.io https://ift.tt/2KTIlJ7
0 notes
mbaljeetsingh · 8 years ago
Text
Creating One Browser Extension For All Browsers: Edge, Chrome, Firefox, Opera, Brave And Vivaldi
In today’s article, we’ll create a JavaScript extension that works in all major modern browsers, using the very same code base. Indeed, the Chrome extension model based on HTML, CSS and JavaScript is now available almost everywhere, and there is even a Browser Extension Community Group1 working on a standard.
I’ll explain how you can install this extension that supports the web extension model (i.e. Edge, Chrome, Firefox, Opera, Brave and Vivaldi), and provide some simple tips on how to get a unique code base for all of them, but also how to debug in each browser.
Note: We won’t cover Safari in this article because it doesn’t support the same extension model2 as others.
Further Reading on SmashingMag: Link
I won’t cover the basics of extension development because plenty of good resources are already available from each vendor:
So, if you’ve never built an extension before or don’t know how it works, have a quick look at those resources. Don’t worry: Building one is simple and straightforward.
Our Extension Link
Let’s build a proof of concept — an extension that uses artificial intelligence (AI) and computer vision to help the blind analyze images on a web page.
We’ll see that, with a few lines of code, we can create some powerful features in the browser. In my case, I’m concerned with accessibility on the web and I’ve already spent some time thinking about how to make a breakout game accessible using web audio and SVG14, for instance.
Still, I’ve been looking for something that would help blind people in a more general way. I was recently inspired while listening to a great talk by Chris Heilmann15 in Lisbon: “Pixels and Hidden Meaning in Pixels16.”
Indeed, using today’s AI algorithms in the cloud, as well as text-to-speech technologies, exposed in the browser with the Web Speech API17 or using a remote cloud service, we can very easily build an extension that analyzes web page images with missing or improperly filled alt text properties.
My little proof of concept simply extracts images from a web page (the one in the active tab) and displays the thumbnails in a list. When you click on one of the images, the extension queries the Computer Vision API to get some descriptive text for the image and then uses either the Web Speech API or Bing Speech API to share it with the visitor.
The video below demonstrates it in Edge, Chrome, Firefox, Opera and Brave.
youtube
You’ll notice that, even when the Computer Vision API is analyzing some CGI images, it’s very accurate! I’m really impressed by the progress the industry has made on this in recent months.
I’m using these services:
Computer Vision API18, Microsoft Cognitive Services This is free to use19 (with a quota). You’ll need to generate a free key; replace the TODO section in the code with your key to make this extension work on your machine. To get an idea of what this API can do, play around with it20.
21
Bing Text to Speech API22, Microsoft Cognitive Services This is also free to use23 (with a quota, too). You’ll need to generate a free key again. We’ll also use a small library24 that I wrote recently to call this API from JavaScript. If you don’t have a Bing key, the extension will always fall back to the Web Speech API, which is supported by all recent browsers.
But feel free to try other similar services:
You can find the code for this small browser extension on my GitHub page27. Feel free to modify the code for other products you want to test.
Tip To Make Your Code Compatible With All Browsers Link
Most of the code and tutorials you’ll find use the namespace chrome.xxx for the Extension API (chrome.tabs, for instance).
But, as I’ve said, the Extension API model is currently being standardized to browser.xxx, and some browsers are defining their own namespaces in the meantime (for example, Edge is using msBrowser).
Fortunately, most of the API remains the same behind the browser. So, it’s very simple to create a little trick to support all browsers and namespace definitions, thanks to the beauty of JavaScript:
window.browser = (function () { return window.msBrowser || window.browser || window.chrome; })();
And voilà!
Of course, you’ll also need to use the subset of the API supported by all browsers. For instance:
Extension Architecture Link
Let’s review together the architecture of this extension. If you’re new to browser extensions, this should help you to understand the flow.
Let’s start with the manifest file31:
32
(View large version33)
This manifest file and its associated JSON is the minimum you’ll need to load an extension in all browsers, if we’re not considering the code of the extension itself, of course. Please check the source34 in my GitHub account, and start from here to be sure that your extension is compatible with all browsers.
For instance, you must specify an author property to load it in Edge; otherwise, it will throw an error. You’ll also need to use the same structure for the icons. The default_title property is also important because it’s used by screen readers in some browsers.
Here are links to the documentation to help you build a manifest file that is compatible everywhere:
The sample extension used in this article is mainly based on the concept of the content script38. This is a script living in the context of the page that we’d like to inspect. Because it has access to the DOM, it will help us to retrieve the images contained in the web page. If you’d like to know more about what a content script is, Opera39, Mozilla40 and Google41 have documentation on it.
Our content script42 is simple:
43
(View large version44)
console.log("Dare Angel content script started"); browser.runtime.onMessage.addListener(function (request, sender, sendResponse) { if (request.command == "requestImages") { var images = document.getElementsByTagName('img'); var imagesList = []; for (var i = 0; i < images.length; i++) { if ((images[i].src.toLowerCase().endsWith(".jpg") || images[i].src.toLowerCase().endsWith(".png")) && (images[i].width > 64 && images[i].height > 64)) { imagesList.push({ url: images[i].src, alt: images[i].alt }); } } sendResponse(JSON.stringify(imagesList)); } }); view raw
This first logs into the console to let you check that the extension has properly loaded. Check it via your browser’s developer tool, accessible from F12, Control + Shift + I or ⌘ + ⌥ + I.
It then waits for a message from the UI page with a requestImages command to get all of the images available in the current DOM, and then it returns a list of their URLs if they’re bigger than 64 × 64 pixels (to avoid all of the pixel-tracking junk and low-resolution images).
45
(View large version46)
The popup UI page47 we’re using is very simple and will display the list of images returned by the content script inside a flexbox container48. It loads the start.js script, which immediately creates an instance of dareangel.dashboard.js49 to send a message to the content script to get the URLs of the images in the currently visible tab.
Here’s the code that lives in the UI page, requesting the URLs to the content script:
browser.tabs.query({ active: true, currentWindow: true }, (tabs) => { browser.tabs.sendMessage(tabs[0].id, { command: "requestImages" }, (response) => { this._imagesList = JSON.parse(response); this._imagesList.forEach((element) => { var newImageHTMLElement = document.createElement("img"); newImageHTMLElement.src = element.url; newImageHTMLElement.alt = element.alt; newImageHTMLElement.tabIndex = this._tabIndex; this._tabIndex++; newImageHTMLElement.addEventListener("focus", (event) => { if (COMPUTERVISIONKEY !== "") { this.analyzeThisImage(event.target.src); } else { var warningMsg = document.createElement("div"); warningMsg.innerHTML = "
Please generate a Computer Vision key in the other tab. Link
"; this._targetDiv.insertBefore(warningMsg, this._targetDiv.firstChild); browser.tabs.create({ active: false, url: "http://ift.tt/2p05YSn" }); } }); this._targetDiv.appendChild(newImageHTMLElement); }); }); });
We’re creating image elements. Each image will trigger an event if it has focus, querying the Computer Vision API for review.
This is done by this simple XHR call:
analyzeThisImage(url) { var xhr = new XMLHttpRequest(); xhr.onreadystatechange = () => { if (xhr.readyState == 4 && xhr.status == 200) { var response = document.querySelector('#response'); var reponse = JSON.parse(xhr.response); var resultToSpeak = `With a confidence of ${Math.round(reponse.description.captions[0].confidence * 100)}%, I think it's ${reponse.description.captions[0].text}`; console.log(resultToSpeak); if (!this._useBingTTS || BINGSPEECHKEY === "") { var synUtterance = new SpeechSynthesisUtterance(); synUtterance.text = resultToSpeak; window.speechSynthesis.speak(synUtterance); } else { this._bingTTSclient.synthesize(resultToSpeak); } } }; xhr.onerror = (evt) => { console.log(evt); }; try { xhr.open('POST', 'http://ift.tt/2o2AsFP'); xhr.setRequestHeader("Content-Type", "application/json"); xhr.setRequestHeader("Ocp-Apim-Subscription-Key", COMPUTERVISIONKEY); var requestObject = { "url": url }; xhr.send(JSON.stringify(requestObject)); } catch (ex) { console.log(ex); } } view raw
The following articles will you help you to understand how this Computer Vision API works:
“Analyzing an Image Version 1.050,” Microsoft Cognitive Services
“Computer Vision API, v1.051,” Microsoft Cognitive Services This shows you via an interactive console in a web page how to call the REST API with the proper JSON properties, and the JSON object you’ll get in return. It’s useful to understand how it works and how you will call it.
In our case, we’re using the describe feature of the API. You’ll also notice in the callback that we will try to use either the Web Speech API or the Bing Text-to-Speech service, based on your options.
Here, then, is the global workflow of this little extension:
52
(View large version53)
Loading The Extension In Each Browser Link
Let’s review quickly how to install the extension in each browser.
Prerequisites Link
Download or clone my small extension54 from GitHub somewhere to your hard drive.
Also, modify dareangel.dashboard.js to add at least a Computer Vision API key. Otherwise, the extension will only be able to display the images extracted from the web page.
Microsoft Edge Link
First, you’ll need at least a Windows 10 Anniversary Update (OS Build 14393+) to have support for extensions in Edge.
Then, open Edge and type about:flags in the address bar. Check the “Enable extension developer features.”
55
Click on “…” in the Edge’s navigation bar and then “Extensions” and then “Load extension,” and select the folder where you’ve cloned my GitHub repository. You’ll get this:
56
Click on this freshly loaded extension, and enable “Show button next to the address bar.”
57
Note the “Reload extension” button, which is useful while you’re developing your extension. You won’t be forced to remove or reinstall it during the development process; just click the button to refresh the extension.
Navigate to BabylonJS626158, and click on the Dare Angel (DA) button to follow the same demo as shown in the video.
Google Chrome, Opera, Vivaldi Link
In Chrome, navigate to chrome://extensions. In Opera, navigate to opera://extensions. And in Vivaldi, navigate to vivaldi://extensions. Then, enable “Developer mode.”
Click on “Load unpacked extension,” and choose the folder where you’ve extracted my extension.
59
(View large version60)
Navigate to BabylonJS626158, and open the extension to check that it works fine.
Mozilla Firefox Link
You’ve got two options here. The first is to temporarily load your extension, which is as easy as it is in Edge and Chrome.
Open Firefox, navigate to about:debugging and click “Load Temporary Add-on.” Then, navigate to the folder of the extension, and select the manifest.json file. That’s it! Now go to BabylonJS626158 to test the extension.
63
(View large version64)
The only problem with this solution is that every time you close the browser, you’ll have to reload the extension. The second option would be to use the XPI packaging. You can learn more about this in “Extension Packaging65” on the Mozilla Developer Network.
The public version of Brave doesn’t have a “developer mode” embedded in it to let you load an unsigned extension. You’ll need to build your own version of it by following the steps in “Loading Chrome Extensions in Brave66.”
As explained in that article, once you’ve cloned Brave, you’ll need to open the extensions.js file in a text editor. Locate the lines below, and insert the registration code for your extension. In my case, I’ve just added the two last lines:
// Manually install the braveExtension and torrentExtension extensionInfo.setState(config.braveExtensionId, extensionStates.REGISTERED) loadExtension(config.braveExtensionId, getExtensionsPath('brave'), generateBraveManifest(), 'component') extensionInfo.setState('DareAngel', extensionStates.REGISTERED) loadExtension('DareAngel', getExtensionsPath('DareAngel/')) view raw
Copy the extension to the app/extensions folder. Open two command prompts in the browser-laptop folder. In the first one, launch npm run watch, and wait for webpack to finish building Brave’s Electron app. It should say, “webpack: bundle is now VALID.” Otherwise, you’ll run into some issues.
67
(View large version68)
Then, in the second command prompt, launch npm start, which will launch our slightly custom version of Brave.
In Brave, navigate to about:extensions, and you should see the extension displayed and loaded in the address bar.
69
(View large version70)
Debugging The Extension In Each Browser Link
Tip for all browsers: Using console.log(), simply log some data from the flow of your extension. Most of the time, using the browser’s developer tools, you’ll be able to click on the JavaScript file that has logged it to open it and debug it.
Microsoft Edge Link
To debug the client script part, living in the context of the page, you just need to open F12. Then, click on the “Debugger” tab and find your extension’s folder.
Open the script file that you’d like to debug — dareangel.client.js, in my case — and debug your code as usual, setting up breakpoints, etc.
71
(View large version72)
If your extension creates a separate tab to do its job (like the Page Analyzer73, which our Vorlon.js74 team published in the store), simply press F12 on that tab to debug it.
75
(View large version76)
If you’d like to debug the popup page, you’ll first need to get the ID of your extension. To do that, simply go into the property of the extension and you’ll find an ID property:
77
Then, you’ll need to type in the address bar something like http://ms-browser-extensionID_of_your_extension/yourpage.html. In our case, it would be http://ms-browser-extensionDareAngel_vdbyzyarbfgh8/dashboard.html. Then, simply use F12 on this page:
78
(View large version79)
Google Chrome, Opera, Vivaldi, Brave Link
Because Chrome and Opera rely on the same Blink code base, they share the same debugging process. Even though Brave and Vivaldi are forks of Chromium, they also share the same debugging process most of the time.
To debug the client script part, open the browser’s developer tools on the page that you’d like to debug (pressing F12, Control + Shift + I or ⌘ + ⌥ + I, depending on the browser or platform you’re using).
Then, click on the “Content scripts” tab and find your extension’s folder. Open the script file that you’d like to debug, and debug your code just as you would do with any JavaScript code.
80
(View large version81)
To debug a tab that your extension would create, it’s exactly the same as with Edge: Simply use the developer tools.
82
(View large version83)
For Chrome and Opera, to debug the popup page, right-click on the button of your extension next to the address bar and choose “Inspect popup,” or open the HTML pane of the popup and right-click inside it to “Inspect.” Vivaldi only supports right-click and then “Inspect” inside the HTML pane once opened.
84
(View large version85)
For Brave, it’s the same process as with Edge. You first need to find the GUID associated with your extension in about:extensions:
86
And then, in a separate tab, open the page you’d like to debug like — in my case, chrome-extension://bodaahkboijjjodkbmmddgjldpifcjap/dashboard.html — and open developer tools.
87
(View large version88)
For the layout, you have a bit of help using Shift + F8, which will let you inspect the complete frame of Brave. And you’ll discover that Brave is an Electron app using React!
Note, for instance, the data-reactroot attribute.
89
(View large version90)
Note: I had to slightly modify the CSS of the extension for Brave because it currently displays popups with a transparent background by default, and I also had some issues with the height of my images collection. I’ve limited it to four elements in Brave.
Mozilla Firefox Link
Mozilla has really great documentation on debugging web extensions91.
For the client script part, it’s the same as in Edge, Chrome, Opera and Brave. Simply open the developer tools in the tab you’d like to debug, and you’ll find a moz-extension://guid section with your code to debug:
92
(View large version93)
If you need to debug a tab that your extension would create (like Vorlon.js’ Page Analyzer extension), simply use the developer tools:
94
(View large version95)
Finally, debugging a popup is a bit more complex but is well explained in the “Debugging Popups96” section of the documentation.
97
(View large version98)
Publishing Your Extension In Each Store Link
Each vendor has detailed documentation on the process to follow to publish your extension in its store. They all take similar approaches. You need to package the extension in a particular file format — most of the time, a ZIP-like container. Then, you have to submit it in a dedicated portal, choose a pricing model and wait for the review process to complete. If accepted, your extension will be downloadable in the browser itself by any user who visits the extensions store.
Here are the various processes:
Please note that submitting a Microsoft Edge extension to the Windows Store is currently a restricted capability. Reach out to the Microsoft Edge team103 with your request to be a part of the Windows Store, and they’ll consider you for a future update.
I’ve tried to share as much of what I’ve learned from working on our Vorlon.js Page Analyzer extension104 and this little proof of concept.
Some developers remember the pain of working through various implementations to build their extension — whether it meant using different build directories, or working with slightly different extension APIs, or following totally different approaches, such as Firefox’s XUL extensions or Internet Explorer’s BHOs and ActiveX.
It’s awesome to see that, today, using our regular JavaScript, CSS and HTML skills, we can build great extensions using the very same code base and across all browsers!
Feel free to ping me on Twitter105 for any feedback.
(ms, vf, rb, yk, al, il)
1 http://ift.tt/2c92Ku0
2 http://ift.tt/2o2wVqV
3 http://ift.tt/2p0aEHR
4 http://ift.tt/2dIoRta
5 http://ift.tt/2fCP0pv
6 http://ift.tt/2p0dpce
7 http://ift.tt/1jjUVLU
8 http://ift.tt/1T113ur
9 http://ift.tt/2p0t0Zn
10 http://ift.tt/1YveJBe
11 http://ift.tt/1UQrtjh
12 http://ift.tt/2gHVCSM
13 http://ift.tt/2hNeF2P
14 http://ift.tt/2gHWAOO
15 https://twitter.com/codepo8
16 https://www.youtube.com/watch?v=TWVNTsdm27U
17 http://ift.tt/1dNKMBR
18 http://ift.tt/1RtTMEa
19 http://ift.tt/2a8as7R
20 http://ift.tt/1SxHPMI
21 http://ift.tt/2p060tt
22 http://ift.tt/1RtTLA3
23 http://ift.tt/2gHX47s
24 http://ift.tt/2hNo1Ma
25 http://ift.tt/21w7H0F
26 http://ift.tt/1PvX9e4
27 http://ift.tt/2gHVZg4
28 http://ift.tt/2fcSXl6
29 http://ift.tt/1YveJBe
30 http://ift.tt/2o2vMj2
31 http://ift.tt/2gHKntv
32 http://ift.tt/2p0f4i2
33 http://ift.tt/2p0f4i2
34 http://ift.tt/2gHKntv
35 http://ift.tt/1h5wgHa
36 http://ift.tt/2chO3Bf
37 http://ift.tt/1LOrqNJ
38 http://ift.tt/2o2BDEZ
39 http://ift.tt/2o2B6mG
40 http://ift.tt/2ghy3l7
41 http://ift.tt/1oP0nqO
42 http://ift.tt/2gI0M0N
43 http://ift.tt/2o2D5HB
44 http://ift.tt/2o2D5HB
45 http://ift.tt/2o2U10H
46 http://ift.tt/2o2U10H
47 http://ift.tt/2hNhYXU
48 http://ift.tt/2gHWVAU
49 http://ift.tt/2hNotdf
50 http://ift.tt/2gHX4nY
51 http://ift.tt/24mPQNz
52 http://ift.tt/2p0aBf9
53 http://ift.tt/2p0aBf9
54 http://ift.tt/2gHSt5f
55 http://ift.tt/2o2vGYR
56 http://ift.tt/2o2F4f0
57 http://ift.tt/2o2xNMg
58 http://ift.tt/1aUDteS
59 http://ift.tt/2p0lmOP
60 http://ift.tt/2p0lmOP
61 http://ift.tt/1aUDteS
62 http://ift.tt/1aUDteS
63 http://ift.tt/2o2GW7p
64 http://ift.tt/2o2GW7p
65 http://ift.tt/1N7jLzi
66 http://ift.tt/2jHIv6F
67 http://ift.tt/2o2z9GX
68 http://ift.tt/2o2z9GX
69 http://ift.tt/2o2Av4t
70 http://ift.tt/2o2Av4t
71 http://ift.tt/2p0aG2r
72 http://ift.tt/2p0aG2r
73 http://ift.tt/2hNo7n0
74 http://www.vorlonjs.io/
75 http://ift.tt/2o2Ev57
76 http://ift.tt/2o2Ev57
77 http://ift.tt/2o2xQaU
78 http://ift.tt/2o2AxcB
79 http://ift.tt/2o2AxcB
80 http://ift.tt/2p0a39p
81 http://ift.tt/2p0a39p
82 http://ift.tt/2p0g9GG
83 http://ift.tt/2p0g9GG
84 http://ift.tt/2p0aGiX
85 http://ift.tt/2p0aGiX
86 http://ift.tt/2p0miCv
87 http://ift.tt/2o2BEZz
88 http://ift.tt/2o2BEZz
89 http://ift.tt/2o2lqjs
90 http://ift.tt/2o2lqjs
91 http://ift.tt/2hNtouy
92 http://ift.tt/2o2Ndjv
93 http://ift.tt/2o2Ndjv
94 http://ift.tt/2o2xOzO
95 http://ift.tt/2o2xOzO
96 http://ift.tt/2hNtouy
97 http://ift.tt/2p0pJct
98 http://ift.tt/2p0pJct
99 http://ift.tt/1lOuIFz
100 http://ift.tt/2khtL1F
101 http://ift.tt/2p0okml
102 http://ift.tt/2p0m7HB
103 http://ift.tt/1T1115G
104 http://ift.tt/2hNo7n0
105 https://twitter.com/davrous
↑ Back to top Tweet itShare on Facebook
via Smashing Magazine http://ift.tt/2o9DF6N
0 notes