diff --git a/third_party/operatophone/config.xml b/third_party/operatophone/config.xml new file mode 100644 index 0000000..b53300d --- /dev/null +++ b/third_party/operatophone/config.xml @@ -0,0 +1,27 @@ + + + Opera to Phone + 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. + Rich Tibbett + + + +Copyright 2010 Opera Software ASA. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +Portions of this work are modifications based on work created and shared +by Google and used according to terms described in the Creative Commons 3.0 +Attribution License. + + diff --git a/third_party/operatophone/constants.js b/third_party/operatophone/constants.js new file mode 100644 index 0000000..e37f833 --- /dev/null +++ b/third_party/operatophone/constants.js @@ -0,0 +1,32 @@ +/* + * 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 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 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); diff --git a/third_party/operatophone/help.html b/third_party/operatophone/help.html new file mode 100644 index 0000000..b8b57d5 --- /dev/null +++ b/third_party/operatophone/help.html @@ -0,0 +1,46 @@ + + + Opera to Phone + + + +

Opera to Phone Extension - Help

+ +

Welcome to Opera to Phone.

+ +

+ This extension adds a button to Opera that allows users to send links from their Opera desktop browser to their Android device using Android's Cloud to Device Messaging service. +

+

+ You need to install the Chrome to Phone Android application on your + phone for this extension to work. The application can be downloaded from Android Market (search for 'Chrome to Phone'). Requires a mobile + phone running Android 2.2 ("Froyo") or later. +

+ +

Extension Features:

+ + + +

Requirements

+ + + +

+ *** This is an experimental port of the Chrome to Phone extension to Opera 11 but it has been tested and is working *** +

+ +

If you have any questions, comments or feedback, please email me at richt@opera.com. + + + \ No newline at end of file diff --git a/third_party/operatophone/icon.png b/third_party/operatophone/icon.png new file mode 100644 index 0000000..a7ac15e Binary files /dev/null and b/third_party/operatophone/icon.png differ diff --git a/third_party/operatophone/icon_64.png b/third_party/operatophone/icon_64.png new file mode 100644 index 0000000..d6f08cd Binary files /dev/null and b/third_party/operatophone/icon_64.png differ diff --git a/third_party/operatophone/includes/operatophone.js b/third_party/operatophone/includes/operatophone.js new file mode 100644 index 0000000..609f6d4 --- /dev/null +++ b/third_party/operatophone/includes/operatophone.js @@ -0,0 +1,64 @@ +// ==UserScript== +// @include * +// ==/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'; + +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 pageInfo = { + action: ACTION_SEND_PAGE, + data: { + link: encodeURIComponent(currentUrl), + title: encodeURIComponent(document.title), + selection: encodeURIComponent(window.getSelection()) + } + }; + + // URL overrides + if (currentUrl.match(/^http[s]?:\/\/maps\.google\./) || + currentUrl.match(/^http[s]?:\/\/www\.google\.[a-z]{2,3}(\.[a-z]{2})\/maps/)) { + var link = document.getElementById('link'); + if (link && link.href) + pageInfo.data.link = encodeURIComponent(link.href); + } + + opera.extension.postMessage(pageInfo); + } +}, false); + +//opera.postError("UserJS loaded: " + window.location.href + " / " + window.top.userJS_UUID); \ No newline at end of file diff --git a/third_party/operatophone/index.html b/third_party/operatophone/index.html new file mode 100644 index 0000000..6db3e47 --- /dev/null +++ b/third_party/operatophone/index.html @@ -0,0 +1,108 @@ + + + + + + + + + + diff --git a/third_party/operatophone/popup.html b/third_party/operatophone/popup.html new file mode 100644 index 0000000..324b990 --- /dev/null +++ b/third_party/operatophone/popup.html @@ -0,0 +1,114 @@ + + + + + + + + + + + + + +
+
+

| +

+
+ + \ No newline at end of file diff --git a/third_party/operatophone/send_logic.js b/third_party/operatophone/send_logic.js new file mode 100644 index 0000000..b9c570e --- /dev/null +++ b/third_party/operatophone/send_logic.js @@ -0,0 +1,37 @@ +/* + * 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 channel; +var socket; +var req = new XMLHttpRequest(); + +function sendToPhone(title, url, sel, msgType, listener) { + req.open('POST', sendUrl, true); + req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); + req.setRequestHeader('X-Same-Domain', 'true'); // XSRF protector + + req.onreadystatechange = function() { + if (this.readyState == 4) { + if (req.status == 200) { + var body = req.responseText; + if (body.indexOf('OK') == 0) { + listener(STATUS_SUCCESS); + } else if (body.indexOf('LOGIN_REQUIRED') == 0) { + listener(STATUS_LOGIN_REQUIRED); + } else if (body.indexOf('DEVICE_NOT_REGISTERED') == 0) { + listener(STATUS_DEVICE_NOT_REGISTERED); + } + } else { + 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); +}