1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/addon-sdk/source/lib/sdk/windows/tabs-fennec.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,171 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 +'use strict'; 1.8 + 1.9 +const { Class } = require('../core/heritage'); 1.10 +const { Tab } = require('../tabs/tab'); 1.11 +const { browserWindows } = require('./fennec'); 1.12 +const { windowNS } = require('../window/namespace'); 1.13 +const { tabsNS, tabNS } = require('../tabs/namespace'); 1.14 +const { openTab, getTabs, getSelectedTab, getTabForBrowser: getRawTabForBrowser, 1.15 + getTabContentWindow } = require('../tabs/utils'); 1.16 +const { Options } = require('../tabs/common'); 1.17 +const { getTabForBrowser, getTabForRawTab } = require('../tabs/helpers'); 1.18 +const { on, once, off, emit } = require('../event/core'); 1.19 +const { method } = require('../lang/functional'); 1.20 +const { EVENTS } = require('../tabs/events'); 1.21 +const { EventTarget } = require('../event/target'); 1.22 +const { when: unload } = require('../system/unload'); 1.23 +const { windowIterator } = require('../deprecated/window-utils'); 1.24 +const { List, addListItem, removeListItem } = require('../util/list'); 1.25 +const { isPrivateBrowsingSupported } = require('../self'); 1.26 +const { isTabPBSupported, ignoreWindow } = require('../private-browsing/utils'); 1.27 + 1.28 +const mainWindow = windowNS(browserWindows.activeWindow).window; 1.29 + 1.30 +const ERR_FENNEC_MSG = 'This method is not yet supported by Fennec'; 1.31 + 1.32 +const supportPrivateTabs = isPrivateBrowsingSupported && isTabPBSupported; 1.33 + 1.34 +const Tabs = Class({ 1.35 + implements: [ List ], 1.36 + extends: EventTarget, 1.37 + initialize: function initialize(options) { 1.38 + let tabsInternals = tabsNS(this); 1.39 + let window = tabsNS(this).window = options.window || mainWindow; 1.40 + 1.41 + EventTarget.prototype.initialize.call(this, options); 1.42 + List.prototype.initialize.apply(this, getTabs(window).map(Tab)); 1.43 + 1.44 + // TabOpen event 1.45 + window.BrowserApp.deck.addEventListener(EVENTS.open.dom, onTabOpen, false); 1.46 + 1.47 + // TabSelect 1.48 + window.BrowserApp.deck.addEventListener(EVENTS.activate.dom, onTabSelect, false); 1.49 + }, 1.50 + get activeTab() { 1.51 + return getTabForRawTab(getSelectedTab(tabsNS(this).window)); 1.52 + }, 1.53 + open: function(options) { 1.54 + options = Options(options); 1.55 + let activeWin = browserWindows.activeWindow; 1.56 + 1.57 + if (options.isPinned) { 1.58 + console.error(ERR_FENNEC_MSG); // TODO 1.59 + } 1.60 + 1.61 + let rawTab = openTab(windowNS(activeWin).window, options.url, { 1.62 + inBackground: options.inBackground, 1.63 + isPrivate: supportPrivateTabs && options.isPrivate 1.64 + }); 1.65 + 1.66 + // by now the tab has been created 1.67 + let tab = getTabForRawTab(rawTab); 1.68 + 1.69 + if (options.onClose) 1.70 + tab.on('close', options.onClose); 1.71 + 1.72 + if (options.onOpen) { 1.73 + // NOTE: on Fennec this will be true 1.74 + if (tabNS(tab).opened) 1.75 + options.onOpen(tab); 1.76 + 1.77 + tab.on('open', options.onOpen); 1.78 + } 1.79 + 1.80 + if (options.onReady) 1.81 + tab.on('ready', options.onReady); 1.82 + 1.83 + if (options.onLoad) 1.84 + tab.on('load', options.onLoad); 1.85 + 1.86 + if (options.onPageShow) 1.87 + tab.on('pageshow', options.onPageShow); 1.88 + 1.89 + if (options.onActivate) 1.90 + tab.on('activate', options.onActivate); 1.91 + 1.92 + return tab; 1.93 + } 1.94 +}); 1.95 +let gTabs = exports.tabs = Tabs(mainWindow); 1.96 + 1.97 +function tabsUnloader(event, window) { 1.98 + window = window || (event && event.target); 1.99 + if (!(window && window.BrowserApp)) 1.100 + return; 1.101 + window.BrowserApp.deck.removeEventListener(EVENTS.open.dom, onTabOpen, false); 1.102 + window.BrowserApp.deck.removeEventListener(EVENTS.activate.dom, onTabSelect, false); 1.103 +} 1.104 + 1.105 +// unload handler 1.106 +unload(function() { 1.107 + for (let window in windowIterator()) { 1.108 + tabsUnloader(null, window); 1.109 + } 1.110 +}); 1.111 + 1.112 +function addTab(tab) { 1.113 + addListItem(gTabs, tab); 1.114 + return tab; 1.115 +} 1.116 + 1.117 +function removeTab(tab) { 1.118 + removeListItem(gTabs, tab); 1.119 + return tab; 1.120 +} 1.121 + 1.122 +// TabOpen 1.123 +function onTabOpen(event) { 1.124 + let browser = event.target; 1.125 + 1.126 + // Eventually ignore private tabs 1.127 + if (ignoreWindow(browser.contentWindow)) 1.128 + return; 1.129 + 1.130 + let tab = getTabForBrowser(browser); 1.131 + if (tab === null) { 1.132 + let rawTab = getRawTabForBrowser(browser); 1.133 + 1.134 + // create a Tab instance for this new tab 1.135 + tab = addTab(Tab(rawTab)); 1.136 + } 1.137 + 1.138 + tabNS(tab).opened = true; 1.139 + 1.140 + tab.on('ready', function() emit(gTabs, 'ready', tab)); 1.141 + tab.once('close', onTabClose); 1.142 + 1.143 + tab.on('pageshow', function(_tab, persisted) 1.144 + emit(gTabs, 'pageshow', tab, persisted)); 1.145 + 1.146 + emit(tab, 'open', tab); 1.147 + emit(gTabs, 'open', tab); 1.148 +} 1.149 + 1.150 +// TabSelect 1.151 +function onTabSelect(event) { 1.152 + let browser = event.target; 1.153 + 1.154 + // Eventually ignore private tabs 1.155 + if (ignoreWindow(browser.contentWindow)) 1.156 + return; 1.157 + 1.158 + // Set value whenever new tab becomes active. 1.159 + let tab = getTabForBrowser(browser); 1.160 + emit(tab, 'activate', tab); 1.161 + emit(gTabs, 'activate', tab); 1.162 + 1.163 + for each (let t in gTabs) { 1.164 + if (t === tab) continue; 1.165 + emit(t, 'deactivate', t); 1.166 + emit(gTabs, 'deactivate', t); 1.167 + } 1.168 +} 1.169 + 1.170 +// TabClose 1.171 +function onTabClose(tab) { 1.172 + removeTab(tab); 1.173 + emit(gTabs, EVENTS.close.name, tab); 1.174 +}