Skip to content

Loading…

More fixes and performance improvements to Safari event handling and dispatching #548

Merged
merged 2 commits into from

2 participants

@chrisaljoudi

Cleanup, slight restructuring, improvements in vapi-background and vapi-client for Safari. Performance gains (overhead reduction). Squashed some noncritical errors introduced in #542.

I suggest a version bump at this point.

@gorhill gorhill merged commit 965f3cf into chrisaljoudi:master

1 check passed

Details continuous-integration/travis-ci The Travis CI build passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jan 20, 2015
  1. Doh

    committed
This page is out of date. Refresh to see the latest.
Showing with 65 additions and 114 deletions.
  1. +20 −25 platform/safari/vapi-background.js
  2. +45 −89 platform/safari/vapi-client.js
View
45 platform/safari/vapi-background.js
@@ -188,33 +188,23 @@ vAPI.tabs = {
/******************************************************************************/
vAPI.tabs.registerListeners = function() {
- var onNavigation = this.onNavigation;
-
safari.application.addEventListener('beforeNavigate', function(e) {
- if ( !e.target || !e.target.url || e.target.url === 'about:blank' ) {
+ if ( !vAPI.tabs.popupCandidate || !e.target || e.url === 'about:blank' ) {
return;
}
- var url = e.target.url, tabId = vAPI.tabs.getTabId(e.target);
- if ( vAPI.tabs.popupCandidate ) {
- var details = {
- url: url,
- tabId: tabId,
- sourceTabId: vAPI.tabs.popupCandidate
- };
- vAPI.tabs.popupCandidate = false;
- if ( vAPI.tabs.onPopup(details) ) {
- e.preventDefault();
- if ( vAPI.tabs.stack[details.sourceTabId] ) {
- vAPI.tabs.stack[details.sourceTabId].activate();
- }
- return;
+ var url = e.url, tabId = vAPI.tabs.getTabId(e.target);
+ var details = {
+ url: url,
+ tabId: tabId,
+ sourceTabId: vAPI.tabs.popupCandidate
+ };
+ vAPI.tabs.popupCandidate = false;
+ if ( vAPI.tabs.onPopup(details) ) {
+ e.preventDefault();
+ if ( vAPI.tabs.stack[details.sourceTabId] ) {
+ vAPI.tabs.stack[details.sourceTabId].activate();
}
}
- onNavigation({
- url: url,
- frameId: 0,
- tabId: tabId
- });
}, true);
// onClosed handled in the main tab-close event
@@ -588,9 +578,6 @@ vAPI.messaging.broadcast = function(message) {
/******************************************************************************/
-
-/******************************************************************************/
-
vAPI.net = {};
/******************************************************************************/
@@ -649,6 +636,14 @@ vAPI.net.registerListeners = function() {
return;
}
+ if ( e.message.navigatedToNew ) {
+ vAPI.tabs.onNavigation({
+ url: e.message.url,
+ frameId: 0,
+ tabId: vAPI.tabs.getTabId(e.target)
+ });
+ return;
+ }
block = vAPI.net.onBeforeRequest;
View
134 platform/safari/vapi-client.js
@@ -191,95 +191,63 @@ if ( location.protocol === 'safari-extension:' ) {
/******************************************************************************/
-var beforeLoadEvent = document.createEvent('Event');
-beforeLoadEvent.initEvent('beforeload');
-
-/******************************************************************************/
-
var frameId = window === window.top ? 0 : Date.now() % 1E5;
var parentFrameId = frameId ? 0 : -1;
-var linkHelper = document.createElement('a');
-var onBeforeLoad = function(e, details) {
- if ( e.url && e.url.lastIndexOf('data:', 0) === 0 ) {
- return;
- }
-
- linkHelper.href = details ? details.url : e.url;
- var url = linkHelper.href;
-
- if ( url.lastIndexOf('http:', 0) === -1 && url.lastIndexOf('https:', 0) === -1) {
- return;
- }
-
- if ( details ) {
- details.url = url;
- } else {
- details = {
- url: url
- };
-
- switch ( e.target.nodeName.toLowerCase() ) {
- case 'frame':
- case 'iframe':
- details.type = 'sub_frame';
- break;
- case 'script':
- details.type = 'script';
- break;
- case 'img':
- case 'input': // type=image
- details.type = 'image';
- break;
- case 'object':
- case 'embed':
- details.type = 'object';
- break;
- case 'link':
- var rel = e.target.rel.trim().toLowerCase();
-
- if ( rel.indexOf('icon') !== -1 ) {
- details.type = 'image';
- break;
- } else if ( rel === 'stylesheet' ) {
- details.type = 'stylesheet';
- break;
- }
- default:
- details.type = 'other';
- }
-
- }
+var beforeLoadEvent = new Event('beforeload'); // Helper event to message background
- // This can run even before the first DOMSubtreeModified event fired
- if ( firstMutation ) {
- firstMutation();
- }
+// Inform that we've navigated
+if(frameId === 0) {
+ safari.self.tab.canLoad(beforeLoadEvent, {
+ url: location.href,
+ type: 'main_frame',
+ navigatedToNew: true
+ });
+}
- // tabId is determined in the background script
- // details.tabId = null;
+var linkHelper = document.createElement('a');
+var nodeTypes = {
+ 'frame': 'sub_frame',
+ 'iframe': 'sub_frame',
+ 'script': 'script',
+ 'img': 'image',
+ 'input': 'image',
+ 'object': 'object',
+ 'embed': 'object',
+ 'link': 'stylesheet'
+};
+var shouldBlockDetailedRequest = function(details) {
+ linkHelper.href = details.url;
+ details.url = linkHelper.href;
details.frameId = frameId;
details.parentFrameId = parentFrameId;
details.timeStamp = Date.now();
-
+ return !(safari.self.tab.canLoad(beforeLoadEvent, details));
+}
+var onBeforeLoad = function(e) {
+ if(e.url.lastIndexOf('data:', 0) === 0) {
+ return;
+ }
+ linkHelper.href = e.url;
+ var url = linkHelper.href;
+ var details = {
+ url: url,
+ type: nodeTypes[e.target.nodeName.toLowerCase()] || 'other',
+ // tabId is determined in the background script
+ frameId: frameId,
+ parentFrameId: parentFrameId,
+ timeStamp: Date.now()
+ };
var response = safari.self.tab.canLoad(e, details);
-
- if ( !response ) {
- if ( details.type === 'main_frame' ) {
- window.stop();
- } else {
- e.preventDefault();
- }
-
+ if(!response) {
+ e.preventDefault();
return false;
}
-
// Local mirroring, response should be a data: URL here
- if ( typeof response !== 'string' ) {
+ if(typeof response !== 'string') {
return;
}
-
+ // Okay, we're mirroring...
e.preventDefault();
-
// Content Security Policy with disallowed inline scripts may break things
details = document.createElement('script');
details.textContent = atob(response.slice(response.indexOf(',', 20) + 1));
@@ -308,11 +276,9 @@ var firstMutation = function() {
var randEventName = uniqueId();
window.addEventListener(randEventName, function(e) {
- var result = onBeforeLoad(beforeLoadEvent, e.detail);
-
- if ( result === false ) {
+ if(shouldBlockDetailedRequest(e.detail)) {
e.detail.url = false;
- }
+ };
}, true);
// the extension context is unable to reach the page context,
@@ -409,18 +375,8 @@ var onContextMenu = function(e) {
self.addEventListener('contextmenu', onContextMenu, true);
-/******************************************************************************/
-
-// 'main_frame' simulation
-if ( frameId === 0 ) {
- onBeforeLoad(beforeLoadEvent, {
- url: location.href,
- type: 'main_frame'
- });
-}
/******************************************************************************/
-
})();
/******************************************************************************/
Something went wrong with that request. Please try again.