Opera to Phone - Version 1.3: general bug fixes

This commit is contained in:
rich.tibbett
2010-12-12 02:08:48 +00:00
parent bcca22d5cd
commit 6abd44a267
6 changed files with 178 additions and 201 deletions

View File

@@ -1,9 +1,9 @@
<?xml version='1.0' encoding='utf-8'?>
<widget xmlns="http://www.w3.org/ns/widgets" id="extensions:opera-to-phone" version="1.0_beta">
<name short="OperaToPhone">Opera to Phone</name>
<description>This extension adds a button to Opera that lets you seamlessly push links, maps, youtube videos, phone numbers and text to copy to the clipboard directly to your Android device. You also need to install the Chrome to Phone Android application on your phone. The application can be downloaded from Android Market (search for 'Chrome to Phone'). Requires a mobile phone running Android 2.2 ("Froyo") or later.</description>
<author href="http://opera.com" email="richt@opera.com">Rich Tibbett</author>
<access origin="https://chrometophone.appspot.com/*"/>
<widget xmlns="http://www.w3.org/ns/widgets" id="https://addons.opera.com/addons/extensions/details/operatophone/" version="1.3">
<name>Opera to Phone</name>
<description>Seamlessly push links, maps, youtube videos, phone numbers and text directly to your Android device. Requires a mobile phone running Android 2.2+ and the 'Chrome to Phone' application.</description>
<author email="rich.tibbett@gmail.com">Rich Tibbett</author>
<access origin="https://chrometophone.appspot.com"/>
<icon src="icon_64.png"/>
<license>
Copyright 2010 Opera Software ASA.

View File

@@ -8,25 +8,23 @@ var apiVersion = 5;
var baseUrl = 'https://chrometophone.appspot.com';
var sendUrl = baseUrl + '/send?ver=' + apiVersion;
var signInUrl = baseUrl + '/signin?extret=' +
encodeURIComponent('http://code.google.com/p/chrometophone/logo') + '?login';
encodeURIComponent('http://code.google.com/p/chrometophone/logo') + '?login&ver=' + apiVersion;;
var signOutUrl = baseUrl + '/signout?extret=' +
encodeURIComponent('http://code.google.com/p/chrometophone/logo') + '?logout';
encodeURIComponent('http://code.google.com/p/chrometophone/logo') + '?logout&ver=' + apiVersion;;
var registerUrl = baseUrl + '/register?ver=' + apiVersion;
var apkUrl = 'http://code.google.com/p/chrometophone/wiki/AndroidApp';
var ACTION_START_SEND = 'start_send_process';
var ACTION_SEND_PAGE = 'send_to_phone';
var ACTION_APK_REQUIRED = 'apk_required';
var ACTION_REGISTER_USERJS = 'register_userjs';
var ACTION_DEREGISTER_USERJS = 'deregister_userjs';
var ACTION_CAPTURE_SELECTION = 'capture_selection';
var ACTION_SELECTION_CAPTURED = 'selection_captured';
var ACTION_OPEN_TAB = 'open_tab';
var ACTION_CLOSE_TAB = 'close_tab';
var STATUS_SUCCESS = 'success';
var STATUS_LOGIN_REQUIRED = 'login_required';
var STATUS_DEVICE_NOT_REGISTERED = 'device_not_registered';
var STATUS_HTTP_PAGES_ONLY = 'http_pages_only';
var STATUS_GENERAL_ERROR = 'general_error';
var STATUS_NO_TAB_ACCESS = 'no_tab_access';
var STATUS_GENERAL_ERROR = 'general_error';
var BROWSER_CHANNEL_RETRY_INTERVAL_MS = 10000 * (1 + Math.random() - 0.5);

View File

@@ -1,64 +1,76 @@
// ==UserScript==
// @include *
// @include http://*
// @include https://*
// ==/UserScript==
// obtain access to all tabs
var ACTION_REGISTER_USERJS = 'register_userjs';
var ACTION_DEREGISTER_USERJS = 'deregister_userjs';
var ACTION_CAPTURE_SELECTION = 'capture_selection';
var ACTION_SEND_PAGE = 'send_to_phone';
var ACTION_CLOSE_TAB = 'close_tab';
function S4() {
return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
}
function guid() {
return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4());
}
if(!window.top.userJS_UUID) {
window.top.userJS_UUID = guid();
window.addEventListener('focus', function(){
opera.extension.postMessage({action: ACTION_REGISTER_USERJS, uuid: window.top.userJS_UUID});
}, false);
window.addEventListener('blur', function(){
opera.extension.postMessage({action: ACTION_DEREGISTER_USERJS, uuid: window.top.userJS_UUID});
}, false);
// register this tab as the active userjs onload
opera.extension.postMessage({action: ACTION_REGISTER_USERJS, uuid: window.top.userJS_UUID});
}
opera.extension.addEventListener('message', function(request) {
//opera.postError('Callback received at UserJS: ' + request.data.action);
if(request.data.action==ACTION_CAPTURE_SELECTION
&& request.data.uuid==window.top.userJS_UUID) {
var currentUrl = document.location.href;
var currentUrl = document.location.href;
opera.extension.addEventListener( 'message', function( message ) {
if( message.data.action === ACTION_CAPTURE_SELECTION ) {
var pageInfo = {
action: ACTION_SEND_PAGE,
data: {
link: encodeURIComponent(currentUrl),
title: encodeURIComponent(document.title),
selection: encodeURIComponent(window.getSelection())
link: currentUrl,
title: document.title,
selection: window.getSelection() ? window.getSelection().toString() : null
}
};
// URL overrides
if (currentUrl.match(/^http[s]?:\/\/maps\.google\./) ||
currentUrl.match(/^http[s]?:\/\/www\.google\.[a-z]{2,3}(\.[a-z]{2})\/maps/)) {
if ( currentUrl.match( /^http[s]?:\/\/maps\.google\./i ) ||
currentUrl.match( /^http[s]?:\/\/www\.google\.[a-z]{2,3}(\.[a-z]{2})\/maps/i ) ) {
var link = document.getElementById('link');
if (link && link.href)
pageInfo.data.link = encodeURIComponent(link.href);
pageInfo.data.link = link.href;
}
opera.extension.postMessage(pageInfo);
opera.extension.postMessage( pageInfo );
}
}, false);
//opera.postError("UserJS loaded: " + window.location.href + " / " + window.top.userJS_UUID);
function findAndReplace(searchText, replacement, searchNode) {
if (!searchText || typeof replacement === 'undefined') {
// Throw error here if you want...
return;
}
var regex = typeof searchText === 'string' ?
new RegExp(searchText, 'g') : searchText,
childNodes = (searchNode || document.body).childNodes,
cnLength = childNodes.length,
excludes = 'html,head,style,title,link,meta,script,object,iframe';
while (cnLength--) {
var currentNode = childNodes[cnLength];
if (currentNode.nodeType === 1 &&
(excludes + ',').indexOf(currentNode.nodeName.toLowerCase() + ',') === -1) {
arguments.callee(searchText, replacement, currentNode);
}
if (currentNode.nodeType !== 3 || !regex.test(currentNode.data) ) {
continue;
}
var parent = currentNode.parentNode,
frag = (function(){
var html = currentNode.data.replace(regex, replacement),
wrap = document.createElement('div'),
frag = document.createDocumentFragment();
wrap.innerHTML = html;
while (wrap.firstChild) {
frag.appendChild(wrap.firstChild);
}
return frag;
})();
parent.insertBefore(frag, currentNode);
parent.removeChild(currentNode);
}
}
window.addEventListener( 'DOMContentLoaded', function() {
if( currentUrl.match( /^http[s]?:\/\/www\.google\.com\/accounts\/ServiceLogin\?(.*)?ahname=Chrome\+to\+Phone(.*)?$/i ) ) {
// Opera log in message so users know what they are logging in to.
findAndReplace('Chrome', 'Opera', document.body);
} else if (currentUrl.match( /^http:\/\/code\.google\.com\/p\/chrometophone\/logo(.*)?$/i )) {
opera.extension.postMessage({
action: ACTION_CLOSE_TAB
});
}
}, false);

View File

@@ -4,7 +4,6 @@
<script type="text/javascript" src="constants.js"></script>
<script type="text/javascript" src="send_logic.js"></script>
<script>
var UIItemProperties = { // options for the button
disabled: false,
title: "Opera to Phone",
@@ -18,89 +17,63 @@ var UIItemProperties = { // options for the button
var operaBtn = opera.contexts.toolbar.createItem( UIItemProperties ); // create the button
opera.contexts.toolbar.addItem( operaBtn ); // add button to UI
var currentTab = null; // tracks currently focused tab
opera.extension.addEventListener('message', function(request) { onMessage(request); }, false);
var currentUserJS = null; // keeps track of which UserJS is in focus
var timoutTimer = null;
function onMessage(request) {
function onMessage( message ) {
var currentTab = opera.extension.tabs.getFocused();
if (request.data.action==ACTION_REGISTER_USERJS) {
currentUserJS = request.data.uuid;
//opera.postError("BG: Registered UserJS[" + currentUserJS + "]");
} else if (request.data.action==ACTION_DEREGISTER_USERJS) {
// deregister after a short delay, so the button has time to capture the currentUserJS
window.setTimeout(function() {
if(currentUserJS==request.data.uuid) {
//opera.postError("BG: Deregistering UserJS[" + currentUserJS + "]");
currentUserJS = null;
}
}, 300);
} else if(request.data.action==ACTION_START_SEND) {
var captureSelection = {
action: ACTION_CAPTURE_SELECTION,
uuid: currentUserJS
};
// Get the selected text (if any) from the UserJS
opera.extension.broadcastMessage(captureSelection);
// Set timeoutTimer to throw an error after 1 second...
timeoutTimer = window.setTimeout(function() {
request.data.action = ACTION_SEND_PAGE;
onMessage(request); // stop waiting for UserJS and go to next step
switch( message.data.action ) {
case ACTION_START_SEND:
if( currentTab ) {
var captureSelection = {
action: ACTION_CAPTURE_SELECTION
};
currentTab.postMessage(captureSelection);
}
timeoutTimer = window.setTimeout( function() {
message.data.action = ACTION_SEND_PAGE;
onMessage( message );
}, 1000);
} else if (request.data.action==ACTION_SEND_PAGE) {
// Cancel timeoutTimer
if(timeoutTimer) window.clearTimeout(timeoutTimer);
var userJS_data = {};
if(request.data.data) userJS_data = request.data.data;
// Set currentTab pointer
currentTab = opera.extension.tabs.getFocused();
if(currentTab || userJS_data.link) {
var url = userJS_data.link ? userJS_data.link : encodeURIComponent(currentTab.url);
var title = userJS_data.title ? userJS_data.title : encodeURIComponent(currentTab.title);
var sel = userJS_data.selection ? userJS_data.selection : '';
var msgType = (sel && sel.length > 0) ? 'selection' : 'page';
var urlCheck = decodeURIComponent(url);
if (urlCheck.indexOf('http:') == 0 || urlCheck.indexOf('https:') == 0) {
sendToPhone(title, url, sel, msgType, function(status) {
// Display sendToPhone result in popup.html
opera.extension.broadcastMessage({action: status});
break;
case ACTION_SEND_PAGE:
window.clearTimeout( timeoutTimer ); // Cancel timeout error timer
var pageData = message.data.data || {};
if( currentTab ) {
var data = {
title: pageData.title || currentTab.title,
url: pageData.link || currentTab.url,
sel: pageData.selection || null,
type: pageData.selection ? 'selection' : 'page'
};
sendToPhone( data, function( status ) {
// Display sendToPhone result in Popup
opera.extension.broadcastMessage({
action: status
});
} else {
opera.extension.broadcastMessage({action: STATUS_NO_TAB_ACCESS});
}
} else { // no object means that the extension does not have access to the current tab :(
opera.extension.broadcastMessage({action: STATUS_NO_TAB_ACCESS});
} );
} else {
opera.extension.broadcastMessage({
action: STATUS_NO_TAB_ACCESS
});
}
// Reset currentTab pointer
currentTab = null;
} else if (request.data.action==ACTION_APK_REQUIRED) {
opera.extension.tabs.create({url: apkUrl, focused:true});
}
break;
case ACTION_OPEN_TAB:
if(message.data.data && message.data.data.url) {
var tabData = {
url: message.data.data.url,
focused: true
};
opera.extension.tabs.create( tabData );
}
break;
case ACTION_CLOSE_TAB:
if( currentTab )
currentTab.close();
break;
}
}
opera.extension.addEventListener( 'message' , onMessage, false );
</script>
</head>
<body>

View File

@@ -7,77 +7,62 @@ body {
min-width: 320px;
overflow: hidden;
}
a, a:visited, a:active {
color: blue;
}
td {
font-family: verdana;
font-family: Verdana, Arial;
font-size: 12px;
color: black;
}
</style>
<script type="text/javascript">
/*
* Portions of this page are modifications based on work created and shared
* by Google and used according to terms described in the Creative Commons 3.0
* Attribution License.
*/
var apiVersion = 5;
var baseUrl = 'https://chrometophone.appspot.com';
var sendUrl = baseUrl + '/send?ver=' + apiVersion;
var signInUrl = baseUrl + '/signin?extret=' +
encodeURIComponent('http://code.google.com/p/chrometophone/logo') + '?login';
var signOutUrl = baseUrl + '/signout?extret=' +
encodeURIComponent('http://code.google.com/p/chrometophone/logo') + '?logout';
var registerUrl = baseUrl + '/register?ver=' + apiVersion;
var ACTION_START_SEND = 'start_send_process';
var ACTION_SEND_PAGE = 'send_to_phone';
var ACTION_APK_REQUIRED = 'apk_required';
var ACTION_REGISTER_USERJS = 'register_userjs';
var ACTION_DEREGISTER_USERJS = 'deregister_userjs';
var ACTION_CAPTURE_SELECTION = 'capture_selection';
var STATUS_SUCCESS = 'success';
var STATUS_LOGIN_REQUIRED = 'login_required';
var STATUS_DEVICE_NOT_REGISTERED = 'device_not_registered';
var STATUS_HTTP_PAGES_ONLY = 'http_pages_only';
var STATUS_GENERAL_ERROR = 'general_error';
var STATUS_NO_TAB_ACCESS = 'no_tab_access';
var BROWSER_CHANNEL_RETRY_INTERVAL_MS = 10000 * (1 + Math.random() - 0.5);
</script>
<script type="text/javascript" src="constants.js"></script>
<script>
function loadHandler() {
document.getElementById('msg').innerHTML = "Sending to phone...";
var msg = document.getElementById('msg');
msg.innerHTML = "Sending to phone...";
document.getElementById('help').innerHTML = "Help";
document.getElementById('signout').innerHTML = "Sign out";
setSignOutVisibility(false);
opera.extension.postMessage({action: ACTION_START_SEND});
// Callback from the background process
opera.extension.addEventListener('message', function(status) {
if (status.data.action == STATUS_SUCCESS) {
document.getElementById('msg').innerHTML = "Sent to phone."
activateSignOutLink();
} else if (status.data.action == STATUS_LOGIN_REQUIRED) {
var signinLink = '<a href="' + signInUrl + '" target="_o2pTab">sign in</a>';
document.getElementById('msg').innerHTML = "Please " + signinLink + " to Opera to Phone.";
setSignOutVisibility(false);
} else if (status.data.action == STATUS_DEVICE_NOT_REGISTERED) {
opera.extension.postMessage({action: ACTION_APK_REQUIRED});
document.getElementById('msg').innerHTML = "Device not registered for user.";
activateSignOutLink();
} else if (status.data.action == STATUS_NO_TAB_ACCESS) {
document.getElementById('msg').innerHTML = "Only HTTP URLs are supported (or try refreshing the page).";
} else if (status.data.action == STATUS_GENERAL_ERROR) {
document.getElementById('msg').innerHTML = "Error sending to phone: " + status.data.action;
activateSignOutLink();
opera.extension.addEventListener( 'message', function( message ) {
switch(message.data.action) {
case STATUS_SUCCESS:
msg.innerHTML = "Sent to phone."
activateSignOutLink();
window.setTimeout(function() {
window.close();
}, 3000);
break;
case STATUS_LOGIN_REQUIRED:
var signinLink = '<a href="' + signInUrl + '" target="_o2pTab">sign in</a>';
msg.innerHTML = "Please " + signinLink + " to Opera to Phone.";
setSignOutVisibility(false);
break;
case STATUS_DEVICE_NOT_REGISTERED:
opera.extension.postMessage({
action: ACTION_OPEN_URL,
data: {
url: apkUrl
}
});
msg.innerHTML = "Device not registered for user.";
activateSignOutLink();
case STATUS_NO_TAB_ACCESS:
msg.innerHTML = "Cannot access the current tab.";
break;
case STATUS_GENERAL_ERROR:
msg.innerHTML = "Error sending to phone: " + message.data.action;
activateSignOutLink();
break;
}
}, false);
opera.extension.postMessage({
action: ACTION_START_SEND
});
}
function activateSignOutLink() {
@@ -85,7 +70,7 @@ function activateSignOutLink() {
var signOutLink = document.getElementById('signout');
signOutLink.style.color = 'blue';
signOutLink.href=signOutUrl;
signOutLink.click();
//signOutLink.click();
}
function setSignOutVisibility(visible) {
@@ -102,11 +87,11 @@ window.addEventListener("load", loadHandler, false);
<body>
<table>
<tr>
<td valign="top" width="48px"><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1%2B%2FAAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTM5jWRgMAAAuVSURBVGiBxZp7jFzXXcc%2F55x779zZ2Z3ZGe%2Fatb2sEztZxzWRRZUEmbiGBuoohjataEgoShoKxJFogmgLERFqSiNKpSLSlkdrTJSCCBGNQiFSiVIJV2mdBhnba5N0s36sXa%2B9tjvr9czO7Ozs3Mf58cfsjGdf9rjOhp%2F0k2bOfZzf9%2Fc%2B51wlIlwPKaXavve%2B%2B%2B67OZvNvt%2FzvM1a65scx%2Bnp7u5eFUWRDzQFmX1nXCwW8yKSt9YerdVqb166dOm1l1566dSc%2Bd8NAI%2Fu2vXhzq6uT%2Fi%2Bf7vneascx%2FESiQS1Wo19%2B%2FaRSqXQWiMiKKUIggDP89i6dStBEBBFEVEUBUEQXJienv7%2B5OTkM88%2B%2B%2ByhJoBr0eJbN2%2FMpWK2afhVBTuBPsAKDItS%2Fx657t6TH%2Fj513d8%2FR9mAJ7Y9chT%2FnvWfL6nZwXpdBrXdVFKYa1lZmaGsbGxJoAGRVGEtZb%2B%2Fn6MMVhrsdZSrVYplUrk8%2Fnw4sWL9%2B7Zs%2BeVtgEc37Dxgy7ygBG1DVitIKVAN56UOkeiVFm0Go1cd%2B%2F3Nq0%2Fl9%2Fyvi%2FfMDBAGAScP3%2BefD7PxMQE5XKZmZkZoigiCII5c7muSzKZxHVduru7yWazdHd309PTQy6Xo1KpcPTo0ZEjR45sd64m%2BPCGjXcmhC8aYbvmMlANxEAkoABHgQbHimRVJFk3rm1RHRlW9vdz5PBh9u%2Ffz%2BjoKKVSienp6aaWG9xKWmu01hhjSCQS%2BL5PKpWit7eXgYEBtm3bxrp16zZcunTps1e0wPD6gacS8JSpy4hQ%2F6GAshCUhP8IhAMafF%2FxS2nFB5IKLBDHMd%2F75EMcGB%2FnWy%2B8QLlcXqDpayVjDF1dXdx44408%2BOCDlEqlt5e0wPD6gecS8LCiLlCDBChZTozE3P%2FRM8cOtVz6wn%2F1D%2FzmWsM3kwovBKQjxZHB7zIxMYFSCmPMdQEQEYrFIoODg9x%2B%2B%2B1s3rx5tV7sxh%2BtH9jtKh4WBbaFRUEVKqciPjxPeAB%2BefTYC3nLowFgtSKWy%2B7hOE7TNX5aNsbgui5QD3QRUQsAHL5hYJcLj0Bd860cA9OWZ%2B49e%2BztpbS0%2FfSx56rCD%2BjwEeeyxpVS7xg3rGGtZQ6AH%2FTf1O9p%2FtLM%2BrG0MEAoVCZivrGU8A2aEf4mjiw2ts2wf6cBNGhODHQa%2FQWj6IxbhG5qEIjghzvOHBu7GoCJkO9i4kIcx1mlNUqpOXn%2BeqnVCs23vvYzN%2Fe7igfUIsJD0xL72pngnrFjxWpH15B1XBRy3b6%2FGDeoaYGk4WNakbCLilQHEAmH2wEAMC7Om6Fwp57V%2FjtpAT1rVUCaABzFTs3i2qc%2BLlYYaXeSasIfQ9WrxnIAAFBKOQ7At1etX6%2FhltaAnU8iTCGU2p2kaBJjCE3%2Ff6djYNYCdQBpT9%2BhFNkrAoBiYCm3O0lXpThq4xCll88CMBsDWsmvKbR%2FpYcEpgozerrdSdaWxwsVG6HUwsC7XmrEgIg0g%2FgXUailAniWagfHnbDdSSq2XgWWw4VaWxIHQFB9amnvaZD9HG%2B1v%2FoRpNEoLlcMWGvrACzC1RZmIrS%2F6pk3mTFm2WJAA8Rwug3Vmlc7NrcthQHNPAsYowE9Jy6up5A1K3Ek8qoI9koqVopENhd5bQPQqp4gZrtIYwxKGTo6DFFs0No0x38abgSxBqhY%2BU6EVK8iU1fClVS7ABxForFh0NBapaLZ%2BSuaz%2BxSFCY1tFinXZ7fV2mAY0Hw3zWRvLCwhW7hbqCzfQA6J8yNAVEaoxWffaLKp37bMll2r9mdGusKa%2B1lC%2Fzp%2BFh%2BWmQwpN7zL8Edoki3CyBnzHtqtQQX8jVGz5QplDSFSUO5YmDa8ud%2FVOH3H65RLDlXBWGMwXGc5mKmWCwSx3FdUY0Ji8LLKZFfd1k6n7qom4A3W8ei4TWbQX8I5UZKO6AMShvGvmPv2dJ7kmRnzJlfSNCdgVg07%2FvZACmDqglPf2YKEHb%2Fcyc9WYXWC7OhiBDHMUEQUK1WqVQqVCqVBYWMt5CX01YuZZTKLVXQNLIF%2BPbcUXsBiT6KBHeIVaBAUKz%2BIPS53%2BLu7Q54DsSToARmhLgMaIUpK57%2B9BRhWOMre1x6cwqRumuICFEUEcdxY2OrvgKbl4WaAP5s9GTxX9bdtNsX%2BROj1AIrCKDhzvmgnFsuTERv99wP6gDIitYH40BDYIEAWsvIbAzGMZgpw5f%2BOGCmOsnfPgdGK%2BaXjEbhmr8pMGdBA%2FA%2FjvlyAX5igWgRDmDrqRs2rVkAYtPFHwN%2FP3%2F88ibM0gk6DgHt8bnHXHp7NMLimWc%2BoEUBPDNytHDGmD8oi8WKELVwLEIgkrpE9LvzhYiGsutBHpq7ihaMCtEqRiuLVhajhDm2FTBpxYV8jbs%2FEZMf13hu%2B2vjBQAAHjt59F%2FPav3XMyIIczNRCJSFT19Yv2lDU%2FjhNSvRiW%2Bi3LUoLxZJlMOKTzCVpBKtIjJZxOtC3BTW82E2kzSEP5MP2fHxkAOHNB3JJQ21KM2JgVbader449%2B44ebVa639mKsUccu1KSQzYsOXyxtu%2BUjXyPBxUDOo5O%2BhO2vFr8itw69He6ZFuiKBk7%2F1APsO%2FZCDB%2FeTSHhUKhG%2F8ZEEX3rCQBxz%2BlzMzocihoY16TSIQDv7zK0utOTO3KM7d97%2FtVde2bMmjj7ZwWUQAlwU3ntAov2Hbhz4p2P38L8WdEVm7pgUebAqkmiYtVxSnDkbcfzEFI7rE4XC2DkDK1xGDsLOh0KOHacp%2FLXSFQHwd1%2B1j8PvfHH9xgNrovAvcqiMQRFRd62CSHcpjh93ZjNWJIKlnmAEEKNwPHBdwXU1yaShFFpW9hjOndTs%2BHjAyVNCOq1mtXptgjf4qt3lkyePfv1rUXD3a7WZV09HgQ1FMErhzQZSo3o3xoxSTIswHIVxaHTY2dlJGIaICF5Cc2Qo4t4Hqpz8sSWTufYOPQgCjDFkMhmiKGrngEMlQRJAT9ZLvH9rsmP7Bi%2BxeZU2q5Jap1yljQCB2Kgc28o5G51%2Fu1Z78%2FVadd%2Fnn3zymTAMci%2B%2B%2BCKjo6OIWKLIoLSmI9neRm%2BjEsdxjIjQ1dXFbbfdxo4dOzh37tzMVc8HqHepVaBYCGon%2FjOo%2FSPQA6zD9XI9rtMRAcUwqBBGeWAUuAR0WBv%2Fle%2F7bNmyhZUrVzIxMcHk5CTVapUgCJobv42utVWZjVTpOA5dXV10dnayYsUKstksq1evbgJyWl%2FQJlkgP8tXsp4ClLWWMAzxPI%2B%2Bvj76%2B%2Fux1jZ7mzAMm%2Bdj1locx8Fai1IK3%2FfxfR%2BnvnlCGIZNXtALLQe1KiaXy5FMJimVSkxNTeH7Pn19fbiuS7FYpFqtorUmjmMymQypVIpKpUKhUCCKIrLZLL7vMzU11WoxtZwArLU2bmg2k8mQyWQIw5BisYjWmnQ6je%2F7lEolZmZmmn2%2B7%2FvkcjmUUoyPj6OUIpPJkE6nm02etZY4jmvLCWCmUqlcSKfTvVprDh48SBRFpFIpMpkMQRDwxhtvEMcx6XS6CaZarTI8PMzg4CC%2B79Pd3Y2IMDg4SBAEdHR0sHHjRmq1GpVK5fhyApB8Pv%2BG53m3Oo5Db29v80LD13t7e%2Bu5XGvuuusutm3bxvPPP9%2FUciM2lFKsWLECEWmuiSuVCmfPnv23ZY2Bw4cP7%2FY875FGEM5PFo3%2FjuNw%2FPhxisUihUIBY0yzdixGWmvOnz%2F%2Fo7179%2B5eVgBDQ0OHMpnMH65ateoZrXXzlHL%2BSYu1lqGhIWq1GtlstnlPa3pt%2FE4kEhQKhfLIyMinoiiaeFc%2BNdi0adOHent7HzPGbBORZEOoxd6zmDwtLXRorf3%2B2bNnnz5x4sRr8C59KzFLXl9f3625XO7nfN9%2FrzFmrVIqq5RKKaU8mSuIAiIRqYhIwVr7k1qtNlwoFA6ePn36EFBr3vhufq0yjwyQAZKAx9y9hNkjOaaBEvWlyOLzXy%2BA%2F2%2F6PzBw4Z94LQ3uAAAAAElFTkSuQmCC" style="margin-right: 4px;"/></td>
<td valign="top" width="48px"><img src="/icon_64.png" width="48px" height="48px" style="margin-right: 4px;"/></td>
<td valign="middle">
<b><div id="msg"></div></b>
<p><a id="help" href="help.html" target="_o2pTab"></a> <span id="sep">|</span>
<a id="signout" target="_o2pTab" style="color: gray;"></a></p>
<p><a id="help" href="help.html" target="_o2pTab"></a> <span id="sep" style="visibility:hidden;">|</span>
<a id="signout" target="_blank" style="color: gray;"></a></p>
</td>
</tr>
</table>

View File

@@ -8,7 +8,7 @@ var channel;
var socket;
var req = new XMLHttpRequest();
function sendToPhone(title, url, sel, msgType, listener) {
function sendToPhone( data, listener ) {
req.open('POST', sendUrl, true);
req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
req.setRequestHeader('X-Same-Domain', 'true'); // XSRF protector
@@ -25,13 +25,22 @@ function sendToPhone(title, url, sel, msgType, listener) {
listener(STATUS_DEVICE_NOT_REGISTERED);
}
} else {
listener(STATUS_GENERAL_ERROR);
listener(STATUS_GENERAL_ERROR);
}
}
};
// title, url and sel have already been encoded...
var data = 'title=' + title + '&url=' + url +
'&sel=' + sel + '&type=' + encodeURIComponent(msgType);
req.send(data);
var postData = '';
for(var key in data) {
if(postData.length > 1)
postData += '&';
if( data[key] !== null ) {
opera.postError(key + ' = ' + data[key]);
postData += key + '=' + encodeURIComponent( data[key] );
}
}
//var postData = 'title=' + data.title + '&url=' + data.url +
//'&sel=' + data.sel + '&type=' + encodeURIComponent(data.msgType);
req.send(postData);
}