Opera 15+ Extension tabs.sendMessage works only after browser restart - macos

I reworked the "Clip to DEVONthink" to use in Opera 15+. The problem I'm left with is that the extension only works after a browser restart.
Update 1: Tested on Mac OS X 10.9.2 with Opera 21.0.1432.67, Opera Next 22.0.1471.40 and Google Chrome 35.0.1916.114. They all behave the same.
Update 2: Opera's own example for message passing got the same behavior. I'm left with the question if that's the expected behavior.
There's a background script defined in manifest.json:
"background": {
"scripts": [ "main.js" ]
},
and a content script:
"content_scripts": [ {
"js": [ "add_listener.js" ],
"matches": [ "http://*/*", "https://*/*" ],
}],
... and in main.js in chrome.browserAction.onClicked.addListener a message is send to the content script to request page title & content, etc.
chrome.browserAction.onClicked.addListener(
function (tab) {
chrome.tabs.sendMessage(tab.id, {line: 'getdevonthinkurl' });
}
);
... and the content script sends a message back:
chrome.runtime.onMessage.addListener(
function (request, sender){
if (request.line=='getdevonthinkurl'){
chrome.runtime.sendMessage({devonthinkurl:getDEVONthinkURL()});
}
}
);
... and that message is received by the main.js background script:
chrome.runtime.onMessage.addListener(
function (request, sender) {
if (request.devonthinkurl){
chrome.tabs.update(sender.tab.id, {"url": request.devonthinkurl});
}
}
);
As mentioned above it works perfect after a browser restart but it don't understand why it won't work without.
Does anyone have got an idea (I may add I'm not strong at programming and there's maybe an fundamental flaw in the design)?

The only thing which comes to my mind is that you reloading extension, but just after this step you are not refreshing page where content script is injected. Is there any error in background page? I tried several times and it works for me. Anyway you can use callback in message which can be more readable.
So main.js can look like:
chrome.browserAction.onClicked.addListener(function (tab) {
chrome.tabs.sendMessage(tab.id, {line: 'getdevonthinkurl'},
function(response){
chrome.tabs.update(tab.id, {'url': request.devonthinkurl});
});
});
And add_listener.js like this:
chrome.runtime.onMessage.addListener(
function (request, sender, sendResponse){
if (request.line=='getdevonthinkurl'){
sendResponse({devonthinkurl:getDEVONthinkURL()});
}
}
);

Related

Uncaught (in promise) DOMException When Initiating pushManager.subscribe

I'm trying to add push messaging to my service worker and facing issue that is eluding me since last night.
In my main HTML file, I have the following -
<script>
if('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/service-worker.js', {scope: '/pwa/'}).then(registration => {
console.log('Service Worker Registered: ', registration);
registration.pushManager.subscribe({userVisibleOnly:true});
});
})
}
</script>
I do get "Service Worker Registered" message on the console. Which means the registration is successful. Chrome however follows it with following line that doesn't say anything about the error -
Uncaught (in promise) DOMException (index):1
Clicking on the (index):1 takes me to the top of corresponding page /pwa/, and highlights the <!DOCTYPE html>.
It does not give me any meaningful information to investigate the issue further.
Would appreciate if you could guide me in fixing this issue. I'll paste the rest of my code and setup below.
Backend framework: Laravel.
Entry in my webpack.mix.js
const workboxPlugin = require('workbox-webpack-plugin');
mix.webpackConfig({
plugins: [
new workboxPlugin.InjectManifest({
swSrc: 'public/service-worker-offline.js', // more control over the caching
swDest: 'service-worker.js', // the service-worker file name
importsDirectory: 'service-worker-assets' // have a dedicated folder for sw files
})
],
output: {
publicPath: '' // Refer: https://github.com/GoogleChrome/workbox/issues/1534
}
});
Entry in my service-worker-offline.js -
workbox.skipWaiting();
workbox.clientsClaim();
// some other entries, followed by
self.addEventListener('push', (event) => {
const title = 'Aha! Push Notifications with Service Worker';
const options = {
'body' : event.data.text()
};
event.waitUntil(self.registration.showNotification(title, options))
});
I look forward to your responses and thank you in advance for your help.
Addendum:
I did further investigation and found out that if I do -
Notification.requestPermission().then(function(permission) {
registration.pushManager.subscribe({userVisibleOnly: true});
})
then the push notification works; but the error still remains. However, the error now points to registration.pushManager.subscribe({userVisibleOnly: true}); line in the JS. What could be the reason?
The DOMException has details that are not always visible. Catch your DOMException, and make sure to log the message to the console. It will generally be much more informative. In my case, the "Registration failed - permission denied" message reminded me that I had blocked all notifications in my chrome settings.
If you are using react, fix serviceWorker.unregister () with serviceWorker.register () in index.js. I solved it like this

Read SSL Certificates in a Firefox Extension

I am working on a Firefox extension that would display the SSL certificate information to the user. The actual information would be the same as the one built in to the browser, but I will be experimenting with layouts and other information for UX.
I've been working with Firefox extensions instead of add ons due to deprecation of add-ons in 2017, but this project will be finished before then.
I was trying the example found here, but the extension seems to stop on the require("chrome").
Next I tried writing simpler code to figure out how the example works, but this code doesn't have a channel attached to the request. My code, minus all sorts of printing statements, is below:
document.getElementById("click_button").addEventListener("click",
function(e) {
var url = "https://secure-website-example.google.com";
xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.addEventListener("error",
function(e) {
dumpSecurityInfo(xhr, -1);
}, false);
xhr.onload = function(e) {
dumpSecurityInfo(xhr);
};
xhr.send();
});
function dumpSecurityInfo(xhr, error) {
var channel = xhr.channel;
try {
console.log("Connection status:");
if (!error) { console.log("Succeeded"); }
else { console.log("Failed :("); }
var securityInfo = channel.securityInfo;
} catch(err) {
alert(err);
}
}
with a manifest like this:
"manifest_version": 2,
"name": "Certificate Browser",
"version": "1.0",
...
"permissions": [
"activeTab",
"webRequest",
"https://secure-website-example.google.com/*"
],
"browser_action": {
...
"default_popup": "popup/certificate_information.html"
}
Am I missing any permissions necessary to have access to the certificate? Is there a better way of grabbing certificate information?
The wiki page you linked to refers to APIs available in the addon sdk and bootstrapped extensions. The kind of manifest indicates you're writing a webextensions which are far more limited.

S3 Upload Issue

I am trying to upload a file on S3. I have been verified everything couple of times and all looks correct to me, but whenever I am trying to upload file, getting error message saying
responseText =
InvalidArgumentPOST requires exactly one file upload per request.0file3670E4EE52B3BCD5b3rOF/9WJHymo1ZENIOlrct/ZusAJ50AnSIP0df3K3+DdEcAFolJDx8qU6DH2N1l
Can someone please help me to findout what I am doing wrong here?
<div id="s3-fileuploader" class="dropArea"></div>
<script type="text/javascript">
j$ = jQuery.noConflict();
//block and unblock UIbased on endpoint url
function setUI(){
j$('div.dropArea').unblock();
}
$(document).ready(function () {
$('#s3-fileuploader').fineUploader({
request: {
endpoint: "https://{!bucketname}.s3.amazonaws.com",
accessKey: "{!key}"
},
signature: {
//always included
"expiration": "{!expireStr}",
signature : "{!signedPolicy}",
policy: "{!policy}",
"conditions":
[
//always included
{"acl": "public-read"},
//always included
{"bucket": "{!bucketname}"},
//not included in IE9 and older or Android 2.3.x and older
{"Content-Type": "{!ContentType}"},
//always included
{"key": "{!key}"},
//always included
{"x-amz-meta-qqfilename": "{!URLENCODE('test.jpg')}"},
]
},
cors: {
expected: true, //all requests are expected to be cross-domain requests
sendCredentials: false, //if you want cookies to be sent along with the request
allowXdr: true
},
autoUpload: true,
multiple:false,
debug: true,
text: {
uploadButton: '<i class="icon-plus icon-white">Select Files</i> '
},
uploadSuccess: {
endpoint: "{!redirectURL}"
}
}).on('submit',function(event,id,name){
//set endpoint
console.log('https://{!bucketname}.s3.amazonaws.com');
$(this).fineUploader('setEndpoint','https://{!bucketname}.s3.amazonaws.com');
});
setUI();
});
</script>
</body>
The signature option is supposed to include information about your signature server. Instead you are apparently attaching an (invalid) policy document to this option. Furthermore, you do not create the police document, Fine Uploader creates it for you and passes it to your signature server for signing.
Also you should be using the fineUploaderS3 jquery plugin for this.
It looks like you have not read the documentation that describes how Fine Uploader S3 works. I suggest starting with the guides on the home page of http://docs.fineuploader.com.

Ext.Ajax.Request not working in Browser

Ext.Ajax.Request doesn't seem to work on desktop web browsers for me. It works perfectly fine on devices and on the xcode simulators but on desktop web browsers, it calls on the failure method. Here is the code:
// send ajax request
Ext.Ajax.request({
url: 'http://testapp.cloudapp.net/index.php/api/accounts/login/',
method: 'POST',
params: {
username: Ext.getCmp('username').getValue(),
password: Ext.getCmp('password').getValue()
},
dataType: 'json',
success : function(response, request) {
if(response.responseText == true) {
Ext.Msg.alert('validated');
// animate to wall view
Ext.Viewport.animateActiveItem(targetView, { type : 'fade' } );
//destroy Login and Register Views
var vwRegister = Ext.ComponentQuery.query('register')[0],
vwLogin = Ext.ComponentQuery.query('login')[0];
setTimeout( function() {
vwRegister.destroy();
vwLogin.destroy();
}, 2000);
}
else {
Ext.Msg.alert('invalid user');
}
},
failure: function(response, request) {
Ext.Msg.alert('error');
}
});
I don't think this has something to do with the "Same-origin policy" because I tried doing the same thing using jQuery's $.ajax function and it worked fine.
Check your debug console, you most likely will see an error about the same origin policy.
If nothing else try opening chrome with the --disable-web-security option to see if it helps.
See this question for exact syntax.
Good luck, Brad
Though not particularly safe or recommended, you can also start browsers like Chrome in a state that disables web security features, like the same origin policy.
For Windows...
chrome.exe --disable-web-security
For Mac...
Chrome.app --args --disable-web-security
Since I don't particularly enjoy using the terminal every time, you can write a bash script to do it for you, or use automator on a Mac.
Also, ensure the browser isn't already running, or else this will not work.

request.xhr undefined in Ext JS

my web site is made using Ext JS 4.1 framework and ASP .Net MVC v3. When new frame is rendered there are 19 separate AJAX requests for retrieving data in JSON-format. All requests are familiar and made by Ext.Ajax.request(). Example:
Ext.Ajax.request({
url: getOrderLink,
method: "GET",
params: { recId: orderRecId },
headers: {
'Accept': 'application/json'
},
success: function (response) {
var order = Ext.decode(response.responseText);
...
}
});
In some cases there are errors in ext-all.js in
onStateChange : function(request) {
if (request.xhr.readyState == 4) {
this.clearTimeout(request);
this.onComplete(request);
this.cleanup(request);
}
},
where request has no property xhr so that request.xhr.readyState throws exception "Cannot read property 'readState' of undefined".
This errors appear not for all requests and don't effect site work(responses are retrieved successfully). Some times this errors don't appear at all. Timeout for all requests is set to 30s by default and they take about 1.5-2 seconds each.
I am using Google Chrome 21.
Could you please give me some idea why it's happening.
The problem seems to occur if and only if you have a breakpoint or a "debugger;" line in anything related to AJAX. For me it happened in Chrome, haven't tried other browsers yet.
In my case it happened when I had set a breakpoint in a load event handler for a store like code example below.
But the error occurrs if you set a breakpoint inside the Ext onStateChange function in the framework itself as well.
If disabling your breakpoints and debugger; calls removes the error you can safely ignore it!
There is a similar thread on ExtJS forums. Sencha might add a fix.
Ext.define('MyApp.controller.MyController', {
extend: 'Ext.app.Controller',
stores: ['Projects'],
init: function () {
this.getProjectsStore().addListener(
"load",
this.onProjectsStoreLoaded,
this
);
},
onProjectsStoreLoaded: function () {
console.log('MyController: onProjectsStoreLoaded');
debugger; // <- this causes the errors to appear in the console
SomeOtherThingsIWantedToDebug();
}
}

Resources