‘Live News’ Extension for Google Chrome using SAPUI5
Building a Chrome Extension using SAPUI5
We are going to create a simple Chrome Extension which displays live news from various news providers across the globe. For the News APIs, create your account in https://newsapi.org/and get your API key in order to get the API response.
To build a Chrome Extension, the very first thing we’ll need to create is a manifest file named manifest.json
. This manifest is nothing more than a metadata file in JSON format that contains properties like your extension’s name, description, version number and so on. At a high level, we will use it to declare to Chrome what the extension is going to do, and what permissions it requires in order to do those things. To learn more about the manifest, read the Manifest File Format documentation.
Create a manifest.json file and save it to your local drive with below contents. Please note, We need to inject SAPUI5 bootstrap in our index.html file using CDN but you cannot simply include an external script file in your extension pages. This would violate the default Content Security Policy.
For a script served over https
, it’s possible to relax the policy; but http
origins are forbidden for security reasons: it’s too easy to intercept the request and inject malicious code.
{
"manifest_version": 2,
"name": "News Extension for Chrome using SAPUI5",
"description": "This extension shows latest News feeds from various News providers",
"version": "1.0",
"browser_action": {
"default_icon": "sap-ui5.png",
"default_popup": "popup.html"
},
"content_security_policy": "script-src 'self' 'unsafe-eval' https://sapui5.hana.ondemand.com/resources/sap-ui-core.js; object-src 'self'",
"permissions": [
"activeTab",
"https://sapui5.hana.ondemand.com/"
]
}
We declared a browser action, the activeTab permission to see the URL of the current tab, and the host permission to access the external SAPUI5 bootstrap.
You probably noticed that manifest.json
pointed at two resource files when defining the browser action: sap-ui5.png
and popup.html
. Both resources must exist inside the extension package, so let’s create them now:
sap-ui5.png
will be displayed next to the Omnibox, waiting for user interaction. I have download icon image from here and saved it to local project folder with namesap-ui5.png
popup.html
will be rendered inside the popup window that’s created in response to a user’s click on the browser action. It’s a standard HTML file, just like you’re used to from web development, giving you more or less free reign over what the popup displays.
Below is the code for this file, which is simple bootstrapping of SAPUI5 and one injected popup.js file with some basic css styling.
<!doctype html>
<!--
This page is shown when the extension button is clicked, because the
"browser_action" field in manifest.json contains the "default_popup" key with
value "popup.html".
-->
<html>
<head>
<title>News Extension for Chrome using SAPUI5</title>
<style>
html{
width: 450px;
height: 500px;
}
body {
font-family: "Segoe UI", "Lucida Grande", Tahoma, sans-serif;
font-size: 100%;
width: 450px;
height: 500px;
}
.myCustomChannelLogo{
border-radius: 50%;
}
.sapMNav.sapMSplitContainerMaster{
width: 20%;
}
.sapMLIB.sapMLIBSelected {
background: #5cc7b2;
}
</style>
<!--
- JavaScript and HTML must be in separate files: see our Content Security
- Policy documentation[1] for details and explanation.
-
- [1]: https://developer.chrome.com/extensions/contentSecurityPolicy
-->
<script id="sap-ui-bootstrap"
type="text/javascript"
src="https://sapui5.hana.ondemand.com/resources/sap-ui-core.js"
data-sap-ui-theme="sap_belize"
data-sap-ui-libs="sap.m"></script>
<script src="popup.js"></script>
</head>
<body class= "sapUiBody">
<div id="content"></div>
</body>
</html>
The actual logic of rendering the content of the popup is implemented by popup.js. (Refer to below Code).
sap.ui.getCore().attachInit(function(){
var oList = new sap.m.List();
var oItem = new sap.m.StandardListItem({
title: "{title}",
description:"{description}",
info: "{author}"
});
var oJSONDataModel = new sap.ui.model.json.JSONModel('https://newsapi.org/v1/articles?source=the-new-york-times&sortBy=top&apiKey=YOUR_API_KEY');
oList.setModel(oJSONDataModel);
oList.bindItems('/articles',oItem);
var oDPage1 = new sap.m.Page({
title: "My News App",
headerContent:[
new sap.m.Button({
icon:"sap-icon://home",
type:"Accept",
press:function(){
var oJSONDataModel = new sap.ui.model.json.JSONModel('https://newsapi.org/v1/articles?source=the-new-york-times&sortBy=top&apiKey=YOUR_API_KEY');
oList.setModel(oJSONDataModel);
oList.bindItems('/articles',oItem);
}
})
],
content:[
new sap.m.FlexBox({
items:[
new sap.m.VBox({
width: "100%",
items:[
oList
],
alignItems: "Center",
justifyContent:"Center",
backgroundDesign: "Solid"
})
],
alignItems: "Center",
justifyContent: "Center"
})
]
});
var oList2 = new sap.m.List('mList',{
mode: sap.m.ListMode.SingleSelectMaster ,
selectionChange : function(e) {
if (this._prevSelect) {
this._prevSelect.$().css('background-color', '');
}
var item = e.getParameter('listItem');
item.$().css('background-color', '#5cc7b2');
this._prevSelect = item;
if(item.sId == '__item1-mList-0'){
var oJSONDataModel = new sap.ui.model.json.JSONModel(' https://newsapi.org/v1/articles?source=the-new-york-times&sortBy=top&apiKey=YOUR_API_KEY');
oList.setModel(oJSONDataModel);
oList.bindItems('/articles',oItem);
}
else if (item.sId == '__item1-mList-1'){
var oJSONDataModel = new sap.ui.model.json.JSONModel('https://newsapi.org/v1/articles?source=bbc-news&sortBy=top&apiKey=YOUR_API_KEY');
oList.setModel(oJSONDataModel);
oList.bindItems('/articles',oItem);
}
else if (item.sId == '__item1-mList-2'){
var oJSONDataModel = new sap.ui.model.json.JSONModel('https://newsapi.org/v1/articles?source=daily-mail&sortBy=top&apiKey=YOUR_API_KEY');
oList.setModel(oJSONDataModel);
oList.bindItems('/articles',oItem);
}
else if (item.sId == '__item1-mList-3'){
var oJSONDataModel = new sap.ui.model.json.JSONModel('https://newsapi.org/v1/articles?source=the-times-of-india&sortBy=top&apiKey=YOUR_API_KEY');
oList.setModel(oJSONDataModel);
oList.bindItems('/articles',oItem);
}
else if (item.sId == '__item1-mList-4'){
var oJSONDataModel = new sap.ui.model.json.JSONModel('https://newsapi.org/v1/articles?source=the-hindu&sortBy=top&apiKey=YOUR_API_KEY');
oList.setModel(oJSONDataModel);
oList.bindItems('/articles',oItem);
}
},
updateFinished : function(oEvent){
var firstItem = sap.ui.getCore().byId("mList").getItems()[0];
sap.ui.getCore().byId("mList").setSelectedItem(firstItem,true);
}
});
var oItem2 = new sap.m.CustomListItem({
content:[
new sap.m.HBox({
items:[
new sap.m.Image({
width: "80%",
height: "80%",
src: "{channelLogo}"
}).addStyleClass("myCustomChannelLogo")
],
alignItems: "Center",
justifyContent: "Center"
})
],
press:function(){
alert();
}
});
var oJSONDataModel2 = new sap.ui.model.json.JSONModel("channels.json");
//oJSONDataModel2.loadData();
oList2.setModel(oJSONDataModel2);
oList2.bindItems('/',oItem2);
var oMPage1 = new sap.m.Page({
title: "Channels",
content:[
oList2
]
});
var app = new sap.m.SplitApp("app1",{
detailPages:[
oDPage1
],
masterPages:[
oMPage1
]
});
app.placeAt("content");
});
Replace YOUR_API_KEY with key you got from https://newsapi.org/ after successful creation of account.
One local file channels.json was created to get list of news channels. It’s contents are-
[
{
"channelName" : "New York Times",
"channelLogo" : "https://cdn1.nyt.com/mw-static/images/touch-icon-ipad-144.319373aa.png"
},
{
"channelName" : "BBC",
"channelLogo" : "http://m.files.bbci.co.uk/modules/bbc-morph-news-waf-page-meta/1.2.0/apple-touch-icon.png"
},
{
"channelName" : "Daily Mail",
"channelLogo" : "http://www.dailymail.co.uk/apple-touch-icon.png"
},
{
"channelName" : "Times of India",
"channelLogo" : "https://3.bp.blogspot.com/-NaKhQfcARS8/V6mkOa5dZOI/AAAAAAAA4JI/1wgXfCJeyuIkLPXxzTCqlyruuNRlNdZuQCLcB/s1600/TOI_Logo.png"
},
{
"channelName" : "The Hindu",
"channelLogo" : "https://store-images.s-microsoft.com/image/apps.38416.9007199266250907.217cbcfc-4852-43d4-b3af-766d136f85fa.6ce717fa-8786-45ed-9bfc-ebc414691daa?w=180&h=180&q=60"
}
]
So finally your local project folder will look like this, with below 5 files-
- channels.json
- manifest.json
- popup.html
- popup.js
- sap-ui5.png
That’s it. We have our Chrome extension. Let’s load it in our browser. To load the extension, Chrome gives you a quick way of loading up your working directory for testing. Let’s do that now.
- Visit
chrome://extensions
in your browser (or open up the Chrome menu by clicking the icon to the far right of the Omnibox:and select Extensions under the Tools menu to get to the same place).
- Ensure that the Developer mode checkbox in the top right-hand corner is checked.
- Click Load unpacked extension… to pop up a file-selection dialog.
- Navigate to the directory in which your extension files live, and select it.
Alternatively, you can drag and drop the directory where your extension files live onto chrome://extensions
in your browser to load it.
If the extension is valid, it’ll be loaded up and active right away! If it’s invalid, an error message will be displayed at the top of the page. Correct the error, and try again.
Finally you are going to see one new extension added in your brower. Click on it and get the live news feed.
Preview-
1. New Added Extension
2. After Click on Extension
3. Channels list
Code Repository: https://github.com/3bhu1/chrome-extension-using-SAPUI5
Reference: https://developer.chrome.com/extensions/getstarted