mirror of
https://github.com/fergalmoran/chrometophone.git
synced 2025-12-22 09:41:51 +00:00
Version 1.0 alpha
- Core SendToPhone function has been removed from the chrome and made a module. - Support for common protocols has been added (market, sms, mms, callto) Issues - Protocol handling does not work with Firefox 4b2+ due to a change in how Gecko handles such components. - Frequent errors on send, (status 0) and (status 400)
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
content sendtophone chrome/content/
|
||||
skin sendtophone classic/1.0 chrome/skin/
|
||||
resource sendtophone modules/
|
||||
|
||||
locale sendtophone en chrome/locale/en/
|
||||
locale sendtophone de chrome/locale/de/
|
||||
locale sendtophone es chrome/locale/es/
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<groupbox align="center" orient="horizontal">
|
||||
<vbox>
|
||||
<text value="Send To Phone" style="font-weight: bold; font-size: x-large;"/>
|
||||
<text value="&version; 0.9.2"/>
|
||||
<text value="&version; 1.0 alpha"/>
|
||||
<separator class="thin"/>
|
||||
<text value="&createdBy;" style="font-weight: bold;"/>
|
||||
<text value="Alfonso Martínez de Lizarrondo & Patrick O'Reilly"/>
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
Copyright 2010 Alfonso Martínez de Lizarrondo & Patrick O'Reilly
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
sendtophone.init = function()
|
||||
{
|
||||
// Try to install the toolbar button, but only once
|
||||
@@ -6,6 +22,9 @@ sendtophone.init = function()
|
||||
this.installToolbarButton();
|
||||
this.prefs.setBoolPref( "installedButton", true ) ;
|
||||
}
|
||||
|
||||
document.getElementById("contentAreaContextMenu")
|
||||
.addEventListener("popupshowing", function (e){ sendtophone.showFirefoxContextMenu(e); }, false);
|
||||
}
|
||||
|
||||
sendtophone.installToolbarButton = function()
|
||||
@@ -35,12 +54,6 @@ sendtophone.installToolbarButton = function()
|
||||
|
||||
}
|
||||
|
||||
|
||||
sendtophone.onFirefoxLoad = function() {
|
||||
document.getElementById("contentAreaContextMenu")
|
||||
.addEventListener("popupshowing", function (e){ sendtophone.showFirefoxContextMenu(e); }, false);
|
||||
};
|
||||
|
||||
sendtophone.showFirefoxContextMenu = function(event) {
|
||||
// show or hide the menuitem based on what the context menu is on
|
||||
// see http://kb.mozillazine.org/Adding_items_to_menus
|
||||
@@ -49,4 +62,3 @@ sendtophone.showFirefoxContextMenu = function(event) {
|
||||
document.getElementById("context-sendtophone-text").hidden = !gContextMenu.isTextSelected;
|
||||
};
|
||||
|
||||
window.addEventListener("load", function(e) { sendtophone.onFirefoxLoad(e); }, false);
|
||||
|
||||
@@ -1,10 +1,24 @@
|
||||
/*
|
||||
Copyright 2010 Alfonso Martínez de Lizarrondo & Patrick O'Reilly
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
|
||||
// Core functions
|
||||
Components.utils.import("resource://sendtophone/sendtophone.js");
|
||||
|
||||
var sendtophone = {
|
||||
baseUrl : '',
|
||||
req : null,
|
||||
apiVersion : 3,
|
||||
loggedInUrl : "http://code.google.com/p/chrometophone/logo?login",
|
||||
loggedOutUrl : "http://code.google.com/p/chrometophone/logo?logout",
|
||||
apkUrl : "http://code.google.com/p/chrometophone/downloads/detail?name=chrometophone-android-v1.1.apk",
|
||||
|
||||
init: function()
|
||||
{
|
||||
@@ -20,12 +34,6 @@ var sendtophone = {
|
||||
me.prefs = Components.classes["@mozilla.org/preferences-service;1"]
|
||||
.getService(Components.interfaces.nsIPrefService)
|
||||
.getBranch("extensions.sendtophone.") ;
|
||||
// Allow the people to use their own server if they prefer to not trust this server
|
||||
me.baseUrl = me.prefs.getCharPref( "appUrl" ) ;
|
||||
|
||||
me.sendUrl = me.baseUrl + '/send?ver=' + me.apiVersion;
|
||||
me.logInUrl = me.baseUrl + '/signin?ver=' + me.apiVersion + '&extret=' + encodeURIComponent(me.loggedInUrl);
|
||||
me.logOutUrl = me.baseUrl + '/signout?ver=' + me.apiVersion + '&extret=' + encodeURIComponent(me.loggedOutUrl);
|
||||
|
||||
me.init();
|
||||
},
|
||||
@@ -52,7 +60,7 @@ var sendtophone = {
|
||||
break;
|
||||
case 'page':
|
||||
default:
|
||||
var info = sendtophone.getInfo();
|
||||
var info = this.getInfo();
|
||||
title = info.title;
|
||||
url = info.url;
|
||||
selection = info.selection;
|
||||
@@ -66,7 +74,7 @@ var sendtophone = {
|
||||
if (selection.length > max_length)
|
||||
selection = selection.substring(0, max_length);
|
||||
|
||||
this.sendToPhone(title, url, selection);
|
||||
sendtophoneCore.send(title, url, selection);
|
||||
/*
|
||||
}
|
||||
else
|
||||
@@ -85,32 +93,6 @@ var sendtophone = {
|
||||
text);
|
||||
},
|
||||
|
||||
// Shows a message in a growl-like notification
|
||||
popupNotification: function(text)
|
||||
{
|
||||
var title = this.strings.getString("SendToPhoneTitle");
|
||||
var image = "chrome://sendtophone/skin/icon.png";
|
||||
try {
|
||||
// Avoid crash on Fedora 12.
|
||||
// Reported on 8th June https://addons.mozilla.org/en-US/firefox/reviews/display/161941
|
||||
var listener = {
|
||||
observe: function(subject, topic, data) {}
|
||||
};
|
||||
|
||||
Components.classes['@mozilla.org/alerts-service;1']
|
||||
.getService(Components.interfaces.nsIAlertsService)
|
||||
.showAlertNotification(image, title, text, false, '', listener);
|
||||
} catch(e)
|
||||
{
|
||||
// prevents runtime error on platforms that don't implement nsIAlertsService
|
||||
var win = Components.classes['@mozilla.org/embedcomp/window-watcher;1']
|
||||
.getService(Components.interfaces.nsIWindowWatcher)
|
||||
.openWindow(null, 'chrome://global/content/alerts/alert.xul',
|
||||
'_blank', 'chrome,titlebar=no,popup=yes', null);
|
||||
win.arguments = [image, title, text, false, ''];
|
||||
}
|
||||
},
|
||||
|
||||
onToolbarButtonCommand: function(e) {
|
||||
// just reuse the function above.
|
||||
sendtophone.onMenuItemCommand(e, 'page');
|
||||
@@ -118,133 +100,30 @@ var sendtophone = {
|
||||
|
||||
getInfo: function() {
|
||||
var doc = gBrowser.contentDocument,
|
||||
win = doc.defaultView;
|
||||
win = doc.defaultView;
|
||||
var href = doc.location.href;
|
||||
// Is it the Google Maps page?
|
||||
if (/https?:\/\/maps\.google\..{2,3}\//.test(href))
|
||||
|
||||
if (this.isMapsURL(href))
|
||||
{
|
||||
// Then try to send the current view:
|
||||
var link = doc.getElementById('link');
|
||||
if (link && link.href)
|
||||
href = link.href;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
"title": doc.title,
|
||||
"url": href,
|
||||
"selection": win.getSelection().toString()
|
||||
};
|
||||
|
||||
},
|
||||
|
||||
processXHR: function(url, method, data, callback)
|
||||
isMapsURL: function(url)
|
||||
{
|
||||
if (!this.req)
|
||||
this.req = new XMLHttpRequest();
|
||||
|
||||
var req = this.req;
|
||||
|
||||
req.open(method, url, true);
|
||||
req.setRequestHeader('X-Extension', 'true'); // XSRF protector
|
||||
|
||||
if (method=='POST')
|
||||
req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
|
||||
|
||||
req.onreadystatechange = function()
|
||||
{
|
||||
// here this == req
|
||||
if (this.readyState == 4)
|
||||
{
|
||||
var body = req.responseText;
|
||||
if (req.status == 200)
|
||||
{
|
||||
// Check if the body is a html redirect
|
||||
var redirectMatch = body.match(/<meta http-equiv="refresh" content="\d;\s*url=(')?(.*)\1">/);
|
||||
if (redirectMatch)
|
||||
{
|
||||
var redirectUrl = redirectMatch[2].replace(/&/g, '&');
|
||||
if (redirectUrl == sendtophone.loggedOutUrl)
|
||||
{
|
||||
sendtophone.logoutSuccessful();
|
||||
return;
|
||||
}
|
||||
// Do the redirect and use the original callback
|
||||
sendtophone.processXHR( redirectUrl, 'GET', null, callback);
|
||||
}
|
||||
else
|
||||
callback.call( sendtophone, req );
|
||||
}
|
||||
else
|
||||
{
|
||||
sendtophone.alert(sendtophone.strings.getString("ErrorOnSend") + ' (status ' + req.status + ')\r\n' + body);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// To send correctly cookies.
|
||||
// Force the request to include cookies even though this chrome code
|
||||
// is seen as a third-party, so the server knows the user for which we are
|
||||
// requesting favorites (or anything else user-specific in the future).
|
||||
// This only works in Firefox 3.6; in Firefox 3.5 the request will instead
|
||||
// fail to send cookies if the user has disabled third-party cookies.
|
||||
try {
|
||||
req.channel.QueryInterface(Ci.nsIHttpChannelInternal).
|
||||
forceAllowThirdPartyCookie = true;
|
||||
}
|
||||
catch(ex) { /* user is using Firefox 3.5 */ }
|
||||
|
||||
req.send( data );
|
||||
},
|
||||
|
||||
sendToPhone: function(title, url, selection)
|
||||
{
|
||||
var data = 'title=' + encodeURIComponent(title) +
|
||||
'&url=' + encodeURIComponent(url) + '&sel=' + encodeURIComponent(selection);
|
||||
|
||||
this.pendingMessage = data;
|
||||
this.processXHR(this.sendUrl, 'POST', data, this.processSentData);
|
||||
},
|
||||
|
||||
processSentData : function(req)
|
||||
{
|
||||
var body = req.responseText;
|
||||
|
||||
if (body.substring(0, 2) == 'OK')
|
||||
{
|
||||
delete this.pendingMessage;
|
||||
this.popupNotification(this.strings.getString("InfoSent"));
|
||||
return;
|
||||
}
|
||||
if (body.indexOf('LOGIN_REQUIRED') == 0)
|
||||
{
|
||||
var me = sendtophone;
|
||||
me.popupNotification( me.strings.getString("LoginRequired") );
|
||||
var lastTab = gBrowser.tabContainer.selectedIndex;
|
||||
var tab = gBrowser.addTab(me.baseUrl + '/signin?ver=' + me.apiVersion + '&extret=' + encodeURIComponent(me.loggedInUrl));
|
||||
//Open Google login page
|
||||
gBrowser.selectedTab = tab;
|
||||
var c2pTab = gBrowser.getBrowserForTab(tab);
|
||||
//Add listener for callback URL
|
||||
c2pTab.addEventListener("load", function () {
|
||||
if(sendtophone.loggedInUrl==c2pTab.currentURI.spec){
|
||||
//Resend URL from that Tab
|
||||
sendtophone.loginSuccessful();
|
||||
//Close Google login
|
||||
gBrowser.removeCurrentTab();
|
||||
//ReFocus on tab being sent
|
||||
gBrowser.selectedTab = gBrowser.tabContainer.childNodes[lastTab];
|
||||
}
|
||||
}, true);
|
||||
return;
|
||||
}
|
||||
if (body.indexOf('DEVICE_NOT_REGISTERED') == 0)
|
||||
{
|
||||
this.popupNotification(this.strings.getString("DeviceNotRegistered"));
|
||||
|
||||
var tab = gBrowser.addTab( this.apkUrl );
|
||||
gBrowser.selectedTab = tab;
|
||||
return;
|
||||
}
|
||||
|
||||
this.alert(this.strings.getString("ErrorOnSend") + '\r\n' + body);
|
||||
return url.match("http://maps\\.google\\.[a-z]{2,3}(\\.[a-z]{2})?[/?].*") || url.match("http://www\\.google\\.[a-z]{2,3}(\\.[a-z]{2})?/maps.*");
|
||||
},
|
||||
|
||||
initPopup: function()
|
||||
@@ -255,46 +134,9 @@ var sendtophone = {
|
||||
|
||||
logout: function()
|
||||
{
|
||||
var lastTab = gBrowser.tabContainer.selectedIndex;
|
||||
var tab = gBrowser.addTab(this.logOutUrl);
|
||||
// Open Google logout page
|
||||
gBrowser.selectedTab = tab;
|
||||
var c2pTab = gBrowser.getBrowserForTab(tab);
|
||||
//Add listener for callback URL
|
||||
c2pTab.addEventListener("load", function () {
|
||||
if(sendtophone.loggedOutUrl==c2pTab.currentURI.spec){
|
||||
sendtophone.logoutSuccessful();
|
||||
|
||||
// Close logout tab
|
||||
gBrowser.removeCurrentTab();
|
||||
// ReFocus on tab being sent
|
||||
gBrowser.selectedTab = gBrowser.tabContainer.childNodes[lastTab];
|
||||
}
|
||||
}, true);
|
||||
|
||||
/*
|
||||
// This doesn't work if third party cookies are bloqued. Why???
|
||||
this.processXHR(this.logOutUrl, 'GET', null, function(req)
|
||||
{
|
||||
// This will be called only if there's a problem
|
||||
this.alert(this.strings.getString("LogoutError") + '\r\n' + req.responseText );
|
||||
});
|
||||
*/
|
||||
},
|
||||
|
||||
logoutSuccessful: function()
|
||||
{
|
||||
this.popupNotification(this.strings.getString("LogoutSuccessful"));
|
||||
},
|
||||
|
||||
|
||||
loginSuccessful: function()
|
||||
{
|
||||
this.popupNotification( this.strings.getString("LoginSuccessful") );
|
||||
|
||||
// Send pending message
|
||||
this.processXHR(this.sendUrl, 'POST', this.pendingMessage, this.processSentData);
|
||||
sendtophoneCore.logout();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
window.addEventListener("load", sendtophone.onLoad, false);
|
||||
|
||||
285
third_party/firefox_sendtophone/components/protocoltophone.js
vendored
Normal file
285
third_party/firefox_sendtophone/components/protocoltophone.js
vendored
Normal file
@@ -0,0 +1,285 @@
|
||||
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (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.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the MLDonkey protocol handler 2.5.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Simon Peter <dn.tlp@gmx.net>.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2003 - 2008
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Sven Koch
|
||||
* Len Walter <len@unsw.edu.au>
|
||||
* Dan Fritz <templar_of_ni@yahoo.se>
|
||||
* David Ciecierski <dawid.ciecierski@gmail.com>
|
||||
* Dennis Plöger <dennis@dieploegers.de>
|
||||
* Dominik Röttsches <d-r@roettsches.de>
|
||||
* Stefan Huber <stef@efan.ch>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/***** Defines *****/
|
||||
|
||||
// components defined in this file
|
||||
const MARKETPROT_HANDLER_CONTRACTID =
|
||||
"@mozilla.org/network/protocol;1?name=market";
|
||||
const MARKETPROT_HANDLER_CID =
|
||||
Components.ID("{76A4F09C-9B67-11DF-A9F4-6018E0D72085}");
|
||||
|
||||
const SMSPROT_HANDLER_CONTRACTID =
|
||||
"@mozilla.org/network/protocol;1?name=sms";
|
||||
const SMSPROT_HANDLER_CID =
|
||||
Components.ID("{85F1603A-9B67-11DF-96B2-6118E0D72085}");
|
||||
|
||||
const SMSTOPROT_HANDLER_CONTRACTID =
|
||||
"@mozilla.org/network/protocol;1?name=smsto";
|
||||
const SMSTOPROT_HANDLER_CID =
|
||||
Components.ID("{8A9EB484-9B67-11DF-9BAE-8818E0D72085}");
|
||||
|
||||
const MMSPROT_HANDLER_CONTRACTID =
|
||||
"@mozilla.org/network/protocol;1?name=mms";
|
||||
const MMSPROT_HANDLER_CID =
|
||||
Components.ID("{A47959A0-9B70-11DF-92BC-6721E0D72085}");
|
||||
|
||||
const MMSTOPROT_HANDLER_CONTRACTID =
|
||||
"@mozilla.org/network/protocol;1?name=mmsto";
|
||||
const MMSTOPROT_HANDLER_CID =
|
||||
Components.ID("{A9CE57D4-9B70-11DF-8AF1-6821E0D72085}");
|
||||
|
||||
const CALLTOPROT_HANDLER_CONTRACTID =
|
||||
"@mozilla.org/network/protocol;1?name=callto";
|
||||
const CALLTOPROT_HANDLER_CID =
|
||||
Components.ID("{E8763476-9B6A-11DF-86FD-B81BE0D72085}");
|
||||
|
||||
// components used in this file
|
||||
const NS_IOSERVICE_CID = "{7fe2aeb0-95d1-11df-981c-0800200c9a66}";
|
||||
const NS_PREFSERVICE_CONTRACTID = "@mozilla.org/preferences-service;1";
|
||||
const URI_CONTRACTID = "@mozilla.org/network/simple-uri;1";
|
||||
const NS_WINDOWWATCHER_CONTRACTID = "@mozilla.org/embedcomp/window-watcher;1";
|
||||
const INPUTSTREAMCHANNEL_CONTRACTID = "@mozilla.org/network/input-stream-channel;1";
|
||||
const CATEGORY_MANAGER_CONTRACTID = "@mozilla.org/categorymanager;1";
|
||||
const HTTP_HANDLER_CONTRACTID = "@mozilla.org/network/protocol;1?name=http";
|
||||
|
||||
// interfaces used in this file
|
||||
const nsIProtocolHandler = Components.interfaces.nsIProtocolHandler;
|
||||
const nsIURI = Components.interfaces.nsIURI;
|
||||
const nsIPrefService = Components.interfaces.nsIPrefService;
|
||||
const nsIWindowWatcher = Components.interfaces.nsIWindowWatcher;
|
||||
const nsIChannel = Components.interfaces.nsIChannel;
|
||||
const nsIContentPolicy = Components.interfaces.nsIContentPolicy;
|
||||
|
||||
// some misc. constants
|
||||
const PREF_BRANCH = "extensions.sendtophone.";
|
||||
|
||||
/***** PhoneByProtocolHandler *****/
|
||||
|
||||
function PhoneByProtocolHandler(scheme)
|
||||
{
|
||||
this.scheme = scheme;
|
||||
}
|
||||
|
||||
// attribute defaults
|
||||
PhoneByProtocolHandler.prototype.defaultPort = -1;
|
||||
PhoneByProtocolHandler.prototype.protocolFlags = nsIProtocolHandler.URI_NORELATIVE;
|
||||
PhoneByProtocolHandler.prototype.withinLoad = false;
|
||||
|
||||
PhoneByProtocolHandler.prototype.newURI = function(aSpec, aCharset, aBaseURI)
|
||||
{
|
||||
var uri = Components.classes[URI_CONTRACTID].createInstance(nsIURI);
|
||||
uri.spec = aSpec;
|
||||
return uri;
|
||||
}
|
||||
|
||||
PhoneByProtocolHandler.prototype.loadPhoneToProtocol = function(aURI)
|
||||
{
|
||||
var s2pTitle;
|
||||
var s2pURL = encodeURIComponent(decodeURI(aURI.spec));
|
||||
|
||||
// read preferences again (otherwise saved settings won't be used until after restart
|
||||
ProtocolToPhoneModule.readPreferences(PREF_BRANCH);
|
||||
|
||||
// Core functions
|
||||
if (typeof sendtophoneCore == "undefined")
|
||||
Components.utils.import("resource://sendtophone/sendtophone.js");
|
||||
|
||||
if (!s2pURL.indexOf('market')){
|
||||
s2pTitle = "Market Link";
|
||||
}
|
||||
else if (!s2pURL.indexOf('sms')){
|
||||
s2pTitle = "Send SMS";
|
||||
}
|
||||
else if (!s2pURL.indexOf('mms')){
|
||||
s2pTitle = "Send MMS";
|
||||
}
|
||||
else if (!s2pURL.indexOf('call')){
|
||||
s2pTitle = "Call Number";
|
||||
}
|
||||
else{
|
||||
s2pTitle = "Other";
|
||||
}
|
||||
|
||||
sendtophoneCore.send(s2pTitle, cfgUrl + s2pURL, "")
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
PhoneByProtocolHandler.prototype.newChannel = function(aURI)
|
||||
{
|
||||
// pass URI to PhoneToProtocol
|
||||
var chan = this.loadPhoneToProtocol(aURI);
|
||||
|
||||
// return a fake empty channel so current window doesn't change
|
||||
if(chan == null) chan = Components.classes[INPUTSTREAMCHANNEL_CONTRACTID].createInstance(nsIChannel);
|
||||
return chan;
|
||||
}
|
||||
|
||||
/***** PhoneByProtocolHandlerFactory *****/
|
||||
|
||||
function PhoneByProtocolHandlerFactory(scheme)
|
||||
{
|
||||
this.scheme = scheme;
|
||||
}
|
||||
|
||||
PhoneByProtocolHandlerFactory.prototype.createInstance = function(outer, iid)
|
||||
{
|
||||
if(outer != null) throw Components.results.NS_ERROR_NO_AGGREGATION;
|
||||
|
||||
if(!iid.equals(nsIProtocolHandler) && !iid.equals(nsIContentPolicy))
|
||||
throw Components.results.NS_ERROR_INVALID_ARG;
|
||||
|
||||
return new PhoneByProtocolHandler(this.scheme);
|
||||
}
|
||||
|
||||
var factory_market = new PhoneByProtocolHandlerFactory("market");
|
||||
var factory_sms = new PhoneByProtocolHandlerFactory("sms");
|
||||
var factory_smsto = new PhoneByProtocolHandlerFactory("smsto");
|
||||
var factory_mms = new PhoneByProtocolHandlerFactory("mms");
|
||||
var factory_mmsto = new PhoneByProtocolHandlerFactory("mmsto");
|
||||
var factory_callto = new PhoneByProtocolHandlerFactory("callto");
|
||||
|
||||
/***** ProtocolToPhoneModule *****/
|
||||
|
||||
var ProtocolToPhoneModule = new Object();
|
||||
|
||||
ProtocolToPhoneModule.readPreferences = function(pref_branch)
|
||||
{
|
||||
// get preferences branch
|
||||
var PrefService = Components.classes[NS_PREFSERVICE_CONTRACTID].getService(nsIPrefService);
|
||||
var myPrefs = PrefService.getBranch(null); // Mozilla bug #107617
|
||||
|
||||
// read preferences (if available)
|
||||
if(myPrefs.getPrefType(pref_branch + "url") == myPrefs.PREF_STRING)
|
||||
cfgUrl = myPrefs.getCharPref(pref_branch + "url");
|
||||
if(myPrefs.getPrefType(pref_branch + "protocols") == myPrefs.PREF_STRING)
|
||||
cfgProtocols = myPrefs.getCharPref(pref_branch + "protocols");
|
||||
}
|
||||
|
||||
ProtocolToPhoneModule.registerSelf = function(compMgr, fileSpec, location, type)
|
||||
{
|
||||
compMgr = compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
|
||||
|
||||
// register market protocol handler
|
||||
compMgr.registerFactoryLocation(MARKETPROT_HANDLER_CID,
|
||||
"market protocol handler",
|
||||
MARKETPROT_HANDLER_CONTRACTID,
|
||||
fileSpec, location, type);
|
||||
|
||||
// register sms protocol handler
|
||||
compMgr.registerFactoryLocation(SMSPROT_HANDLER_CID,
|
||||
"sms protocol handler",
|
||||
SMSPROT_HANDLER_CONTRACTID,
|
||||
fileSpec, location, type);
|
||||
|
||||
// register smsto protocol handler
|
||||
compMgr.registerFactoryLocation(SMSTOPROT_HANDLER_CID,
|
||||
"smsto protocol handler",
|
||||
SMSTOPROT_HANDLER_CONTRACTID,
|
||||
fileSpec, location, type);
|
||||
// register mms protocol handler
|
||||
compMgr.registerFactoryLocation(MMSPROT_HANDLER_CID,
|
||||
"mms protocol handler",
|
||||
MMSPROT_HANDLER_CONTRACTID,
|
||||
fileSpec, location, type);
|
||||
|
||||
// register mmsto protocol handler
|
||||
compMgr.registerFactoryLocation(MMSTOPROT_HANDLER_CID,
|
||||
"mmsto protocol handler",
|
||||
MMSTOPROT_HANDLER_CONTRACTID,
|
||||
fileSpec, location, type);
|
||||
// register callto protocol handler
|
||||
compMgr.registerFactoryLocation(CALLTOPROT_HANDLER_CID,
|
||||
"calltoo protocol handler",
|
||||
CALLTOPROT_HANDLER_CONTRACTID,
|
||||
fileSpec, location, type);
|
||||
}
|
||||
|
||||
ProtocolToPhoneModule.unregisterSelf = function(compMgr, fileSpec, location)
|
||||
{
|
||||
compMgr = compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
|
||||
|
||||
// unregister our components
|
||||
compMgr.unregisterFactoryLocation(MARKETPROT_HANDLER_CID, fileSpec);
|
||||
compMgr.unregisterFactoryLocation(SMSPROT_HANDLER_CID, fileSpec);
|
||||
compMgr.unregisterFactoryLocation(SMSTOPROT_HANDLER_CID, fileSpec);
|
||||
compMgr.unregisterFactoryLocation(MMSPROT_HANDLER_CID, fileSpec);
|
||||
compMgr.unregisterFactoryLocation(MMSTOPROT_HANDLER_CID, fileSpec);
|
||||
compMgr.unregisterFactoryLocation(CALLTOPROT_HANDLER_CID, fileSpec);
|
||||
|
||||
}
|
||||
|
||||
ProtocolToPhoneModule.getClassObject = function(compMgr, cid, iid)
|
||||
{
|
||||
|
||||
if(!iid.equals(Components.interfaces.nsIFactory))
|
||||
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
// read preferences
|
||||
this.readPreferences(PREF_BRANCH);
|
||||
|
||||
// return protocol handler factories
|
||||
// To disable a protocol simply comment the line out.
|
||||
if(cid.equals(MARKETPROT_HANDLER_CID)) { if(cfgProtocols.search("market") != -1) return factory_market; else return null; }
|
||||
if(cid.equals(SMSPROT_HANDLER_CID)) { if(cfgProtocols.search("sms") != -1) return factory_sms; else return null; }
|
||||
if(cid.equals(SMSTOPROT_HANDLER_CID)) { if (cfgProtocols.search("smsto") != -1) return factory_smsto; else return null; }
|
||||
if(cid.equals(MMSPROT_HANDLER_CID)) { if(cfgProtocols.search("mms") != -1) return factory_mms; else return null; }
|
||||
if(cid.equals(MMSTOPROT_HANDLER_CID)) { if (cfgProtocols.search("mmsto") != -1) return factory_mmsto; else return null; }
|
||||
if(cid.equals(CALLTOPROT_HANDLER_CID)) { if (cfgProtocols.search("callto") != -1) return factory_callto; else return null; }
|
||||
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
|
||||
ProtocolToPhoneModule.canUnload = function(compMgr)
|
||||
{
|
||||
return true; // our objects can be unloaded
|
||||
}
|
||||
|
||||
/***** Entrypoint *****/
|
||||
|
||||
function NSGetModule(compMgr, fileSpec)
|
||||
{
|
||||
return ProtocolToPhoneModule;
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
pref("extensions.sendtophone.installedButton", false);
|
||||
pref("extensions.sendtophone.appUrl", "https://chrometophone.appspot.com");
|
||||
pref("extensions.sendtophone.url", "http://smallroomstudios.net/s2p.php?ml=");
|
||||
pref("extensions.sendtophone.protocols", "market smsto sms mms mmsto callto");
|
||||
|
||||
// https://developer.mozilla.org/en/Localizing_extension_descriptions
|
||||
pref("extensions.sendtophone@martinezdelizarrondo.com.description", "chrome://sendtophone/locale/overlay.properties");
|
||||
|
||||
4
third_party/firefox_sendtophone/install.rdf
vendored
4
third_party/firefox_sendtophone/install.rdf
vendored
@@ -4,7 +4,7 @@
|
||||
<em:id>sendtophone@martinezdelizarrondo.com</em:id>
|
||||
<em:type>2</em:type>
|
||||
<em:name>Send To Phone</em:name>
|
||||
<em:version>0.9.2</em:version>
|
||||
<em:version>1.0 alpha</em:version>
|
||||
<em:creator>Alfonso Martínez de Lizarrondo</em:creator>
|
||||
<em:contributor>Patrick O'Reilly</em:contributor>
|
||||
<em:description>Send links to your Android 2.2 phone using the new C2DM service. Based on the ChromeToPhone extension.</em:description>
|
||||
@@ -14,7 +14,7 @@
|
||||
<Description>
|
||||
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id> <!-- Firefox -->
|
||||
<em:minVersion>3.0</em:minVersion>
|
||||
<em:maxVersion>4.0b2pre</em:maxVersion>
|
||||
<em:maxVersion>3.8.6</em:maxVersion>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
</Description>
|
||||
|
||||
248
third_party/firefox_sendtophone/modules/sendtophone.js
vendored
Normal file
248
third_party/firefox_sendtophone/modules/sendtophone.js
vendored
Normal file
@@ -0,0 +1,248 @@
|
||||
/*
|
||||
Copyright 2010 Alfonso Martínez de Lizarrondo & Patrick O'Reilly
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
// https://developer.mozilla.org/en/JavaScript_code_modules/Using_JavaScript_code_modules
|
||||
var EXPORTED_SYMBOLS = ["sendtophoneCore"];
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
|
||||
var sendtophoneCore = {
|
||||
req : null,
|
||||
apiVersion : 4,
|
||||
loggedInUrl : "http://code.google.com/p/chrometophone/logo?login",
|
||||
loggedOutUrl : "http://code.google.com/p/chrometophone/logo?logout",
|
||||
apkUrl : "http://code.google.com/p/chrometophone/downloads/detail?name=chrometophone-android-v1.2.apk",
|
||||
|
||||
init: function()
|
||||
{
|
||||
this.strings = Cc["@mozilla.org/intl/stringbundle;1"]
|
||||
.getService(Ci.nsIStringBundleService)
|
||||
.createBundle("chrome://sendtophone/locale/overlay.properties");
|
||||
|
||||
var prefs = Cc["@mozilla.org/preferences-service;1"]
|
||||
.getService(Ci.nsIPrefService)
|
||||
.getBranch("extensions.sendtophone.") ;
|
||||
|
||||
// Allow the people to use their own server if they prefer to not trust this server
|
||||
var baseUrl = prefs.getCharPref( "appUrl" ) ;
|
||||
|
||||
this.sendUrl = baseUrl + '/send?ver=' + this.apiVersion;
|
||||
this.logInUrl = baseUrl + '/signin?ver=' + this.apiVersion + '&extret=' + encodeURIComponent(this.loggedInUrl);
|
||||
this.logOutUrl = baseUrl + '/signout?ver=' + this.apiVersion + '&extret=' + encodeURIComponent(this.loggedOutUrl);
|
||||
},
|
||||
|
||||
getString: function(name)
|
||||
{
|
||||
return this.strings.GetStringFromName(name);
|
||||
},
|
||||
|
||||
// Shows a message in a modal alert
|
||||
alert: function(text)
|
||||
{
|
||||
var promptService = Cc["@mozilla.org/embedcomp/prompt-service;1"]
|
||||
.getService(Ci.nsIPromptService);
|
||||
promptService.alert(null, this.getString("SendToPhoneTitle"),
|
||||
text);
|
||||
},
|
||||
|
||||
// Shows a message in a growl-like notification
|
||||
popupNotification: function(text)
|
||||
{
|
||||
var title = this.getString("SendToPhoneTitle");
|
||||
var image = "chrome://sendtophone/skin/icon.png";
|
||||
try {
|
||||
// Avoid crash on Fedora 12.
|
||||
// Reported on 8th June https://addons.mozilla.org/en-US/firefox/reviews/display/161941
|
||||
var listener = {
|
||||
observe: function(subject, topic, data) {}
|
||||
};
|
||||
|
||||
Cc['@mozilla.org/alerts-service;1']
|
||||
.getService(Ci.nsIAlertsService)
|
||||
.showAlertNotification(image, title, text, false, '', listener);
|
||||
} catch(e)
|
||||
{
|
||||
// prevents runtime error on platforms that don't implement nsIAlertsService
|
||||
var win = Cc['@mozilla.org/embedcomp/window-watcher;1']
|
||||
.getService(Ci.nsIWindowWatcher)
|
||||
.openWindow(null, 'chrome://global/content/alerts/alert.xul',
|
||||
'_blank', 'chrome,titlebar=no,popup=yes', null);
|
||||
win.arguments = [image, title, text, false, ''];
|
||||
}
|
||||
},
|
||||
|
||||
processXHR: function(url, method, data, callback)
|
||||
{
|
||||
if (!this.req)
|
||||
this.req = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]
|
||||
.createInstance(Ci.nsIXMLHttpRequest);
|
||||
|
||||
var req = this.req;
|
||||
|
||||
req.open(method, url, true);
|
||||
req.setRequestHeader('X-Same-Domain', 'true'); // XSRF protector
|
||||
|
||||
if (method=='POST')
|
||||
req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
|
||||
|
||||
req.onreadystatechange = function()
|
||||
{
|
||||
// here this == req
|
||||
if (this.readyState == 4)
|
||||
{
|
||||
var body = req.responseText;
|
||||
if (req.status == 200)
|
||||
{
|
||||
// Check if the body is a html redirect
|
||||
var redirectMatch = body.match(/<meta http-equiv="refresh" content="\d;\s*url=(')?(.*)\1">/);
|
||||
if (redirectMatch)
|
||||
{
|
||||
var redirectUrl = redirectMatch[2].replace(/&/g, '&');
|
||||
if (redirectUrl == sendtophoneCore.loggedOutUrl)
|
||||
{
|
||||
sendtophoneCore.logoutSuccessful();
|
||||
return;
|
||||
}
|
||||
// Do the redirect and use the original callback
|
||||
sendtophoneCore.processXHR( redirectUrl, 'GET', null, callback);
|
||||
}
|
||||
else
|
||||
callback.call( sendtophoneCore, req );
|
||||
}
|
||||
else
|
||||
{
|
||||
sendtophoneCore.alert(sendtophoneCore.getString("ErrorOnSend") + ' (status ' + req.status + ')\r\n' + body);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// To send correctly cookies.
|
||||
// Force the request to include cookies even though this chrome code
|
||||
// is seen as a third-party, so the server knows the user for which we are
|
||||
// requesting favorites (or anything else user-specific in the future).
|
||||
// This only works in Firefox 3.6; in Firefox 3.5 the request will instead
|
||||
// fail to send cookies if the user has disabled third-party cookies.
|
||||
try {
|
||||
req.channel.QueryInterface(Ci.nsIHttpChannelInternal).
|
||||
forceAllowThirdPartyCookie = true;
|
||||
}
|
||||
catch(ex) { /* user is using Firefox 3.5 */ }
|
||||
|
||||
req.send( data );
|
||||
},
|
||||
|
||||
// Main function
|
||||
// This is the only method that has to be called from outside this module
|
||||
send: function(title, url, selection)
|
||||
{
|
||||
if (!this.sendUrl)
|
||||
this.init();
|
||||
|
||||
var data = 'title=' + encodeURIComponent(title) +
|
||||
'&url=' + encodeURIComponent(url) + '&sel=' + encodeURIComponent(selection);
|
||||
|
||||
this.pendingMessage = data;
|
||||
this.processXHR(this.sendUrl, 'POST', data, this.processSentData);
|
||||
},
|
||||
|
||||
processSentData : function(req)
|
||||
{
|
||||
var body = req.responseText;
|
||||
|
||||
if (body.substring(0, 2) == 'OK')
|
||||
{
|
||||
delete this.pendingMessage;
|
||||
this.popupNotification(this.getString("InfoSent"));
|
||||
return;
|
||||
}
|
||||
if (body.indexOf('LOGIN_REQUIRED') == 0)
|
||||
{
|
||||
this.popupNotification( this.getString("LoginRequired") );
|
||||
|
||||
//Open Google login page and close tab when done
|
||||
this.openTab(this.logInUrl, this.loggedInUrl, function() {sendtophoneCore.loginSuccessful();} );
|
||||
|
||||
return;
|
||||
}
|
||||
if (body.indexOf('DEVICE_NOT_REGISTERED') == 0)
|
||||
{
|
||||
this.popupNotification(this.getString("DeviceNotRegistered"));
|
||||
|
||||
// Open tab with apk download
|
||||
this.openTab(me.apkUrl);
|
||||
return;
|
||||
}
|
||||
|
||||
this.alert(this.getString("ErrorOnSend") + '\r\n' + body);
|
||||
},
|
||||
|
||||
logout: function()
|
||||
{
|
||||
// Open Google logout page, and close tab when finished
|
||||
this.openTab(this.logOutUrl, this.loggedOutUrl, function() {sendtophoneCore.logoutSuccessful();} );
|
||||
|
||||
/*
|
||||
// This doesn't work if third party cookies are bloqued. Why???
|
||||
this.processXHR(this.logOutUrl, 'GET', null, function(req)
|
||||
{
|
||||
// This will be called only if there's a problem
|
||||
this.alert(this.getString("LogoutError") + '\r\n' + req.responseText );
|
||||
});
|
||||
*/
|
||||
},
|
||||
|
||||
openTab: function(url, successUrl, callback)
|
||||
{
|
||||
var gBrowser = Cc["@mozilla.org/embedcomp/window-watcher;1"]
|
||||
.getService(Components.interfaces.nsIWindowWatcher)
|
||||
.activeWindow
|
||||
.gBrowser;
|
||||
|
||||
var lastTab = gBrowser.tabContainer.selectedIndex;
|
||||
var tab = gBrowser.addTab(url);
|
||||
gBrowser.selectedTab = tab;
|
||||
|
||||
if (successUrl && callback)
|
||||
{
|
||||
var c2pTab = gBrowser.getBrowserForTab(tab);
|
||||
//Add listener for callback URL
|
||||
c2pTab.addEventListener("load", function () {
|
||||
if(successUrl==c2pTab.currentURI.spec){
|
||||
callback();
|
||||
|
||||
// Close tab
|
||||
gBrowser.removeCurrentTab();
|
||||
// ReFocus on tab being sent
|
||||
gBrowser.selectedTab = gBrowser.tabContainer.childNodes[lastTab];
|
||||
}
|
||||
}, true);
|
||||
}
|
||||
},
|
||||
|
||||
logoutSuccessful: function()
|
||||
{
|
||||
this.popupNotification(this.getString("LogoutSuccessful"));
|
||||
},
|
||||
|
||||
loginSuccessful: function()
|
||||
{
|
||||
this.popupNotification( this.getString("LoginSuccessful") );
|
||||
|
||||
// Send pending message
|
||||
this.processXHR(this.sendUrl, 'POST', this.pendingMessage, this.processSentData);
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user