diff --git a/content/treestyletab/res/stopRendering.js b/content/treestyletab/res/stopRendering.js index 2928ef74..8cc8b44e 100644 --- a/content/treestyletab/res/stopRendering.js +++ b/content/treestyletab/res/stopRendering.js @@ -12,7 +12,7 @@ http://www.cozmixng.org/repos/piro/fx3-compatibility-lib/trunk/stopRendering.js */ (function() { - const currentRevision = 5; + const currentRevision = 6; if (!('piro.sakura.ne.jp' in window)) window['piro.sakura.ne.jp'] = {}; @@ -27,6 +27,7 @@ 'destroy' in window['piro.sakura.ne.jp'].stopRendering) window['piro.sakura.ne.jp'].stopRendering.destroy(); + const Cc = Components.classes; const Ci = Components.interfaces; window['piro.sakura.ne.jp'].stopRendering = { @@ -45,7 +46,12 @@ stop : function() { - this.baswWindow.setPosition(window.top.innerWidth * 3, window.top.innerHeight * 3); + if (this.useCanvas) { + this.showCanvas(); + } + else { + this.baswWindow.setPosition(window.top.innerWidth * 3, window.top.innerHeight * 3); + } this._stopLevel++; }, @@ -56,24 +62,30 @@ return; this._stopLevel = 0; - this.baswWindow.setPosition(0, 0); - this._popups.forEach(function(aPopup, aIndex) { - if (aPopup.state != 'open') return; - var w = aPopup.boxObject.width; - var h = aPopup.boxObject.height; - var hasWidth = aPopup.hasAttribute('width'); - var hasHeight = aPopup.hasAttribute('height'); - aPopup.sizeTo(w, h-1); - aPopup.sizeTo(w, h); - if (!hasWidth || !hasHeight) - window.setTimeout(function() { - if (!hasWidth) - aPopup.removeAttribute('width'); - if (!hasHeight) - aPopup.removeAttribute('height'); - }, 0); - }, this); + if (this.useCanvas) { + this.hideCanvas(); + } + else { + this.baswWindow.setPosition(0, 0); + + this._popups.forEach(function(aPopup, aIndex) { + if (aPopup.state != 'open') return; + var w = aPopup.boxObject.width; + var h = aPopup.boxObject.height; + var hasWidth = aPopup.hasAttribute('width'); + var hasHeight = aPopup.hasAttribute('height'); + aPopup.sizeTo(w, h-1); + aPopup.sizeTo(w, h); + if (!hasWidth || !hasHeight) + window.setTimeout(function() { + if (!hasWidth) + aPopup.removeAttribute('width'); + if (!hasHeight) + aPopup.removeAttribute('height'); + }, 0); + }, this); + } }, onResize : function(aEvent) @@ -116,22 +128,188 @@ init : function() { - this._popups = []; + if (this.useCanvas) { + this.initCanvas(); + } + else { + this._popups = []; + window.addEventListener('popupshown', this, false); + window.addEventListener('popuphidden', this, false); + } window.addEventListener('resize', this, false); - window.addEventListener('popupshown', this, false); - window.addEventListener('popuphidden', this, false); window.addEventListener('unload', this, false); }, destroy : function() { - this._popups = []; + if (this.useCanvas) { + this.destroyCanvas(); + } + else { + this._popups = []; + window.removeEventListener('popupshown', this, false); + window.removeEventListener('popuphidden', this, false); + } window.removeEventListener('resize', this, false); - window.removeEventListener('popupshown', this, false); - window.removeEventListener('popuphidden', this, false); window.removeEventListener('unload', this, false); - } + }, + + // full screen canvas + + useCanvas : (function() { + const XULAppInfo = Cc['@mozilla.org/xre/app-info;1'] + .getService(Ci.nsIXULAppInfo); + const comparator = Cc['@mozilla.org/xpcom/version-comparator;1'] + .getService(Ci.nsIVersionComparator); + return comparator.compare(XULAppInfo.version, '3.6.9999') > 0; + })(), + + DRAW_WINDOW_FLAGS : Ci.nsIDOMCanvasRenderingContext2D.DRAWWINDOW_DRAW_VIEW | + Ci.nsIDOMCanvasRenderingContext2D.DRAWWINDOW_DRAW_CARET | + Ci.nsIDOMCanvasRenderingContext2D.DRAWWINDOW_DO_NOT_FLUSH, + DRAW_WINDOW_BGCOLOR : 'transparent', + + showCanvas : function() + { + if (this.shown) return; + + var canvas = this.canvas; + if (!canvas) return; + + this.shown = true; + + var rootBox = document.documentElement.boxObject; + var canvasW = window.innerWidth; + var canvasH = window.innerHeight; + + var x = 0, + y = 0, + w = canvasW, + h = canvasH; + + canvas.style.width = (canvas.width = canvasW)+'px'; + canvas.style.height = (canvas.height = canvasH)+'px'; + try { + var ctx = canvas.getContext('2d'); + ctx.clearRect(0, 0, canvasW, canvasH); + ctx.save(); + ctx.translate(x, y); + ctx.drawWindow(window, x, y, w, h, this.DRAW_WINDOW_BGCOLOR, this.DRAW_WINDOW_FLAGS); + ctx.restore(); + + this.browsers.forEach(function(aBrowser) { + try { + var b = aBrowser; + if (b.localName == 'subbrowser') b = b.browser; + var frame = b.contentWindow; + var box = (b.localName == 'tabbrowser' ? b.mCurrentBrowser : b ).boxObject; + var x = box.x; + var y = box.y; + var bw = box.width; + var bh = box.height; + var w = frame.innerWidth; + var h = frame.innerHeight; + ctx.save(); + ctx.translate(x, y); + ctx.scale(bw / w, bh / h); + ctx.drawWindow(frame, 0, 0, w, h, this.DRAW_WINDOW_BGCOLOR, this.DRAW_WINDOW_FLAGS); + ctx.restore(); + } + catch(e) { + } + }, this); + + document.documentElement.setAttribute('fullScreenCanvas-state', 'shown'); + } + catch(e) { + this.hideCanvas(); + } + }, + shown : false, + + hideCanvas : function() + { + if (!this.shown) return; + + document.documentElement.removeAttribute('fullScreenCanvas-state'); + this.shown = false; + }, + + onClick : function(aEvent) + { + this._stopLevel = 0; + this.hideCanvas(); + }, + + + get browsers() + { + browsers = [].concat(Array.slice(document.getElementsByTagName('tabbrowser'))) + .concat(Array.slice(document.getElementsByTagName('browser'))); + if ('SplitBrowser' in window) browsers = browsers.concat(SplitBrowser.browsers); + return browsers; + }, + + initCanvas : function() + { + var canvas = document.createElementNS('http://www.w3.org/1999/xhtml', 'canvas'); + canvas.setAttribute('id', 'fullScreenCanvas-canvas'); + canvas.setAttribute('width', '0'); + canvas.setAttribute('height', '0'); + canvas.setAttribute('style', 'width:0;height:0;'); + this.canvas = canvas; + + var style = document.createElementNS('http://www.w3.org/1999/xhtml', 'style'); + style.setAttribute('id', 'fullScreenCanvas-style'); + style.setAttribute('type', 'text/css'); + style.appendChild(document.createTextNode([ + ':root[fullScreenCanvas-state="shown"] > *:not(#fullScreenCanvas-box) {', + ' visibility: hidden !important;', + '}', + '#fullScreenCanvas-style {', + ' display: none;', + '}', + '#fullScreenCanvas-box {', + ' position: fixed;', + ' z-index: 65000;', + ' top: 0;', + ' left: 0;', + ' visibility: collapse;', + '}', + ':root[fullScreenCanvas-state="shown"] > #fullScreenCanvas-box {', + ' visibility: visible;', + '}' + ].join(''))); + this.style = style; + + var stylePI = document.createProcessingInstruction( + 'xml-stylesheet', + 'type="text/css" href="#fullScreenCanvas-style"' + ); + this.stylePI = stylePI; + + var box = document.createElement('box'); + box.setAttribute('id', 'fullScreenCanvas-box'); + box.setAttribute('onclick', 'window["piro.sakura.ne.jp"].stopRendering.onClick(event);'); + this.box = box; + + box.appendChild(canvas); + box.appendChild(style); + document.documentElement.appendChild(box); + + document.insertBefore(stylePI, document.documentElement); + }, + + destroyCanvas : function() + { + document.documentElement.removeChild(this.box); + document.removeChild(this.stylePI); + this.box = null; + this.canvas = null; + this.style = null; + this.stylePI = null; + } }; window['piro.sakura.ne.jp'].stopRendering.init();