API Docs for: 0.0.1
Show:

File: lib/component.jsx

"use strict";

/**
 * React component that views documents using Google Doc Viewer.
 *
 *
 *
 * <i>Copyright (c) 2016 ItsAsbreuk - http://itsasbreuk.nl</i><br>
 * New BSD License - http://choosealicense.com/licenses/bsd-3-clause/
 *
 *
 * @module component.jsx
 * @class Component
 * @since 15.0.0
*/

require("itsa-jsext");

const React = require("react"),
    BASE_URL = "https://docs.google.com/viewer?embedded=true&url=",
    MAIN_CLASS = "itsa-docviewer",
    MAIN_CLASS_PREFIX = MAIN_CLASS+"-",
    IS_NODE = require("itsa-utils").isNode,
    PropTypes = require("prop-types");

// polyfill Element.requestFullScreen:
if (!IS_NODE) {
    (function(ElementPrototype) {
        ElementPrototype.requestFullScreen ||
        (ElementPrototype.requestFullScreen = ElementPrototype.webkitRequestFullScreen ||
                                              ElementPrototype.mozRequestFullScreen ||
                                              ElementPrototype.msRequestFullScreen);
    }(window.Element.prototype));

}

class Component extends React.Component {
    constructor(props) {
        super(props);
        const instance = this;
        instance.state = {
            loading: true
        };
        instance._ready = Promise.itsa_manage();
        instance.fullScreen = instance.fullScreen.bind(instance);
        instance.handleSrcLoad = instance.handleSrcLoad.bind(instance);
    }

    componentDidUpdate(prevProps) {
        const instance = this,
            props = instance.props;
        console.warn('docviewer componentDidUpdate');
        if (prevProps.src!==props.src) {
            console.warn('docviewer componentDidUpdate reset promise', prevProps.src, props.src);
            instance._ready = Promise.itsa_manage();
            if (props.src) {
                instance.setState({
                    loading: true
                });
            }
            else {
                instance.setState({loading: false}, function() {
                    console.warn('docviewer componentDidUpdate no src fulfilling promise');
                    instance._ready.fulfill();
                });
            }
        }
    }

    /**
     * Will show the content into the full screen. Only if `props.allowFullScreen`===true.
     *
     * @method fullScreen
     * @since 0.0.1
     */
    fullScreen() {
        this.props.allowFullScreen && this._iframeNode.requestFullScreen && this._iframeNode.requestFullScreen();
    }

    print() { // return a Promise!
        console.warn('docviewer.print', this.props.src);
        const instance = this;
        if (instance.props.src) {
            console.warn('docviewer.printing waiting for src to be loaded');
            return instance._ready.then(function() {
                console.warn('docviewer.printing', instance.props.src);
                const win = instance._iframeNode.contentWindow || instance._iframeNode;
                if (typeof win.print==='function') {
                    win.print();
                }
            });
        }
        return Promise.resolve();
    }

    /**
     * Hides the "load-message" as specified by this.props.loadingMsg
     *
     * @method handleSrcLoad
     * @since 16.0.5
     */
    handleSrcLoad() {
        const instance = this;
        instance.setState({loading: false}, function() {
            console.warn('docviewer handleSrcLoad fulfilling promise', instance.props.src);
            instance._ready.fulfill();
        });
    }

    /**
     * React render-method --> renderes the Component.
     *
     * @method render
     * @return ReactComponent
     * @since 15.0.0
     */
    render() {
        let className = MAIN_CLASS,
            source, fullscreenBtn, scrolling, loadingMsg;
        const instance = this,
            props = instance.props,
            propsClass = props.className;

        scrolling = props.scrolling;
        (typeof scrolling==='boolean') && (scrolling=scrolling.toString());
        source = props.src;
        if (!IS_NODE && source) {
            if ((source.substr(0, 7).toLowerCase()!=="http://") && (source.substr(0, 8).toLowerCase()!=="https://")) {
               source = window.location.protocol + "//" + window.location.host + source;
            }
            source = encodeURI(BASE_URL + source);
        }
        propsClass && (className+=" "+propsClass);
        if (props.allowFullScreen) {
            fullscreenBtn = (
                <div
                    className={MAIN_CLASS_PREFIX+"full-screen"}
                    onClick={instance.fullScreen} />
            );
        }
        if (instance.state.loading && props.showLoadingMsg) {
            loadingMsg = (
                <div className={MAIN_CLASS_PREFIX+"loading-msg"}>
                    <div>{props.loadingMsg}</div>
                </div>
            );
        }
        return (
            <div className={className} style={props.style}>
                <iframe
                    allowFullScreen={props.allowFullScreen}
                    frameBorder="0"
                    height="100%"
                    onLoad={instance.handleSrcLoad}
                    ref={node => instance._iframeNode = node}
                    scrolling={props.scrolling}
                    src={source}
                    width="100%" />
                {fullscreenBtn}
                {loadingMsg}
            </div>
        );
    }

}

Component.propTypes = {
    /**
     * Allowed to be displayed into full screen mode, by calling `fullScreen()`
     *
     * @property allowFullScreen
     * @type Boolean
     * @since 15.0.0
    */
    allowFullScreen: PropTypes.bool,

    /**
     * Any class to be set on the main component.
     *
     * @property className
     * @type String
     * @since 15.0.0
    */
    className: PropTypes.string,

    /**
     * The message that shows while the document gets loaded
     *
     * @property loadingMsg
     * @default "loading..."
     * @type String
     * @since 16.0.5
    */
    loadingMsg: PropTypes.string,

    /**
     * Whether the browser should provide a scroll bar when needed.
     * Either `auto`, `yes` or `no`
     *
     * @property scrolling
     * @default "auto"
     * @type String|Boolean
     * @since 15.0.0
    */
    scrolling: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),

    /**
     * Whether to show a message (this.props.loadingMsg) during document load
     *
     * @property showLoadingMsg
     * @default false
     * @type Boolean
     * @since 16.0.5
    */
    showLoadingMsg: PropTypes.bool,

    /**
     * The url of the document to be viewed. May be absolute or relative.
     *
     * @property src
     * @type String
     * @since 15.0.0
    */
    src: PropTypes.string
};

Component.defaultProps = {
    loadingMsg: "loading...",
    scrolling: "auto",
    showLoadingMsg: false
};

module.exports = Component;