<?xml version='1.0'?>
<!DOCTYPE bindings SYSTEM "/native/fx/textonly.dtd"><bindings xmlns="http://www.mozilla.org/xbl" xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
    <binding id="button">
        <resources>
            <stylesheet src="container.css"/>
        </resources>

        <content label="&textonly.label;">
            <xul:deck anonid="buttons" selectedIndex="0">
                <xul:image tooltiptext="&textonly.tooltip.not-available;"/>
                <xul:image tooltiptext="&textonly.tooltip.open;"/>
                <xul:image tooltiptext="&textonly.tooltip.close;"/>
            </xul:deck>
        </content>

        <implementation implements="nsIObserver,nsIDOMEventListener">

            <field name="_buttons" readonly="true">
                this.getElement("buttons")
            </field>

            <field name="_tooltip" readonly="true">
                this.getElement("tooltip")
            </field>

            <field name="api" readonly="true">
                this.module.api
            </field>

            <field name="wListener" readonly="true">
                this.api.Browser.getWindowListener(window)
            </field>

            <field name="staticPrefs" readonly="true">
                new this.api.Settings.PrefsModule(this.api.Settings.getStaticBranchPath())
            </field>

            <field name="holderID">
                "textonly-content-holder"
            </field>

            <field name="frameID" readonly="true">
                "textonly-frame:" + Date.now()
            </field>

            <field name="frameCSS">
                "data:text/css;," + encodeURIComponent( this.getFileContent("inframe/rb.css") )
            </field>

            <field name="frameCSSPrint">
                "data:text/css;," + encodeURIComponent( this.getFileContent("inframe/rb-print.css") )
            </field>

            <field name="frameJS">
                "data:text/javascript;," + encodeURIComponent( this.getFileContent("inframe/rb.js") )
            </field>

            <field name="throbberURLData"><![CDATA["data:image/png;base64,[encoded data, 16468 characters]";]]></field>

            <field name="locale" readonly="true">
                this.api.Environment.addon.locale
            </field>

            <property name="_isActiveBrowser" readonly="true">
                <getter><![CDATA[var mainWindow = document.getElementById("main-window");
return mainWindow && mainWindow.getAttribute("active") == "true";]]></getter>
            </property>

            <property name="contentDoc" onget="return gBrowser.mCurrentBrowser.contentDocument;" readonly="true"/>

            <property name="contentBody" onget="return this.contentDoc.getElementsByTagName('body')[0];" readonly="true"/>

            <property name="textonlyFrame" onget="return this.contentDoc.getElementById(this.frameID);" readonly="true"/>

            <property name="currentTab" onget="return this.wListener.currentTab;" readonly="true"/>

            <property name="tabData" onget="return this.wListener.getTabData(this.currentTab, 'textonly');" readonly="true"/>

            <property name="opened">
                <getter><![CDATA[return Boolean(this.textonlyFrame);]]></getter>
                <setter><![CDATA[if (this.opened == val)
return val;
val ? this.open() : this.close();
return val;]]></setter>
            </property>

            <field name="_available">false</field>
            <property name="available">
                <getter><![CDATA[return this._available;]]></getter>
                <setter><![CDATA[if (this.available == val)
return val;
this._available = val;
this.reDraw();
return val;]]></setter>
            </property>

            <property name="state">
                <getter><![CDATA[return this.opened ? "opened" : this.available ? "closed" : "not-available";]]></getter>
                <setter><![CDATA[this.opened = val == "opened";
this.available = val != "not-available";
return val;]]></setter>
            </property>

            <method name="getElement">
                <parameter name="id"/>
                <body><![CDATA[return document.getAnonymousElementByAttribute(this,"anonid",id);]]></body>
            </method>

            <method name="open">
                <body><![CDATA[if (this.opened)
return null;
this._runTextonly();
this.reDraw();
return this;]]></body>
            </method>

            <method name="close">
                <body><![CDATA[if (! this.opened)
return null;
this._closeTextonly();
this.reDraw();
return this;]]></body>
            </method>

            <method name="openXclose">
                <body><![CDATA[this.opened = ! this.opened;
return this;]]></body>
            </method>

            <method name="getFileContent">
                <parameter name="path"/>
                <body><![CDATA[var fileChannel = this.api.Package.getFileInputChannel("/native/fx/textonly/" + path);
return this.api.StrUtils.readStringFromStream(fileChannel.contentStream);]]></body>
            </method>

            <method name="reDraw">
                <body><![CDATA[var selectedIndex;
switch (this.state) {
case "opened":
selectedIndex = 2;
break;
case "closed":
selectedIndex = 1;
break;
default:
selectedIndex = 0;
break;
}

this._buttons.selectedIndex = selectedIndex;
return this;]]></body>
            </method>

            <method name="observe">
                <parameter name="aSubject"/>
                <parameter name="aTopic"/>
                <parameter name="aData"/>
                <body><![CDATA[this.checkCurrentBrowser();]]></body>
            </method>

            <constructor><![CDATA[this.wListener.addListener("WindowLocationChange",this);
this.wListener.addListener("PageLoad",this);
this.checkCurrentBrowser();]]></constructor>

            <destructor><![CDATA[this.wListener.removeListener("WindowLocationChange",this);
this.wListener.removeListener("PageLoad",this);]]></destructor>

                  

                  <method name="_runTextonly">
                    <body><![CDATA[const kHTMLNS = "http://www.w3.org/1999/xhtml";
var currentBrowser = gBrowser.mCurrentBrowser;
var contentDoc = currentBrowser.contentDocument;
var body;
try {
body = contentDoc.documentElement.getElementsByTagName("body")[0];
}
catch (e) {

}

if (! body)
return;
this.api.Statistics.logShortAction(4900);
var contentShadow = contentDoc.createElementNS(kHTMLNS,"div");
contentShadow.setAttribute("style","position: fixed !important;                            top: 0 !important; left: 0 !important;                            bottom: 0 !important; right: 0 !important;                            width: 100% !important;                            height: 100% !important;                            padding: 0 !important;                            margin: 0 !important;                            border: none !important;                            display: block !important;                            background: #000 !important;                            opacity: .7 !important;                            visibility: visible !important;                            z-index: 2147483647 !important;                       ");
var contentHolder = contentDoc.createElementNS(kHTMLNS,"div");
contentHolder.setAttribute("id",this.holderID);
contentHolder.setAttribute("style","position: fixed !important;                           top: 0 !important; left: 0 !important;                           bottom: 0 !important; right: 0 !important;                           padding: 0 !important;                           margin: 26px 15% !important;                           border: none !important;                           display: block !important;                           visibility: visible !important;                           z-index: 2147483647 !important;                       ");
var contentFrame = contentDoc.createElementNS(kHTMLNS,"iframe");
contentFrame.id = this.frameID;
contentFrame.setAttribute("style","position: absolute !important;                            top: 0 !important; left: 0 !important;                            bottom: 0 !important; right: 0 !important;                            width: 100% !important;                            height: 100% !important;                            min-width: 400px !important;                            padding: 0 !important;                            margin: 0 !important;                            border: 1px solid #ccc !important;                            display: block !important;                            background: #fff !important;                            opacity: 1 !important;                            visibility: visible !important;                            z-index: 2147483647 !important;                            box-shadow: 0px 0px 40px rgba(0,0,0,1);                       ");
var bodyClone = body.cloneNode(true);
bodyClone.style.display = "none";
body.appendChild(contentShadow);
contentHolder.appendChild(contentFrame);
body.appendChild(contentHolder);
contentFrame.contentWindow.focus();
setTimeout(function (me) {
if (! (contentFrame && me && "_appendTextonlyContent" in me))
return;
var frameDocumentElement = contentFrame.contentDocument.documentElement;
var throbberHolder = contentFrame.contentDocument.createElementNS(kHTMLNS,"div");
throbberHolder.setAttribute("id","throbber-holder");
throbberHolder.setAttribute("style","position: fixed !important;                              top: 0 !important; left: 0 !important;                              bottom: 0 !important; right: 0 !important;                              width: 100% !important;                              height: 100% !important;                              padding: 0 !important;                              margin: 0 !important;                              border: none !important;                              display: block;                              background: #fff url('" + me.throbberURLData + "') center center no-repeat !important;                              opacity: 1;                              visibility: visible !important;                              z-index: 2147483647 !important;                         ");
frameDocumentElement.appendChild(throbberHolder);
setTimeout(function (me) {
if (! (contentFrame && me && "_appendTextonlyContent" in me))
return;
contentFrame.contentDocument.title = contentDoc.title;
var frameDocumentElement = contentFrame.contentDocument.documentElement;
var frameBody = frameDocumentElement.getElementsByTagName("body")[0];
if (frameBody)
frameDocumentElement.replaceChild(bodyClone,frameBody); else
frameDocumentElement.appendChild(bodyClone);
me._manageContentEventListeners(true,currentBrowser,contentDoc,contentFrame.contentWindow);
me._appendTextonlyContent(contentFrame);
}
,50,me);
}
,150,this);]]></body>
                  </method>

                  <method name="_closeTextonly">
                    <body><![CDATA[var currentBrowser = gBrowser.mCurrentBrowser;
var contentDoc = currentBrowser.contentDocument;
var existsHolder = contentDoc && contentDoc.getElementById(this.holderID);
if (! existsHolder)
return false;
var shadow = existsHolder.previousSibling;
shadow.parentNode.removeChild(shadow);
this._manageContentEventListeners(false,currentBrowser,contentDoc);
existsHolder.parentNode.removeChild(existsHolder);
return true;]]></body>
                  </method>

                  <method name="handleEvent">
                    <parameter name="aEvent"/>
                    <body><![CDATA[switch (aEvent.type) {
case "DOMMouseScroll":
let aFrameWindow = this.textonlyFrame.contentWindow;
if (aEvent.axis == aEvent.VERTICAL_AXIS)
{
if (aEvent.detail > 0 && aFrameWindow.scrollY >= aFrameWindow.scrollMaxY || aEvent.detail < 0 && aFrameWindow.scrollY == 0)
aEvent.preventDefault();
}

if (aEvent.axis == aEvent.HORIZONTAL_AXIS)
{
if (aEvent.detail > 0 && aFrameWindow.scrollX >= aFrameWindow.scrollMaxX || aEvent.detail < 0 && aFrameWindow.scrollX == 0)
aEvent.preventDefault();
}

break;
case "keydown":
if (aEvent.keyCode == aEvent.DOM_VK_ESCAPE)
this.close();
break;
case "click":
this.close();
break;
case "unload":
if (aEvent.originalTarget == aEvent.target)
this.close();
break;
default:
break;
}
]]></body>
                </method>

                  <method name="_manageContentEventListeners">
                    <parameter name="aAdd"/>
                    <parameter name="aBrowser"/>
                    <parameter name="aDocument"/>
                    <parameter name="aFrameWindow"/>
                    <body><![CDATA[var actionName = aAdd ? "addEventListener" : "removeEventListener";
aBrowser[actionName]("keydown",this,false,false);
aDocument[actionName]("click",this,false,false);
aDocument.defaultView[actionName]("DOMMouseScroll",this,false,false);
if (aFrameWindow)
{
aFrameWindow[actionName]("unload",this,false,false);
aFrameWindow[actionName]("DOMMouseScroll",this,false,false);
}
]]></body>
                  </method>

                  <method name="_appendTextonlyContent">
                    <parameter name="aFrame"/>
                    <body><![CDATA[var contentDoc = aFrame.contentDocument;
var contentDocElement = contentDoc.documentElement;
const kHTMLNS = "http://www.w3.org/1999/xhtml";
var mediaStyle = contentDoc.createElementNS(kHTMLNS,"style");
mediaStyle.setAttribute("media","screen");
contentDocElement.appendChild(mediaStyle);
var mediaStyleSheet = mediaStyle.sheet;
mediaStyleSheet.insertRule("@import url('" + this.frameCSS + "');",mediaStyleSheet.cssRules.length);
var printStyle = contentDoc.createElementNS(kHTMLNS,"style");
printStyle.setAttribute("media","print");
contentDocElement.appendChild(printStyle);
var printStyleSheet = printStyle.sheet;
printStyleSheet.insertRule("@import url('" + this.frameCSSPrint + "');",printStyleSheet.cssRules.length);
var settingsScript = contentDoc.createElementNS(kHTMLNS,"script");
settingsScript.setAttribute("type","text/javascript");
var settingsScriptContent = contentDoc.createTextNode("var FX_MODE = true;                          var readLocale = '" + this.locale.language + "';                          var readConvertLinksToFootnotes = false;                          var readStyle = 'style-newspaper';                          var readSize = 'size-medium';                          var readMargin = 'margin-medium';                          var readThrobberURL = '" + this.throbberURLData + "';                         ");
settingsScript.appendChild(settingsScriptContent);
contentDocElement.appendChild(settingsScript);
var script = contentDoc.createElementNS(kHTMLNS,"script");
script.setAttribute("type","text/javascript");
script.setAttribute("src",this.frameJS);
contentDocElement.appendChild(script);]]></body>
                  </method>

                  <method name="checkCurrentBrowser">
                    <body><![CDATA[var available = false;
var showing = false;
var currentBrowser = gBrowser.mCurrentBrowser;
if (currentBrowser)
{
let url = this.getSpecFromURI(currentBrowser.currentURI);
if (url)
{
available = this._isGoodContentDocument(currentBrowser);
}

}

this.available = available;]]></body>
                  </method>

                  <method name="_isGoodContentDocument">
                    <parameter name="aBrowser"/>
                    <body><![CDATA[var contentDocument = aBrowser.contentDocument;
if (/^https?:\/\//.test(contentDocument.documentURI) && /[^x]html/.test(contentDocument.contentType))
return ! ! contentDocument.getElementsByTagName("body")[0];
return false;]]></body>
                  </method>

                  <method name="getSpecFromURI">
                    <parameter name="aURI"/>
                    <body><![CDATA[try {
if (/https?/.test(aURI.scheme) && aURI.prePath + "/" != aURI.spec.split("#")[0])
return aURI.spec;
}
catch (ex) {
this.api.logger.error(ex);
}

return null;]]></body>
                  </method>
        </implementation>

        <handlers>
            <handler button="0" event="click"><![CDATA[if (this.available)
this.openXclose();]]></handler>
        </handlers>
    </binding>
</bindings>
