Google Chrome, Javascript, NodeJS, Opera

Video – Memory Management Masterclass with Addy Osmani

Really good video on managing memory using Google Chrome Dev Tools.
From YouTube:Published on Sep 2, 2014

Addy is a senior engineer on the Chrome web engineering team, focusing on tools to help improve developer productivity and satisfaction. He works on Polymer – a Web Component library, is the the lead engineer on Yeoman and Web Starter Kit and regularly writes about web application architecture and the front-end. Outside of Google, Addy enjoys both hacking on open-source projects like TodoMVC and Grunt-UnCSS. He has authored books on JavaScript design patterns and frameworks.

Efficient JavaScript webapps need to be fluid and fast. Any app with significant user interaction needs to consider how to effectively keep memory usage down because if too much is consumed, a page might be killed, forcing the user to reload it and cry in a corner. Automatic garbage collection isn’t a substitute for effective memory management, especially in large, long-running web apps. In this talk we’ll walk through how to master the Chrome DevTools for effective memory management. Learn how to tackle performance issues like memory leaks, frequent garbage collection pauses, and overall memory bloat that can really drag you down.


Standard
Browser Extension, Google Chrome, Javascript, Look-It-Up, Opera

Google Chrome and Opera Extension – Look-it-up, a Dictionary Context Menu Extension

Adds context menu item that looks up selected text on dictionary sites. You have the choice of dictionary.com, merriam-webster.com (dictionary and thesaurus), thefreedictionary.com, thesaurus.com, urbandictionary.com, wikipedia.org, wiktionary.org, and yourdictionary.com to look selected terms up with. There is an options page to enable or disable the different menu items included. This is actually a rewrite and improvement of an older version that looked up terms on dictionary.com exclusively. While using the old version, I eventually found myself in need of more options for this add-on so here it is.
 

manifest.json


{
  "name": "Look-it-up",
  "description": "Adds context menu item that looks up selected text on dictionary sites",
  "version": "0.2",
  "permissions": ["contextMenus"],
  "background": {
    "scripts": ["app.js"]
  },
  "options_page": "options.html",
  "icons" : {
        "16" : "book16.png",
        "32" : "book32.png",
        "48" : "book48.png",
        "128" : "book128.png"
    },
  "manifest_version": 2
}

app.js


/** app.js */
var defaultentries = [
	{
	"menu":"dictionary.com",
	"active":1
	},{
	"menu":"merriam-webster.com-dict",
	"active":1
	},{
	"menu":"merriam-webster.com-thes",
	"active":1
	},{
	"menu":"thefreedictionary.com",
	"active":1
	},{
	"menu":"thesaurus.com",
	"active":1
	},{
	"menu":"urbandictionary.com",
	"active":1
	},{
	"menu":"wikipedia.org",
	"active":1
	},{
	"menu":"wiktionary.org",
	"active":1
	},{
	"menu":"yourdictionary.com",
	"active":1
	},
];
var entries = {};
if (!localStorage.getItem("entries")) {
	localStorage.setItem("entries", JSON.stringify(defaultentries));
}
entries = JSON.parse(localStorage.getItem("entries"));
function isActive(menu){
	console.log("isActive");
	var elen = entries.length;
	console.assert(!elen == 0);
	for(i=0;i<elen;i++){
		if(entries[i]["menu"] == menu){
			console.log(entries[i]["menu"]);
			if(entries[i]["active"] == 1){
				return true;
			}else{
				return false;
			}
		}
	}
}
function setActive(menu){
	console.log("setActive");
	var elen = entries.length;
	console.log(menu);
	console.assert(!elen == 0);
	for(i=0;i<elen;i++){
		if(entries[i]["menu"] == menu){
			entries[i]["active"] = 1;
		}
	}
	localStorage.setItem("entries", JSON.stringify(entries));
}
function setInactive(menu){
	console.log("setInactive");
	var elen = entries.length;
	console.log(menu);
	console.assert(!elen == 0);
	for(i=0;i<elen;i++){
		if(entries[i]["menu"] == menu){
			entries[i]["active"] = 0;
		}
	}
	localStorage.setItem("entries", JSON.stringify(entries));
}
/* Create the context menu */
var tm = chrome.contextMenus.create({"title": "Look-it-up", "contexts":["selection"]});
if(isActive("dictionary.com")){
	chrome.contextMenus.create({"title": "dictionary.com", "contexts":["selection"], "parentId": tm, "onclick": lookItUp1});
}
function lookItUp1(i, t){
	var createProperties = {url: "http://www.dictionary.com/cgi-bin/dict.pl?term=" + encodeURIComponent(i.selectionText)};
	chrome.tabs.create(createProperties);
}
if(isActive("merriam-webster.com-dict")){
	chrome.contextMenus.create({"title": "merriam-webster.com-dict", "contexts":["selection"], "parentId": tm, "onclick": lookItUp2});
}
function lookItUp2(i, t){
	var createProperties = {url: "http://www.merriam-webster.com/dictionary/" + encodeURIComponent(i.selectionText)};
	chrome.tabs.create(createProperties);
}
if(isActive("merriam-webster.com-thes")){
	chrome.contextMenus.create({"title": "merriam-webster.com-thes", "contexts":["selection"], "parentId": tm, "onclick": lookItUp3});
}
function lookItUp3(i, t){
	var createProperties = {url: "http://www.merriam-webster.com/thesaurus/" + encodeURIComponent(i.selectionText)};
	chrome.tabs.create(createProperties);
}
if(isActive("thefreedictionary.com")){
	chrome.contextMenus.create({"title": "thefreedictionary.com", "contexts":["selection"], "parentId": tm, "onclick": lookItUp4});
}
function lookItUp4(i, t){
	var createProperties = {url: "http://www.thefreedictionary.com/" + encodeURIComponent(i.selectionText)};
	chrome.tabs.create(createProperties);
}
if(isActive("thesaurus.com")){
	chrome.contextMenus.create({"title": "thesaurus.com", "contexts":["selection"], "parentId": tm, "onclick": lookItUp5});
}
function lookItUp5(i, t){
	var createProperties = {url: "http://thesaurus.com/search?q=" + encodeURIComponent(i.selectionText)};
	chrome.tabs.create(createProperties);
}
if(isActive("urbandictionary.com")){
	chrome.contextMenus.create({"title": "urbandictionary.com", "contexts":["selection"], "parentId": tm, "onclick": lookItUp6});
}
function lookItUp6(i, t){
	var createProperties = {url: "http://www.urbandictionary.com/define.php?term=" + encodeURIComponent(i.selectionText)};
	chrome.tabs.create(createProperties);
}
if(isActive("wikipedia.org")){
	chrome.contextMenus.create({"title": "wikipedia.org", "contexts":["selection"], "parentId": tm, "onclick": lookItUp7});
}
function lookItUp7(i, t){
	var createProperties = {url: "http://en.wikipedia.org/wiki/" + encodeURIComponent(i.selectionText)};
	chrome.tabs.create(createProperties);
}
if(isActive("wiktionary.org")){
	chrome.contextMenus.create({"title": "wiktionary.org", "contexts":["selection"], "parentId": tm, "onclick": lookItUp8});
}
function lookItUp8(i, t){
	var createProperties = {url: "http://en.wiktionary.org/wiki/" + encodeURIComponent(i.selectionText)};
	chrome.tabs.create(createProperties);
}
if(isActive("yourdictionary.com")){
	chrome.contextMenus.create({"title": "yourdictionary.com", "contexts":["selection"], "parentId": tm, "onclick": lookItUp9});
}
function lookItUp9(i, t){
	var createProperties = {url: "http://www.yourdictionary.com/" + encodeURIComponent(i.selectionText)};
	chrome.tabs.create(createProperties);
}

options.html


<!doctype html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Look-it-up Options</title>
	<script type="text/javascript" src="options.js"></script>
</head>
<body>
<ul id="menu">
</ul>
<div class="summary">Changes will take place the next time you start your browser. 
Or if you don't want to close the browser you could uncheck and recheck the enabled box next to this extension on the Extensions tab page.</div>

</body>
</html>

options.js


window.onload = function () {
	ckb = chrome.extension.getBackgroundPage().entries;
	var list = document.getElementById("menu");
	for(i = 0; i < ckb.length; i++){
		console.log(ckb[i]["active"]);
		if(ckb[i]["active"] == 1){
			var li = document.createElement("li");
			var temp = "<input type=\"checkbox\" class=\"butt\" checked=\"true\" value=\"" + ckb[i]["menu"] + "\"><span>" + ckb[i]["menu"] + "</span></input>";
			
			li.innerHTML = temp;
			list.appendChild(li);
		}else{
			var li = document.createElement("li");
			var tempp = "<input type=\"checkbox\" class=\"butt\" value=\"" + ckb[i]["menu"] + "\"><span>" + ckb[i]["menu"] + "</span></input>";
			li.innerHTML = tempp;
			list.appendChild(li);
			
		}
	}
	as = document.getElementsByClassName("butt");
	for(i=0;i<as.length;i++){
		as[i].addEventListener("click",function(evt){
			if(evt.target.checked == true){
				
				chrome.extension.getBackgroundPage().setActive(evt.target.value);
			}else{
				chrome.extension.getBackgroundPage().setInactive(evt.target.value);
			}
		},false)
	}
}


Install Look-it-up Context Menu Extension in Chrome (Google Chrome Store)

Install Look-it-up Context Menu Extension in Opera (My Repository)

Standard
Browser Extension, Google Chrome, Javascript, Opera, Share-It

Google Chrome Extension Share-it New Feature Update – An Options Page

The Google Chrome extension Share-it now has an Options page that enables you to choose which menu items are visible. Users simply can check which menu items to use and which to hide on the options page instead of navigating a menu of irrelevant menu items that they do not use. Preferences in an add-on are stored within the localstorage object in the browser in order to persist across start ups and closings. Developing an options page for your add-on isn’t a very difficult task, however, there are a couple of coding issues  to be aware of.

Share-it context menu running in Google Chrome

Share-it Context Menu

Share-it context menu options page running in Google Chrome

Share-it Options Page

Opera Next Is In The Loop

Something else to note is that I now also test Share-it on Opera Next where it runs superbly. I plan on eventually submitting this to the Opera store for consumption . For now, however, there is a link to download the .nex file at the bottom of this post if you want to use in now. Opera Next is based on the open source Chromium browser which Google Chrome is also based on. The context menu API is basically the same throughout as it allows for a shared code-base for context menu add-on development.

Share-it Context Menu running on Opera Next

Share-it Context Menu running on Opera Next

Caveats Developing an Options page or Popup page

There are a couple of tricky issues you should keep in mind if you are developing an options page for your add-on. First relates to scripting in pages inside of your add-on. There can be no inline script in your pages. Just keep your JavaScript in a separate file and make sure you are careful with your scripting not to create any inline script. Usually this means listening for click events and handling them using the event itself (similar to the way you would do it with Actionscript and Flex if you’ve ever done any Flash coding). The second issue relates to message and object passing. The JavaScript executing in your page isn’t in global scope for security reasons. There’s a special function to call, chrome.extension.getBackgroundPage(), that you have to call in order to gain access to the background page (app.js in this add-on). If you run into problems developing your page you should inspect the running page itself. The generated background page inspector will not show errors for secondary parts of the add-on (remember, not in global scope). Check out the source code below if you’re curious.

Source Code:

manifest.json

{
  "name": "Share-it",
  "description": "Adds context menu items to share the current page on a number of websites",
  "version": "0.4",
  "permissions": ["contextMenus"],
  "background": {
    "scripts": ["app.js"]
  },
  "options_page": "options.html",
  "icons" : {
		"16" : "favicon.ico",
		"32" : "peopleicon32.png",
		"48" : "peopleicon48.png",
		"128" : "peopleicon128.png"
	},
  "manifest_version": 2
}

app.js

/** app.js */
var defaultentries = [
	{
	"menu":"facebook.com",
	"active":1
	},{
	"menu":"twitter.com",
	"active":1
	},{
	"menu":"plus.google.com",
	"active":1
	},{
	"menu":"linkedin.com",
	"active":1
	},{
	"menu":"digg.com",
	"active":1
	},{
	"menu":"stumbleupon.com",
	"active":1
	},{
	"menu":"tumblr.com",
	"active":1
	},{
	"menu":"friendfeed.com",
	"active":1
	},{
	"menu":"fark.com",
	"active":1
	},{
	"menu":"blinklist.com",
	"active":1
	},{
	"menu":"plurk.com",
	"active":1
	},
];
var entries = {};
if (!localStorage.getItem("entries")) {
	localStorage.setItem("entries", JSON.stringify(defaultentries));
}
entries = JSON.parse(localStorage.getItem("entries"));
function isActive(menu){
	console.log("isActive");
	var elen = entries.length;
	console.assert(!elen == 0);
	for(i=0;i<elen;i++){
		if(entries[i]["menu"] == menu){
			console.log(entries[i]["menu"]);
			if(entries[i]["active"] == 1){
				return true;
			}else{
				return false;
			}
		}
	}
}
function setActive(menu){
	console.log("setActive");
	var elen = entries.length;
	console.log(menu);
	console.assert(!elen == 0);
	for(i=0;i<elen;i++){
		if(entries[i]["menu"] == menu){
			entries[i]["active"] = 1;
		}
	}
	localStorage.setItem("entries", JSON.stringify(entries));
}
function setInactive(menu){
	console.log("setInactive");
	var elen = entries.length;
	console.log(menu);
	console.assert(!elen == 0);
	for(i=0;i<elen;i++){
		if(entries[i]["menu"] == menu){
			entries[i]["active"] = 0;
		}
	}
	localStorage.setItem("entries", JSON.stringify(entries));
}
/* Create the context menu */
var hp = chrome.contextMenus.create({"title": "Share-it"});

if(isActive("facebook.com")){
	chrome.contextMenus.create({"title": "facebook.com", "contexts":["page"], "parentId": hp, "onclick": facebookIt});
}
function facebookIt(i, t){
	var createProperties = {url: "http://www.facebook.com/sharer.php?u="+ encodeURI(t.url) + "&src=" + encodeURIComponent("Share-it")};
	chrome.tabs.create(createProperties);
}

if(isActive("twitter.com")){
	chrome.contextMenus.create({"title": "twitter.com", "contexts":["page"], "parentId": hp, "onclick": twitterIt});
}
function twitterIt(i, t){
	var createProperties = {url: "https://twitter.com/share?url="+ encodeURI(t.url) + "&text=" + encodeURIComponent(t.title)};
	chrome.tabs.create(createProperties);
}

if(isActive("plus.google.com")){
	chrome.contextMenus.create({"title": "plus.google.com", "contexts":["page"], "parentId": hp, "onclick": googleplusIt});
}
function googleplusIt(i, t){
	var createProperties = {url: "https://plusone.google.com/_/+1/confirm?hl=en&url="+ encodeURI(t.url)};
	chrome.tabs.create(createProperties);
}

if(isActive("linkedin.com")){
	chrome.contextMenus.create({"title": "linkedin.com", "contexts":["page"], "parentId": hp, "onclick": linkedinIt});
}
function linkedinIt(i, t){
	var createProperties = {url: "http://www.linkedin.com/cws/share?url="+ encodeURI(t.url)};
	chrome.tabs.create(createProperties);
}

if(isActive("digg.com")){
	chrome.contextMenus.create({"title": "digg.com", "contexts":["page"], "parentId": hp, "onclick": diggIt});
}
function diggIt(i, t){
	var createProperties = {url: "http://digg.com/submit?url="+ encodeURI(t.url) + "&title=" + encodeURIComponent(t.title)};
	chrome.tabs.create(createProperties);
}

if(isActive("stumbleupon.com")){
	chrome.contextMenus.create({"title": "stumbleupon.com", "contexts":["page"], "parentId": hp, "onclick": stumbleuponIt});
}
function stumbleuponIt(i, t){
	var createProperties = {url: "http://www.stumbleupon.com/submit?url="+ encodeURI(t.url)};
	chrome.tabs.create(createProperties);
}

if(isActive("tumblr.com")){
	chrome.contextMenus.create({"title": "tumblr.com", "contexts":["page"], "parentId": hp, "onclick": tumblrIt});
}
function tumblrIt(i, t){
	var createProperties = {url: "http://www.tumblr.com/share?v=3&u="+ encodeURI(t.url) + "&t=" + encodeURIComponent(t.title)};
	chrome.tabs.create(createProperties);
}

if(isActive("friendfeed.com")){
	chrome.contextMenus.create({"title": "friendfeed.com", "contexts":["page"], "parentId": hp, "onclick": friendfeedIt});
}
function friendfeedIt(i, t){
	var createProperties = {url: "http://www.friendfeed.com/share?url="+ encodeURI(t.url) + "&title=" + encodeURIComponent(t.title)};
	chrome.tabs.create(createProperties);
}

if(isActive("fark.com")){
	chrome.contextMenus.create({"title": "fark.com", "contexts":["page"], "parentId": hp, "onclick": farkIt});
}
function farkIt(i, t){
	var createProperties = {url: "http://cgi.fark.com/cgi/fark/farkit.pl?u="+ encodeURI(t.url) + "&h=" + encodeURIComponent(t.title)};
	chrome.tabs.create(createProperties);
}

if(isActive("blinklist.com")){
	chrome.contextMenus.create({"title": "blinklist.com", "contexts":["page"], "parentId": hp, "onclick": blinklistIt});
}
function blinklistIt(i, t){
	var createProperties = {url: "http://www.blinklist.com/index.php?Action=Blink/Addblink.php&Url="+ encodeURI(t.url) + "&Title=" + encodeURIComponent(t.title)};
	chrome.tabs.create(createProperties);
}

if(isActive("plurk.com")){
	chrome.contextMenus.create({"title": "plurk.com", "contexts":["page"], "parentId": hp, "onclick": plurkIt});
}
function plurkIt(i, t){
	var createProperties = {url: "http://plurk.com/?qualifier=shares&status=" + encodeURIComponent(t.title) + "%20%2D%20" + encodeURI(t.url)};
	chrome.tabs.create(createProperties);
}

options.html


<!doctype html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Share-it Options</title>
	<script type="text/javascript" src="options.js"></script>
</head>
<body>
<ul id="menu"></ul>
<div class="summary">Changes will take place the next time you start your browser.
Or if you don't want to close the browser you could uncheck and recheck the enabled box next to this extension on the Extensions tab page.</div>
</body>
</html>

options.js


window.onload = function () {
	ckb = chrome.extension.getBackgroundPage().entries;
	var list = document.getElementById("menu");
	for(i = 0; i < ckb.length; i++){
		console.log(ckb[i]["active"]);
		if(ckb[i]["active"] == 1){
			var li = document.createElement("li");
			var temp = "<input class="\&quot;butt\&quot;" type="\&quot;checkbox\&quot;" checked="checked" value="\&quot;&quot;" />" + ckb[i]["menu"] + "";

			li.innerHTML = temp;
			list.appendChild(li);
		}else{
			var li = document.createElement("li");
			var tempp = "<input class="\&quot;butt\&quot;" type="\&quot;checkbox\&quot;" value="\&quot;&quot;" />" + ckb[i]["menu"] + "";
			li.innerHTML = tempp;
			list.appendChild(li);

		}
	}
	as = document.getElementsByClassName("butt");
	for(i=0;i<as.length;i++){
		as[i].addEventListener("click",function(evt){
			if(evt.target.checked == true){

				chrome.extension.getBackgroundPage().setActive(evt.target.value);
			}else{
				chrome.extension.getBackgroundPage().setInactive(evt.target.value);
			}
		},false)
	}
}

Version 0.5 update – fixed the graphics display in newest Chrome browser

If you downloaded an extension from somewhere other than the Google Store (or the Opera Store), Chrome will not let you install it on the fly (Opera will install it, however, you’ll have to go to the extensions page to enable it). You have to go to the browser menu and choose Tools->Extensions to open up the Extensions tab. Then drag the extension from wherever it is on the file-system to the open Extensions page. This should start the install process. If you ever feel funny about a packed extension that was downloaded you can unzip them to inspect the code (if you don’t have 7zip you’ll have to change the file extension to .zip – do it on a copy).

Related:

Chrome Browser:

Opera Next Extension Development:

References From Google Developer:

Standard
Google Chrome, Opera

The New Face of Opera, Google’s Chromium Project

The next version of Opera will be wearing a new face of sorts, it will have Google Chromium at its core. Opera has adopted Google’s Chromium project, the open source version of their proprietary browser Google Chrome,  to be the nucleus of all future versions of the popular browser. The new version, aptly named Opera Next (or Opera 15), is already available for perusal (http://www.opera.com/developer/next). Although available, this version is still under development, so don’t expect to wowed if you are a Google Chrome user as it still rides like plain old Chromium. With updates promised on a bi-weekly basis, it is still uncertain whether legacy users will feel at home using the new version of browser.

Opera Next Speed Dial News

Under perpetual development at this stage, Opera’s legacy features are regularly being integrated. So far, Opera’s unique Internet compression system (renamed from Turbo to Off-Road mode), has been integrated thus providing a faster Internet experience when your connection slows down. Opera Link, Opera’s bookmarking system, isn’t integrated as of the time of this writing which forces users of the new version to use the web interface while still under development. Opera Speed Dial, however, has a new face that has three new states that the old version didn’t have before; one of which allows you to ‘stash’ links you come across instead of bookmarking them (for now at least). The legacy Opera Mail feature has been broken off into a new separate application ( http://www.opera.com/computer/mail ), which contains all of the legacy mail operations and features.

Opera Link on Opera Next

Opera Speed Dial Stash Graphical Mode

Opera Next Speed Dial Stash Link Mode

Extensions

What does this mean for legacy add-on developers? The new core means studying how Chrome extensions are built. Opera Next will run two kinds of extensions: a limited subset of Google’s .crx extensions and Opera’s Navigator Extensions (.nex). Opera’s extension developer documentation has already been updated (http://dev.opera.com/extension-docs/index.html) for the next version. Once you take a gander at the documentation you’ll realize that most of the API is derived from Chrome’s. There are, however, large differences that should be noted. For instance, my post on Google Chrome context menu development will also apply to Opera Next context menu development – but anything I wrote concerning Omnibox extension development will not work for Opera Next as Opera Next does not have an Omnibox API yet (and may never have one). Opera Next uses only a subset of Chrome’s API which will most likely be expanded upon by the Opera team in the form of the opr prefix.

Little by little the new version of Opera is taking on a new personality that may or may not  become popular with legacy users. Only time and good development will tell. In my opinion – so far so good.

RELATED:

Standard
Javascript, Opera

Opera Unite Programming from a Newbie Perspective

Opera Unite is a personal web server platform provided by the Opera browser. To me, Opera Unite is a JavaScript tinkerers platform that is perfect for experimenting with different ideas I may come up with. The Opera web site gives the newbie a list of articles that introduces the different parts of the platform and libraries used to develop an Opera Unite program (http://dev.opera.com/articles/unite/). This article is meant as an introduction to the platform from a newcomers point of view. You should download and install the Opera browser from http://www.opera.com/. There are versions for virtually every popular operating system in use today.

What is Opera Unite?

Opera Unite is a Web Server service that lives inside of the Opera browser. Opera provides your browser with a web address when you enable Unite services in the browser. All calls to that web address are forwarded through the Opera web site to your Unite service through a special service proxy.  People call the address Opera provides you with to run an Opera Unite program installed in your browser. When you are not online, or when your Opera Unite service is not running users that call your web address are forwarded to your Opera Unite profile page.

How Do I Enable Opera Unite?

To enable the Unite service, click the Panels button in the lower left corner of the Opera browser, a toolbar should open up on the left side of the screen. Click the third button down from the top which is the Unite button. The Unite service panel should be open. Click the start button on the top of the panel and follow the directions. The Unite service comes with six apps by default (you should see them listed).

Programming for the Opera Unite Service

In order to program anything for Opera Unite you must have a basic working knowledge of JavaScript. If you are new to it there are plenty of tutorials out there on the Internet. JavaScript is not difficult to learn even though it may seem the opposite from looking at somebody else’s code sometimes. Similar to C++, JavaScript allows a programmer to abstract the abstracted abstraction. In other words, it may seem difficult simply because the script is some other programmers interpretation of something. The basic syntax of JavaScript is always the same, no matter how someone else structures or abstracts something.

(At this point I am assuming you know a bit of JavaScript and you want to get started)

The Structure and Anatomy of an Opera Unite Application

The organization of an Opera Unite application is a simple folder structure containing the files and scripts that your application will use zipped together (with the .zip file extension changed to .ua). There is an xml configuration file that tells Unite the name, path, author, among other things. Also, there is a html index file that acts strictly as a script loader (if you have ever scripted Spartan html this concept shouldn’t be new to you). Other than that there are the scripts that get executed which usually consist of a main.js and library files that you plan to utilize.


  • someuniteapp.ua
    • -scriptsfolder
      • –main.js
    • -index.html
    • -config.xml

    If this is your first time experimenting with Unite development on a Windows system there is something that you must do before you get started. Windows by default hides all known file extensions in Windows Explorer. You must change this in order to be able to change the extension of the zip files you create (so Unite will recognize it as an application). Do this by going to Folder Options in your Windows Explorer Tools menu and choose the View tab. Turn off the check box labeled Hide extensions for known file types. Click the OK button and you’re done. Keep in mind that with this option turned off you rename file types as well as their names (you’ll have to be careful not to change or erase the extension while renaming anything else on your system)(or you could change the setting back when you are finished).

    Config File

    Before anything you should create the configuration file. This is a short xml file that describes your program to Opera:

    
    <?xml version="1.0" encoding="utf-8"?>
    <widget webserver="yes" file="yes" network="private public" >
    <widgetname>YourOperaUniteApplicationName</widgetname>
    <description>A description of your Opera Unite application.</description>
    <author>
    <name>Your Name Goes Here</name>
    <organisation>If you‘re part of a company it’s name goes here</organisation>
    </author>
    <feature name="<a href="http://xmlns.opera.com/webserver&quot;">http://xmlns.opera.com/webserver"</a>>
    <param name="type" value="service"/>
    <param name="servicepath" value="thepaththatyouwanttouse"/>
    </feature>
    <feature name="<a href="http://xmlns.opera.com/fileio&quot;">http://xmlns.opera.com/fileio"</a>></feature>
    </widget>
    
    

    Opera based their Unite feature on their already established widget system which also uses xml configuration files. The file is pretty basic as you can see. The important fields are the application name and description, the author name, and the servicepath field. The service path field is the actual path address for the application that comes after your top level Opera Unite url. Features that are part of Opera’s xml namespace get a feature tag with an address. In the example above I have included the FileIO xml tag for the FileIO feature (you need it to use templates or write to a data file, so I included it).

    Dummy Index File

    The next file is the dummy index.html file. All that file does is call the scripts that are included and ran when you get a visitor. It is not meant to be a home page or anything like that. You create the home page from your script file (you can use a html template file for your html). It could be a blank page template or even just the script tags that include your scripts. Any library (server-side) you plan to use is included here. There is also a loader script library that you can use as well. To me, its just seems easier to use the standard html script tags to include my server-side scripting files:

    
    <!doctype html>
    <html>
    <head>
    <title></title>
    <script src="scripts/template/template.js"></script>
    <script src="scripts/main.js"></script>
    </head>
    <body>
    </body>
    </html>
    
    
    Scripts

    The next thing that you should do is create your scripts folder. In it you will include you main.js along with the libraries you will use in subfolders. Opera has a very good set of libraries to get you started on the server side( http://dev.opera.com/libraries/unite/ ). Keep in mind that you can write your own libraries if you please. The platform is completely extensible in that regard.

    Your main.js file is meant to be the heart of your Opera Unite application. All page requests are answered and processed in this file. Basically, what you do is set up listeners that listen for a ‘page’ request. That listener function will call a specified function (that you write) that will process the request and return a page to the client.  You can write the most Spartan system possible (such as the blog application explained in the developers primer article that concatenates the html response together in a string variable) or you can use the markuper template library – or even roll your own. It really doesn’t matter how you put the response together just as long as what is returned to the client is valid.
    A really simplified example would be (no template):

    // main.js
    var webserver;
    window.onload = function () {
    webserver = opera.io.webserver
    if (webserver)
    {
    // page requests are listened for here (_index is the default listener for the app)</code><code>
    webserver.addEventListener('_index', myHomePage, false);
    }
    }
    function myHomePage(e)
    {
    // set up the response object here
    var response = e.connection.response;
    // page variable
    var pg = “<html><head><title>Spartan Response</title></head><body>Hello simple example</body></html>”;
    // now send it to the client
    response.write(pg);
    // done now close the connection
    response.close();
    }

    Granted, this example really doesn’t do anything special; but it does give the very basic structure of the whole request process. Basically, listeners are set up that call handler functions that handle requests. Response objects are created through the WebServerRequestEvent object that is passed to the handler function (e in the case above) and written out to the client using the write() function of that response object.

    Other Various Files

    Other files that are included would be the icon files that you point to in your configuration file (they’re not really needed but that is where you would include them). Other graphics that your application would use could go in an images folder. Cascading Style Sheets used by your application could go in another folder.

    Note: Opera Unite applications are dependent upon your connection UPLOAD speed. Big images and files could slow down your application drastically. If your application is image laden your best bet would be to upload them to a service such as flickr and call them from within the client html. The same goes for scripting libraries used inside the client html. You could call libraries from google and save the bandwidth to make your application more responsive. However, any libraries you use on the server side should be included in the .ua file.

    Testing

    Opera has to approve any program that they include on their site. However, in order to test something you write you’ll have to install the program off of your hard drive. To do that you zip the files together, rename the file to have a .ua extension instead of a .zip extension (Windows users may have to change the Show File extensions for all Known File Types Windows Explorer setting in order to do this), and drag it to the browser window. This should start the installation process. Keep in mind that you have to have the Unite service already running to install anything from your hard drive.

    Troubleshooting

    If you are having problems installing your application there are two things to check first. Firstly, check and make sure that the Opera Unite service is currently running when you drag your application to the browser window. Secondly, check and make sure that the index.html and the config file is at the root of the .ua (zip) file. Some compression programs will include the folder as the top level – which is what you don’t want (Opera will not recognize it as an application). Simply select all of the files enclosed (instead of right clicking on the folder) in the app folder and add them that way. Other than that – check your script for mistakes.

    In Conclusion

    While this has been a rudimentary look at how an Opera Unite application is constructed I tried to cover the most important parts plainly and blatantly. You can see how requests and responses are handled and how the basic structure of an application comes together. Opera Unite applications can be as simple or as complex as you want them to be.

    From here you could utilize functionality in your application by learning how to use the different Unite libraries in your scripts (the two most prevalent would be Markuper and Yusef Opera’s template and server libraries).

    Reading

Happy Tinkering!

Standard
Opera

Using Opera Unite in your Development Cycle

Using Opera with its Unite service can be invaluable to your development cycle. Most site developers are using their workstation as their development server while they get a site written and developed. During that cycle of development it is virtually impossible for anyone to view the progress without having physical access to that workstation where it is being worked on. I mean, what client or partner isn’t going to want to see “how things are going”?

With Opera Unite you can install different JavaScript server programs that run off of your system while Opera is running. One of those JavaScript server programs that are of particular interest to to web developers working on a development LAMP stack is the Web Proxy (http://unite.opera.com/application/272/) server program. Using Web Proxy it is possible to serve up a program running on your development server. Don’t misunderstand me, it is no perfect solution. The Opera forums are already filled with security complaints and concerns. At this point I wouldn’t feel comfortable using it as a full time solution. But it will enable you to show off the development progress of a site to a client or fellow developer anywhere.

I have has problems with it however. Sometimes you’ll need to refresh the browser to “catch” a renegade style sheet or JavaScript file. Using this server program counts as using a proxy from your development server (LAMP) to the Unite server (running inside Opera) running on your machine that is running through a proxy on Opera’s servers, so there’s bound to be small glitches in throughput. Anything you serve up that uses cookies for security is a security risk. There are other various complaints about the Web Proxy Unite service, but those mentioned are the ones I concern myself with the most.

It’s surprisingly simple to set up too. Download and install the Opera web browser from http://www.opera.com/ . Then go to the link for the Web Proxy Unite program mentioned previously and hit the install button. From there you’ll be asked to enable Unite services in your browser (you’ll need to create a free Opera account and configure the Unite server for your computer – its easy). After that you set a path for the proxy which should be the name of your running development server (on my Windows box its localhost – I believe it sets the running server as default). It also asks for a folder where the content should be served from. DON’T set this as the folder of your program on the development server. That folder will only be served up by Web Proxy if your LAMP development server is off (great for static content though). The path to your localhost will be shown in bold on the configuration dialog. That is the web address to the root of your development server installation. If the program you are working on is in a sub-folder simply add it to that web address to serve it.

One other Opera product I use during development is the Opera Mobile emulator (http://www.opera.com/developer/tools/#operamobile) which emulates a smart phone browser on your desktop. Opera’s mobile edition is getting more and more popular. Viewing how your pages look in an emulator is a blessing when your debugging your css. On a side note: I’ve come across some great web development articles on the Opera developer site (such as this one on mobile pages – http://dev.opera.com/articles/view/the-mobile-web-optimization-guide/).

Opera’s Unite Web Proxy and mobile emulator can be useful anyone developing web sites. Considering that Opera is a free product there’s no reason not to have it on your system.  Opera widgets (http://dev.opera.com/sdk/) are now first class objects on your system. They run as a standalone program does now (without the browser being open). You do, however, need to have the browser installed on your system for them to run. All in all Opera’s a great browser even if you don’t use it for everyday web surfing.

Standard
Javascript, Opera

Working With Opera Unite

Doing your own web page on the Internet is easy. Most of the time, if all you are doing is writing that includes pictures your choices are almost endless. Things get a bit more narrowed down once you want anything more. Google and Microsoft both offer web space and blog space (Google with Blogger and Microsoft with Live), but there are limitations put on what you can do. With those services, like many others, you have to stay within their systems framework. Most people want the bling they see on other sites. Most of the time that bling comes at the cost of including JavaScript on the page at the very least. For more complex animations you may want to include a Flash widget or video. This article is about doing it your way for free.

For many, a personal web page is an ever changing slate of personal taste and thoughts. Being able to express yourself to the fullest, with every option available to you, is difficult to do on the Internet these days (for free). The almighty grail of expression is the web server. You can do anything you want with your own web server space. That, however, costs money every month. Most people want to express themselves in their own way for free. Like taking out a piece of paper and drawing on it, we all want the freedom to do what we want whenever we want to do it.

Most of the public sites that allow blogs and free web sites do not allow JavaScript. Why, because it can be a headache for them. JavaScript, beyond making a web page more expressive, can be used maliciously. JavaScript has become the programming language of the web browser. It can be used to redirect the browser, read and write cookies, and in the right hands – cause general havoc.

Google Sites http://sites.google.com/ is an option for many people. Google does NOT allow you to run your own JavaScript. Google does, however, allow you to embed some of their own JavaScript widgets (which gives you a bit more than the other guys). If you are willing to sacrifice a bit of creativity I would use them. They don’t require ads of any kind and they have many templates to get you started. You can create as many sites with as many pages as you like as long as you keep within the 100mb limitation (you can fit a lot of HTML in a hundred megabytes). After you get set up there I recommend you visit Steegle.com for customization tips. I would also recommend using google docs as well as you may embed anything you write there on your site. It is plain to see that Google give users many free services that could be used to your advantage http://www.google.com/intl/en/options/

You may say “well that’s great, but I want more”. Beyond paying for some shared hosting, there is a way (I did say free at the beginning of this page). However, there are other limitations. It has to be on your computer and you have to download and run

the Opera web browser http://www.opera.com/ with the Unite http://unite.opera.com/ Web Server service turned on. That means your site will have operating hours like a store or the library unless you have your computer running 24 hours a day 7 days a week. When your computer is off or you have Opera turned off users will be redirected to a page that has your Opera profile picture in the upper right corner and an explanation that you Unite server isn’t running. You get one paragraph on that page (that’s it though so think of something short to say – like the hours you are running), and it would be a good idea to have your opera profile picture something relevant to the page you are hosting.

Also, there is the matter of your Internet connection speed. Your web server is limited by your connection UPLOAD (which is usually a little slower than your download throughput). If you are just hosting web pages with a little script in them you’ll have little problems. But if you are hosting last Thanksgiving’s video of uncle Bob acting like a chicken, you may run into a speed problem (dial-up users pay attention). If you put the video on Utube or another video hosting site and embed it on the page you probably won’t have any problems at all however (because all the visitor is downloading from your page is the embed script not the video itself).

Opera provides you with your web address after you choose a name under your user profile. It will show up as a sub-domain under your profile user-name in the URL. The Opera Unite web server program will forward the visitor to a default Unite profile page (which will have your picture from your Opera profile) if your browser isn’t running . If you are running other Unite services other than the web server they will be listed on this page as well.

Domain forwarding services are a way around the default address given by many of the free site providers such as Google sites. Unfortunately most, if not all of these don’t seem to work with Opera Unite’s proxy service. There are a couple out there that are free, but the big thing with those services are ads. Those services will allow you to register a free domain name (just not a dot com name) and point visitors to the page of your choice.

I have had mixed experiences using these types of services. Take smartdots http://www.smartdots.com/ for instance, they tell you that there are no forced ads using their service and they lie, lie, lie (get used to that on the Internet). I found some German ad asking me if I want a free iPod pop up anyway (which made me angry of course). However, smartdots does list you in as many search engines as they can (maybe you can still use that to your advantage). One that is not that bad is the .tk domain service http://www.dot.tk/. TK will give you a domain free, but you have to get 25 hits on that domain in 90 days or it gets canceled (or you can pay 7 dollars a year). No advertisements were found using this service but they do force their favorite icon on your browsers tab. Also, sub pages on your site will always point to your homepage using these free services.

There is also another up side to using these services I almost forgot to mention, you can change where they point to whenever you want to. So you can log in to the domain provider and change to another site hosted on say Google (or anywhere else you can get a free site) whenever you want to.

The Opera Unite Web Server service is great. Your page will have to be named index.html in the folder you create or choose during setup in order to run. Setup is easy, just read what is there and follow the directions. You can choose to create a blank index page to get you started with something to edit.

I am referring to a static web page with anything you want running in it with no JavaScript or Flash limitations. Don’t expect to be able to run PHP doing this because it will not work – just HTML (and JavaScript).

Opera Unite’s Web Server service has the capability to run server side scripts, just not PHP. If you really need to run some kind of server-side scripting it does allow you to using JavaScript. So it is a true web server in that sense. The technology is new, however, and it is largely unknown to me http://dev.opera.com/articles/unite/. Hopefully it will be the subject of another page of text the next time I am writing here. But I do know there are no limitations on static pages using this. The only size limitation is the space you want to use on your hard drive. Keep in mind that Opera Unite has other services to offer, what I am referring to is the Web Server service specifically here.

Standard