<commit_before>/**
 * @file Surface Representation
 * @author Alexander Rose <alexander.rose@weirdbyte.de>
 * @private
 */

import { Vector3, Box3 } from "../../lib/three.es6.js";

import { defaults } from "../utils.js";
import Representation from "./representation.js";
import Volume from "../surface/volume.js";
import SurfaceBuffer from "../buffer/surface-buffer.js";
import DoubleSidedBuffer from "../buffer/doublesided-buffer";
import ContourBuffer from "../buffer/contour-buffer.js";

/**
 * Surface representation parameter object.
 * @typedef {Object} SurfaceRepresentationParameters - surface representation parameters
 * @mixes RepresentationParameters
 *
 * @property {String} isolevelType - Meaning of the isolevel value. Either *value* for the literal value or *sigma* as a factor of the sigma of the data. For volume data only.
 * @property {Float} isolevel - The value at which to create the isosurface. For volume data only.
 * @property {Integer} smooth - How many iterations of laplacian smoothing after surface triangulation. For volume data only.
 * @property {Boolean} background - Render the surface in the background, unlit.
 * @property {Boolean} opaqueBack - Render the back-faces (where normals point away from the camera) of the surface opaque, ignoring the transparency parameter.
 * @property {Integer} boxSize - Size of the box to triangulate volume data in. Set to zero to triangulate the whole volume. For volume data only.
 * @property {Boolean} useWorker - Weather or not to triangulate the volume asynchronously in a Web Worker. For volume data only.
 * @property {Boolean} wrap - Wrap volume data around the edges; use in conjuction with boxSize but not larger than the volume dimension. For volume data only.
 */

/**
 * Surface representation
 */
class SurfaceRepresentation extends Representation{

    /**
     * Create Surface representation object
     * @param {Surface|Volume} surface - the surface or volume to be represented
     * @param {Viewer} viewer - a viewer object
     * @param {SurfaceRepresentationParameters} params - surface representation parameters
     */
    constructor( surface, viewer, params ){

        super( surface, viewer, params );

        this.type = "surface";

        this.parameters = Object.assign( {

            isolevelType: {
                type: "select", options: {
                    "value": "value", "sigma": "sigma"
                }
            },
            isolevel: {
                type: "number", precision: 2, max: 1000, min: -1000
            },
            smooth: {
                type: "integer", precision: 1, max: 10, min: 0
            },
            background: {
                type: "boolean", rebuild: true  // FIXME
            },
            opaqueBack: {
                type: "boolean", buffer: true
            },
            boxSize: {
                type: "integer", precision: 1, max: 100, min: 0
            },
            colorVolume: {
                type: "hidden"
            },
            contour: {
                type: "boolean", rebuild: true
            },
            useWorker: {
                type: "boolean", rebuild: true
            },
            wrap: {
                type: "boolean", rebuild: true
            },

        }, this.parameters );

        if( surface instanceof Volume ){
            this.surface = undefined;
            this.volume = surface;
        }else{
            this.surface = surface;
            this.volume = undefined;
        }

        this.boxCenter = new Vector3();
        this.__boxCenter = new Vector3();
        this.box = new Box3();
        this.__box = new Box3();

        this._position = new Vector3();
        this.setBox = function setBox(){
            this._position.copy( viewer.translationGroup.position ).negate();
            if( !this._position.equals( this.boxCenter ) ){
                this.setParameters( { "boxCenter": this._position } );
            }
        };

        this.viewer.signals.ticked.add( this.setBox, this );

        this.init( params );

    }

    init( params ){

        const p = params || {};
        p.colorScheme = defaults( p.colorScheme, "uniform" );
        p.colorValue = defaults( p.colorValue, 0xDDDDDD );

        this.isolevelType  = defaults( p.isolevelType, "sigma" );
        this.isolevel = defaults( p.isolevel, 2.0 );
        this.smooth = defaults( p.smooth, 0 );
        this.background = defaults( p.background, false );
        this.opaqueBack = defaults( p.opaqueBack, true );
        this.boxSize = defaults( p.boxSize, 0 );
        this.colorVolume = defaults( p.colorVolume, undefined );
        this.contour = defaults( p.contour, false );
        this.useWorker = defaults( p.useWorker, true );
        this.wrap = defaults( p.wrap, false );

        super.init( p );

        this.build();

    }

    attach( callback ){

        this.bufferList.forEach( buffer => {
            this.viewer.add( buffer );
        } );

        this.setVisibility( this.visible );

        callback();

    }

    prepare( callback ){

        if( this.volume ){

            let isolevel;

            if( this.isolevelType === "sigma" ){
                isolevel = this.volume.getValueForSigma( this.isolevel );
            }else{
                isolevel = this.isolevel;
            }

            if( !this.surface ||
                this.__isolevel !== isolevel ||
                this.__smooth !== this.smooth ||
                this.__contour !== this.contour ||
                this.__wrap !== this.wrap ||
                this.__boxSize !== this.boxSize ||
                ( this.boxSize > 0 &&
                    !this.__boxCenter.equals( this.boxCenter ) )
            ){
                this.__isolevel = isolevel;
                this.__smooth = this.smooth;
                this.__contour = this.contour;
                this.__wrap = this.wrap
                this.__boxSize = this.boxSize;
                this.__boxCenter.copy( this.boxCenter );
                this.__box.copy( this.box );

                const onSurfaceFinish = surface => {
                    this.surface = surface;
                    callback();
                };

                if( this.useWorker ){
                    this.volume.getSurfaceWorker(
                        isolevel, this.smooth, this.boxCenter, this.boxSize,
                        this.contour, this.wrap, onSurfaceFinish
                    );
                }else{
                    onSurfaceFinish(
                        this.volume.getSurface(
                            isolevel, this.smooth, this.boxCenter, this.boxSize,
                            this.contour, this.wrap
                        )
                    );
                }
            }else{
                callback();
            }

        }else{
            callback();
        }

    }

    getSurfaceData(){

        return {
            position: this.surface.getPosition(),
            color: this.surface.getColor( this.getColorParams() ),
            index: this.surface.getIndex(),
            normal: this.surface.getNormal(),
            picking: this.surface.getPicking()
        };

    }

    create(){

        const sd = this.getSurfaceData();

        let buffer;

        if( this.contour ){

            buffer = new ContourBuffer(
                sd, this.getBufferParams( {
                    wireframe: false
            } ) );

        } else {

            const surfaceBuffer = new SurfaceBuffer(
                sd, this.getBufferParams( {
                    background: this.background,
                    opaqueBack: this.opaqueBack,
                    dullInterior: false
                } ) );

            buffer = new DoubleSidedBuffer( surfaceBuffer );

        }

        this.bufferList.push( buffer );

    }

    update( what ){

        if( this.bufferList.length === 0 ) return;

        what = what || {};

        const surfaceData = {};

        if( what.position ){
            surfaceData.position = this.surface.getPosition();
        }

        if( what.color ){
            surfaceData.color = this.surface.getColor(
                this.getColorParams()
            );
        }

        if( what.index ){
            surfaceData.index = this.surface.getIndex();
        }

        if( what.normal ){
            surfaceData.normal = this.surface.getNormal();
        }

        this.bufferList.forEach( function( buffer ){
            buffer.setAttributes( surfaceData );
        } );

    }

    /**
     * Set representation parameters
     * @alias SurfaceRepresentation#setParameters
     * @param {SurfaceRepresentationParameters} params - surface parameter object
     * @param {Object} [what] - buffer data attributes to be updated,
     *                        note that this needs to be implemented in the
     *                        derived classes. Generally it allows more
     *                        fine-grained control over updating than
     *                        forcing a rebuild.
     * @param {Boolean} what.position - update position data
     * @param {Boolean} what.color - update color data
     * @param {Boolean} [rebuild] - whether or not to rebuild the representation
     * @return {SurfaceRepresentation} this object
     */
    setParameters( params, what, rebuild ){

        if( params && params.isolevelType !== undefined &&
            this.volume
        ){

            if( this.isolevelType === "value" &&
                params.isolevelType === "sigma"
            ){

                this.isolevel = this.volume.getSigmaForValue(
                    this.isolevel
                );

            }else if( this.isolevelType === "sigma" &&
                params.isolevelType === "value"
            ){

                this.isolevel = this.volume.getValueForSigma(
                    this.isolevel
                );

            }

            this.isolevelType = params.isolevelType;

        }

        if( params && params.boxCenter ){
            this.boxCenter.copy( params.boxCenter );
            delete params.boxCenter;
        }

        // Forbid wireframe && contour as in molsurface
        if( params && params.wireframe && (
            params.contour || ( params.contour === undefined && this.contour )
        ) ){
            params.wireframe = false;
        }

        super.setParameters( params, what, rebuild );

        if( this.volume ){
            this.volume.getBox( this.boxCenter, this.boxSize, this.box );
        }

        if( params && params.colorVolume !== undefined ){
            what.color = true;
        }

        if( this.surface && (
                params.isolevel !== undefined ||
                params.smooth !== undefined ||
                params.wrap !== undefined ||
                params.boxSize !== undefined ||
                ( this.boxSize > 0 &&
                    !this.__box.equals( this.box ) )
            )
        ){
            this.build( {
                "position": true,
                "color": true,
                "index": true,
                "normal": !this.contour
            } );
        }

        return this;

    }

    getColorParams(){

        const p = super.getColorParams();

        p.volume = this.colorVolume;

        return p;

    }

    dispose(){

        this.viewer.signals.ticked.remove( this.setBox, this );

        super.dispose();

    }

}

export default SurfaceRepresentation;
<commit_msg>don’t include picking and normal in contour surface creation<commit_after>/**
 * @file Surface Representation
 * @author Alexander Rose <alexander.rose@weirdbyte.de>
 * @private
 */

import { Vector3, Box3 } from "../../lib/three.es6.js";

import { defaults } from "../utils.js";
import Representation from "./representation.js";
import Volume from "../surface/volume.js";
import SurfaceBuffer from "../buffer/surface-buffer.js";
import DoubleSidedBuffer from "../buffer/doublesided-buffer";
import ContourBuffer from "../buffer/contour-buffer.js";

/**
 * Surface representation parameter object.
 * @typedef {Object} SurfaceRepresentationParameters - surface representation parameters
 * @mixes RepresentationParameters
 *
 * @property {String} isolevelType - Meaning of the isolevel value. Either *value* for the literal value or *sigma* as a factor of the sigma of the data. For volume data only.
 * @property {Float} isolevel - The value at which to create the isosurface. For volume data only.
 * @property {Integer} smooth - How many iterations of laplacian smoothing after surface triangulation. For volume data only.
 * @property {Boolean} background - Render the surface in the background, unlit.
 * @property {Boolean} opaqueBack - Render the back-faces (where normals point away from the camera) of the surface opaque, ignoring the transparency parameter.
 * @property {Integer} boxSize - Size of the box to triangulate volume data in. Set to zero to triangulate the whole volume. For volume data only.
 * @property {Boolean} useWorker - Weather or not to triangulate the volume asynchronously in a Web Worker. For volume data only.
 * @property {Boolean} wrap - Wrap volume data around the edges; use in conjuction with boxSize but not larger than the volume dimension. For volume data only.
 */

/**
 * Surface representation
 */
class SurfaceRepresentation extends Representation{

    /**
     * Create Surface representation object
     * @param {Surface|Volume} surface - the surface or volume to be represented
     * @param {Viewer} viewer - a viewer object
     * @param {SurfaceRepresentationParameters} params - surface representation parameters
     */
    constructor( surface, viewer, params ){

        super( surface, viewer, params );

        this.type = "surface";

        this.parameters = Object.assign( {

            isolevelType: {
                type: "select", options: {
                    "value": "value", "sigma": "sigma"
                }
            },
            isolevel: {
                type: "number", precision: 2, max: 1000, min: -1000
            },
            smooth: {
                type: "integer", precision: 1, max: 10, min: 0
            },
            background: {
                type: "boolean", rebuild: true  // FIXME
            },
            opaqueBack: {
                type: "boolean", buffer: true
            },
            boxSize: {
                type: "integer", precision: 1, max: 100, min: 0
            },
            colorVolume: {
                type: "hidden"
            },
            contour: {
                type: "boolean", rebuild: true
            },
            useWorker: {
                type: "boolean", rebuild: true
            },
            wrap: {
                type: "boolean", rebuild: true
            },

        }, this.parameters );

        if( surface instanceof Volume ){
            this.surface = undefined;
            this.volume = surface;
        }else{
            this.surface = surface;
            this.volume = undefined;
        }

        this.boxCenter = new Vector3();
        this.__boxCenter = new Vector3();
        this.box = new Box3();
        this.__box = new Box3();

        this._position = new Vector3();
        this.setBox = function setBox(){
            this._position.copy( viewer.translationGroup.position ).negate();
            if( !this._position.equals( this.boxCenter ) ){
                this.setParameters( { "boxCenter": this._position } );
            }
        };

        this.viewer.signals.ticked.add( this.setBox, this );

        this.init( params );

    }

    init( params ){

        const p = params || {};
        p.colorScheme = defaults( p.colorScheme, "uniform" );
        p.colorValue = defaults( p.colorValue, 0xDDDDDD );

        this.isolevelType  = defaults( p.isolevelType, "sigma" );
        this.isolevel = defaults( p.isolevel, 2.0 );
        this.smooth = defaults( p.smooth, 0 );
        this.background = defaults( p.background, false );
        this.opaqueBack = defaults( p.opaqueBack, true );
        this.boxSize = defaults( p.boxSize, 0 );
        this.colorVolume = defaults( p.colorVolume, undefined );
        this.contour = defaults( p.contour, false );
        this.useWorker = defaults( p.useWorker, true );
        this.wrap = defaults( p.wrap, false );

        super.init( p );

        this.build();

    }

    attach( callback ){

        this.bufferList.forEach( buffer => {
            this.viewer.add( buffer );
        } );

        this.setVisibility( this.visible );

        callback();

    }

    prepare( callback ){

        if( this.volume ){

            let isolevel;

            if( this.isolevelType === "sigma" ){
                isolevel = this.volume.getValueForSigma( this.isolevel );
            }else{
                isolevel = this.isolevel;
            }

            if( !this.surface ||
                this.__isolevel !== isolevel ||
                this.__smooth !== this.smooth ||
                this.__contour !== this.contour ||
                this.__wrap !== this.wrap ||
                this.__boxSize !== this.boxSize ||
                ( this.boxSize > 0 &&
                    !this.__boxCenter.equals( this.boxCenter ) )
            ){
                this.__isolevel = isolevel;
                this.__smooth = this.smooth;
                this.__contour = this.contour;
                this.__wrap = this.wrap
                this.__boxSize = this.boxSize;
                this.__boxCenter.copy( this.boxCenter );
                this.__box.copy( this.box );

                const onSurfaceFinish = surface => {
                    this.surface = surface;
                    callback();
                };

                if( this.useWorker ){
                    this.volume.getSurfaceWorker(
                        isolevel, this.smooth, this.boxCenter, this.boxSize,
                        this.contour, this.wrap, onSurfaceFinish
                    );
                }else{
                    onSurfaceFinish(
                        this.volume.getSurface(
                            isolevel, this.smooth, this.boxCenter, this.boxSize,
                            this.contour, this.wrap
                        )
                    );
                }
            }else{
                callback();
            }

        }else{
            callback();
        }

    }

    create(){

        const sd = {
            position: this.surface.getPosition(),
            color: this.surface.getColor( this.getColorParams() ),
            index: this.surface.getIndex(),
        };

        let buffer;

        if( this.contour ){

            buffer = new ContourBuffer(
                sd, this.getBufferParams( {
                    wireframe: false
            } ) );

        } else {

            sd.normal = this.surface.getNormal(),
            sd.picking = this.surface.getPicking()

            const surfaceBuffer = new SurfaceBuffer(
                sd, this.getBufferParams( {
                    background: this.background,
                    opaqueBack: this.opaqueBack,
                    dullInterior: false
                } ) );

            buffer = new DoubleSidedBuffer( surfaceBuffer );

        }

        this.bufferList.push( buffer );

    }

    update( what ){

        if( this.bufferList.length === 0 ) return;

        what = what || {};

        const surfaceData = {};

        if( what.position ){
            surfaceData.position = this.surface.getPosition();
        }

        if( what.color ){
            surfaceData.color = this.surface.getColor(
                this.getColorParams()
            );
        }

        if( what.index ){
            surfaceData.index = this.surface.getIndex();
        }

        if( what.normal ){
            surfaceData.normal = this.surface.getNormal();
        }

        this.bufferList.forEach( function( buffer ){
            buffer.setAttributes( surfaceData );
        } );

    }

    /**
     * Set representation parameters
     * @alias SurfaceRepresentation#setParameters
     * @param {SurfaceRepresentationParameters} params - surface parameter object
     * @param {Object} [what] - buffer data attributes to be updated,
     *                        note that this needs to be implemented in the
     *                        derived classes. Generally it allows more
     *                        fine-grained control over updating than
     *                        forcing a rebuild.
     * @param {Boolean} what.position - update position data
     * @param {Boolean} what.color - update color data
     * @param {Boolean} [rebuild] - whether or not to rebuild the representation
     * @return {SurfaceRepresentation} this object
     */
    setParameters( params, what, rebuild ){

        if( params && params.isolevelType !== undefined &&
            this.volume
        ){

            if( this.isolevelType === "value" &&
                params.isolevelType === "sigma"
            ){

                this.isolevel = this.volume.getSigmaForValue(
                    this.isolevel
                );

            }else if( this.isolevelType === "sigma" &&
                params.isolevelType === "value"
            ){

                this.isolevel = this.volume.getValueForSigma(
                    this.isolevel
                );

            }

            this.isolevelType = params.isolevelType;

        }

        if( params && params.boxCenter ){
            this.boxCenter.copy( params.boxCenter );
            delete params.boxCenter;
        }

        // Forbid wireframe && contour as in molsurface
        if( params && params.wireframe && (
            params.contour || ( params.contour === undefined && this.contour )
        ) ){
            params.wireframe = false;
        }

        super.setParameters( params, what, rebuild );

        if( this.volume ){
            this.volume.getBox( this.boxCenter, this.boxSize, this.box );
        }

        if( params && params.colorVolume !== undefined ){
            what.color = true;
        }

        if( this.surface && (
                params.isolevel !== undefined ||
                params.smooth !== undefined ||
                params.wrap !== undefined ||
                params.boxSize !== undefined ||
                ( this.boxSize > 0 &&
                    !this.__box.equals( this.box ) )
            )
        ){
            this.build( {
                "position": true,
                "color": true,
                "index": true,
                "normal": !this.contour
            } );
        }

        return this;

    }

    getColorParams(){

        const p = super.getColorParams();

        p.volume = this.colorVolume;

        return p;

    }

    dispose(){

        this.viewer.signals.ticked.remove( this.setBox, this );

        super.dispose();

    }

}

export default SurfaceRepresentation;
<|endoftext|>


<commit_before>;(function($){
    var jsonpID = 0
    function parseArguments(url, data, success, dataType){
        $.isFunction(data) && (dataType = success, success = data, data = undefined),
        $.isFunction(success) || (dataType = success, success = undefined)
        return {
            url: url,
            data: data,
            success: success,
            dataType: dataType
        }
    }
    $.extend({
        ajaxSettings:{
            // 默认请求类型
            type:'GET',
            // 如果请求成功时执行回调
            success:function(){},
            // 如果请求失败时执行回调
            error:function(){},
            xhr:function () {
              return new window.XMLHttpRequest();
            },
            processData:true,
            async:true,
            complete:function(){},//要求执行回调完整（包括：错误和成功）
            // MIME类型的映射
            accepts:{
                script:'text/javascript, application/javascript',
                json:  'application/json',
                xml:   'application/xml, text/xml',
                html:  'text/html',
                text:  'text/plain'
            },
            // 应该被允许缓存GET响应
            cache: true
        },
        param:function(obj,traditional,scope){
            if($.type(obj) == "String") return obj;
            var params = [],str='';
            params.add=function(key, value){
                this.push(encodeURIComponent(key) + '=' + encodeURIComponent(value== null?"":value))
            };
            if(scope==true&&$.type(obj)=='Object') params.add(traditional,obj)
            else {
                for(var p in obj) {
                    var v = obj[p],str='',
                        k = (function(){
                            if (traditional) {
                                if (traditional==true) return p;
                                else{
                                    if(scope&&$.type(obj)=='Array'){
                                        return traditional
                                    }
                                    return traditional + "[" + ($.type(obj)=='Array'?"":p) + "]";
                                };
                            };
                            return p
                        })();
                    if (typeof v=="object") {
                        str=this.param(v, k ,traditional);
                    }else str=params.add(k,v);

                    if (str) params.push(str);
                };
            }
            return params.join('&');
        },
        get:function(url, success){return $.ajax(parseArguments.apply(null, arguments))},
        post:function(url, data, success, dataType){
            var options = parseArguments.apply(null, arguments);
            return options.type = "POST", $.ajax(options);
        },
        getJSON:function(/* url, data, success */){
            var options = parseArguments.apply(null, arguments),
                url = arguments[0];
            if(url&&url == document.location.host) options.dataType = 'json';
            else options.dataType = 'jsonp';
            return this.ajax(options);
        },
        ajaxJSONP:function (options) {
            var _callbackName = options.jsonpCallback,
            callbackName = ($.isFunction(_callbackName) ? _callbackName() : _callbackName) || ('jsonp' + (++jsonpID)),
            script = document.createElement('script'),
            originalCallback = window[callbackName],
            responseData,xhr={};

            $(script).on('load error', function(e, errorType){
                $(script).off().remove()
                if (e.type == 'error' || !responseData) {
                    options.error(e, errorType || 'error',options)
                } else {
                    options.success(responseData[0], xhr, options)
                }
                window[callbackName] = originalCallback
                if (responseData && $.isFunction(originalCallback))
                originalCallback(responseData[0])
                originalCallback = responseData = undefined
            })

            //插入script 获取返回的数据
            window[callbackName] = function(){responseData = arguments}
            script.src = options.url.replace(/\?(.+)=\?/, '?$1=' + callbackName)
            document.head.appendChild(script)
            return options.xhr()
        },
        ajax:function(options){
            var key,settings,
                setHeader = function(name, value) { headers[name.toLowerCase()] = [name, value] },
                appendQuery = function(url, query) {
                    if (query == '') return url
                    return (url + '&' + query).replace(/[&?]{1,2}/, '?')
                },
                serializeData = function(options){
                    if (options.processData && options.data && $.type(options.data) != "string")
                        options.data = $.param(options.data, options.traditional)
                    if (options.data && (!options.type || options.type.toUpperCase() == 'GET'))
                        options.url = appendQuery(options.url, options.data), options.data = undefined
                };
                options = options || {};
                if ($.isString(options)) {
                    if (arguments[0]=="GET") {
                        var  urls=arguments[1];
                        if (arguments[2]&&$.isFunction(arguments[2])) {
                            $.get(urls,arguments[2])
                        }else if(arguments[2]&&$.isJson(arguments[2])){
                            $.get(urls.indexOf('?')>-1?urls+'&'+this.param(arguments[2]):urls+'?'+this.param(arguments[2]),arguments[3])
                        };
                    }else if(arguments[0]=="POST"){
                        $.post(arguments[1],arguments[2],arguments[3],arguments[4])
                    };
                    return;
                };
                settings=$.extend({}, options || {});
                for (key in $.ajaxSettings) if (settings[key] === undefined) settings[key] = $.ajaxSettings[key];
                //{ type, url, data, success, dataType, contentType }
            serializeData(settings)

            //jsonp
            var dataType = settings.dataType, hasPlaceholder = /\?.+=\?/.test(settings.url)
            if (hasPlaceholder) dataType = 'jsonp';
            //给URL后面加上时间戳
            if (settings.cache === false || (
                (!options || options.cache !== true) &&
                ('script' == dataType || 'jsonp' == dataType)
            )) {
                settings.url = appendQuery(settings.url, '_=' + Date.now())
            }
            //判断是否为jsonp
            if ('jsonp' == dataType) {
                if (!hasPlaceholder) settings.url = appendQuery(settings.url,settings.jsonp ? (settings.jsonp + '=?') : settings.jsonp === false ? '' : 'callback=?')
                return $.ajaxJSONP(settings)
            }

            var data = settings.data,
                callback = settings.success || function(){},
                errback = settings.error || function(){},
                mime = $.ajaxSettings.accepts[settings.dataType],
                content = settings.contentType,
                xhr = new XMLHttpRequest(),
                nativeSetHeader = xhr.setRequestHeader,
                headers={};
                if (!settings.crossDomain) setHeader('X-Requested-With', 'XMLHttpRequest'),setHeader('Accept', mime || '*/*');
                if (settings.headers) for (name in settings.headers) setHeader(name, settings.headers[name]);
                if (settings.contentType || (settings.contentType !== false && settings.data && settings.type.toUpperCase() != 'GET'))
                    setHeader('Content-Type', settings.contentType || 'application/x-www-form-urlencoded');
            xhr.onreadystatechange = function(){
                if (xhr.readyState == 4) {
                    if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 0) {
                        if (mime == 'application/json'&&!(/^\s*$/.test(xhr.responseText))) {
                            var result, error = false;
                                result = xhr.responseText
                            try {
                                if (settings.dataType == 'script')    (1,eval)(result)
                                else if (settings.dataType == 'xml')  result = xhr.responseXML
                                else if (settings.dataType == 'json') result = /^\s*$/.test(result) ? null : JSON.parse(result)
                            } catch (e) { error = e }

                            if (error) errback(error, 'parsererror', xhr, settings);
                            else callback(result, 'success', xhr);
                        } else {
                            callback(xhr.responseText, 'success', xhr)
                        };
                    } else {
                        settings.complete(xhr, error ? 'error' : 'success')
                    }
                }
            };
            if (data&&data instanceof Object&&settings.type=='GET'){
                data?settings.url =(settings.url.indexOf('?')>-1?settings.url +'&'+ data:settings.url +'?'+ data) :null;
            }
            xhr.open(settings.type, settings.url, true);
            if (mime) xhr.setRequestHeader('Accept', mime);
            if (data instanceof Object && mime == 'application/json' ) data = JSON.stringify(data), content = content || 'application/json';
            for (name in headers) nativeSetHeader.apply(xhr, headers[name]);

            xhr.send(data?data:null);
        }
    });
    $.fn.extend({
        load:function (/*url, data, success*/) {
            if (!this.length || arguments.length === 0) return this
            var self = this, parts = arguments[0].split(/\s/), selector,
                options = parseArguments.apply(null, arguments)
                callback = options.success
            if (parts.length > 1){
                options.url = parts[0], selector = parts[1]
            }
            options.success = function(response){
                response = response.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,'')
                self.html(selector ? $('<div>').html(response).find(selector) : response)
                callback && callback.apply(self, arguments)
            }
            $.ajax(options)
            return this
        }
    });
})(JSLite);<commit_msg>解决绑定load事件与从服务器加载数据load方法冲突<commit_after>;(function($){
    var jsonpID = 0
    function parseArguments(url, data, success, dataType){
        $.isFunction(data) && (dataType = success, success = data, data = undefined),
        $.isFunction(success) || (dataType = success, success = undefined)
        return {
            url: url,
            data: data,
            success: success,
            dataType: dataType
        }
    }
    $.extend({
        ajaxSettings:{
            // 默认请求类型
            type:'GET',
            // 如果请求成功时执行回调
            success:function(){},
            // 如果请求失败时执行回调
            error:function(){},
            xhr:function () {
              return new window.XMLHttpRequest();
            },
            processData:true,
            async:true,
            complete:function(){},//要求执行回调完整（包括：错误和成功）
            // MIME类型的映射
            accepts:{
                script:'text/javascript, application/javascript',
                json:  'application/json',
                xml:   'application/xml, text/xml',
                html:  'text/html',
                text:  'text/plain'
            },
            // 应该被允许缓存GET响应
            cache: true
        },
        param:function(obj,traditional,scope){
            if($.type(obj) == "String") return obj;
            var params = [],str='';
            params.add=function(key, value){
                this.push(encodeURIComponent(key) + '=' + encodeURIComponent(value== null?"":value))
            };
            if(scope==true&&$.type(obj)=='Object') params.add(traditional,obj)
            else {
                for(var p in obj) {
                    var v = obj[p],str='',
                        k = (function(){
                            if (traditional) {
                                if (traditional==true) return p;
                                else{
                                    if(scope&&$.type(obj)=='Array'){
                                        return traditional
                                    }
                                    return traditional + "[" + ($.type(obj)=='Array'?"":p) + "]";
                                };
                            };
                            return p
                        })();
                    if (typeof v=="object") {
                        str=this.param(v, k ,traditional);
                    }else str=params.add(k,v);

                    if (str) params.push(str);
                };
            }
            return params.join('&');
        },
        get:function(url, success){return $.ajax(parseArguments.apply(null, arguments))},
        post:function(url, data, success, dataType){
            var options = parseArguments.apply(null, arguments);
            return options.type = "POST", $.ajax(options);
        },
        getJSON:function(/* url, data, success */){
            var options = parseArguments.apply(null, arguments),
                url = arguments[0];
            if(url&&url == document.location.host) options.dataType = 'json';
            else options.dataType = 'jsonp';
            return this.ajax(options);
        },
        ajaxJSONP:function (options) {
            var _callbackName = options.jsonpCallback,
            callbackName = ($.isFunction(_callbackName) ? _callbackName() : _callbackName) || ('jsonp' + (++jsonpID)),
            script = document.createElement('script'),
            originalCallback = window[callbackName],
            responseData,xhr={};

            $(script).on('load error', function(e, errorType){
                $(script).off().remove()
                if (e.type == 'error' || !responseData) {
                    options.error(e, errorType || 'error',options)
                } else {
                    options.success(responseData[0], xhr, options)
                }
                window[callbackName] = originalCallback
                if (responseData && $.isFunction(originalCallback))
                originalCallback(responseData[0])
                originalCallback = responseData = undefined
            })

            //插入script 获取返回的数据
            window[callbackName] = function(){responseData = arguments}
            script.src = options.url.replace(/\?(.+)=\?/, '?$1=' + callbackName)
            document.head.appendChild(script)
            return options.xhr()
        },
        ajax:function(options){
            var key,settings,
                setHeader = function(name, value) { headers[name.toLowerCase()] = [name, value] },
                appendQuery = function(url, query) {
                    if (query == '') return url
                    return (url + '&' + query).replace(/[&?]{1,2}/, '?')
                },
                serializeData = function(options){
                    if (options.processData && options.data && $.type(options.data) != "string")
                        options.data = $.param(options.data, options.traditional)
                    if (options.data && (!options.type || options.type.toUpperCase() == 'GET'))
                        options.url = appendQuery(options.url, options.data), options.data = undefined
                };
                options = options || {};
                if ($.isString(options)) {
                    if (arguments[0]=="GET") {
                        var  urls=arguments[1];
                        if (arguments[2]&&$.isFunction(arguments[2])) {
                            $.get(urls,arguments[2])
                        }else if(arguments[2]&&$.isJson(arguments[2])){
                            $.get(urls.indexOf('?')>-1?urls+'&'+this.param(arguments[2]):urls+'?'+this.param(arguments[2]),arguments[3])
                        };
                    }else if(arguments[0]=="POST"){
                        $.post(arguments[1],arguments[2],arguments[3],arguments[4])
                    };
                    return;
                };
                settings=$.extend({}, options || {});
                for (key in $.ajaxSettings) if (settings[key] === undefined) settings[key] = $.ajaxSettings[key];
                //{ type, url, data, success, dataType, contentType }
            serializeData(settings)

            //jsonp
            var dataType = settings.dataType, hasPlaceholder = /\?.+=\?/.test(settings.url)
            if (hasPlaceholder) dataType = 'jsonp';
            //给URL后面加上时间戳
            if (settings.cache === false || (
                (!options || options.cache !== true) &&
                ('script' == dataType || 'jsonp' == dataType)
            )) {
                settings.url = appendQuery(settings.url, '_=' + Date.now())
            }
            //判断是否为jsonp
            if ('jsonp' == dataType) {
                if (!hasPlaceholder) settings.url = appendQuery(settings.url,settings.jsonp ? (settings.jsonp + '=?') : settings.jsonp === false ? '' : 'callback=?')
                return $.ajaxJSONP(settings)
            }

            var data = settings.data,
                callback = settings.success || function(){},
                errback = settings.error || function(){},
                mime = $.ajaxSettings.accepts[settings.dataType],
                content = settings.contentType,
                xhr = new XMLHttpRequest(),
                nativeSetHeader = xhr.setRequestHeader,
                headers={};
                if (!settings.crossDomain) setHeader('X-Requested-With', 'XMLHttpRequest'),setHeader('Accept', mime || '*/*');
                if (settings.headers) for (name in settings.headers) setHeader(name, settings.headers[name]);
                if (settings.contentType || (settings.contentType !== false && settings.data && settings.type.toUpperCase() != 'GET'))
                    setHeader('Content-Type', settings.contentType || 'application/x-www-form-urlencoded');
            xhr.onreadystatechange = function(){
                if (xhr.readyState == 4) {
                    if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 0) {
                        if (mime == 'application/json'&&!(/^\s*$/.test(xhr.responseText))) {
                            var result, error = false;
                                result = xhr.responseText
                            try {
                                if (settings.dataType == 'script')    (1,eval)(result)
                                else if (settings.dataType == 'xml')  result = xhr.responseXML
                                else if (settings.dataType == 'json') result = /^\s*$/.test(result) ? null : JSON.parse(result)
                            } catch (e) { error = e }

                            if (error) errback(error, 'parsererror', xhr, settings);
                            else callback(result, 'success', xhr);
                        } else {
                            callback(xhr.responseText, 'success', xhr)
                        };
                    } else {
                        settings.complete(xhr, error ? 'error' : 'success')
                    }
                }
            };
            if (data&&data instanceof Object&&settings.type=='GET'){
                data?settings.url =(settings.url.indexOf('?')>-1?settings.url +'&'+ data:settings.url +'?'+ data) :null;
            }
            xhr.open(settings.type, settings.url, true);
            if (mime) xhr.setRequestHeader('Accept', mime);
            if (data instanceof Object && mime == 'application/json' ) data = JSON.stringify(data), content = content || 'application/json';
            for (name in headers) nativeSetHeader.apply(xhr, headers[name]);

            xhr.send(data?data:null);
        }
    });
    var _load = $.fn.load;
    $.fn.extend({
        load:function (url, data, success) {
            //兼容 onload 事件
            if (arguments[0] && typeof arguments[0] !== "string" && _load ) return _load.apply( this, arguments );
            console.log("test")
            if (!this.length || arguments.length === 0) return this
            var self = this, parts = arguments[0].split(/\s/), selector,
                options = parseArguments(url, data, success),
                callback = options.success;
            if (parts.length > 1){
                options.url = parts[0], selector = parts[1]
            }
            options.success = function(response){
                response = response.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,'')
                self.html(selector ? $('<div>').html(response).find(selector) : response)
                callback && callback.apply(self, arguments)
            }
            $.ajax(options)
            return this
        }
    });
})(JSLite);<|endoftext|>


<commit_before>window.cls || (window.cls = {});

/**
 * @constructor
 * @extends ViewBase
 */
cls.ResourceDetailView = function(id, name, container_class, html, default_handler, network_logger) {
  if (cls.ResourceDetailView.instance)
  {
    return cls.ResourceDetailView.instance;
  }
  cls.ResourceDetailView.instance = this;

  this._service = new cls.ResourceManagerService(this, network_logger);

  this.createView = function(container)
  {
    if (this.resource && this.resource.data)
      container.clearAndRender( templates.resource_detail.formatting_data(this.resource) );

    container.clearAndRender( templates.resource_detail.update(this.resource) );
    if(this.data)
      this.go_to_line(container,this.data);

    this.text_search.update_search();
  };

  this.create_disabled_view = function(container)
  {
    container.clearAndRender(window.templates.disabled_view());
  };

  const HIGHLIGHTED_LINE_CLASSNAME = 'highlighted-line';
  const RESOURCE_DETAIL_CONTAINER_CLASSNAME = 'resource-detail-container';
  const TEXT = document.TEXT_NODE;
  const ELE  = document.ELEMENT_NODE;
  this._span = document.createElement('span');
  this._span.textContent = ' ';
  this._line_count = 0;
  this._line_found = false;
  this._target_line = 0;
  this._root_ele = null;
  this._tops = [];

  this._highlight_line = function(ele)
  {
    const CR = "\r";
    const LF = "\n";
    var child = ele.firstChild;
    while (child && !this._line_found)
    {
      if (child.nodeType == ELE)
      {
        this._highlight_line(child);
      }
      else if (child.nodeType == TEXT)
      {
        var value = child.nodeValue;
        for (var pos = 0, len = value.length; pos < len; pos++)
        {
          var c = value.charAt(pos);
          // Linefeed recognition will not support Acorn BBC spooled text output
          if ((c == CR ) || (c == LF))
          {
            this._line_count++;
            if (this._line_count == this._target_line)
            {
              var target_pos = child.splitText(pos);
              child.parentNode.insertBefore(this._span, target_pos);
              this._tops.push(this._span.getBoundingClientRect().top);
              child.parentNode.removeChild(this._span);
              child.parentNode.normalize();
              if (this._tops.length < 2)
              {
                this._target_line+=1;
              }
              else
              {
                var scroll_container = ele;
                var container_top = scroll_container.getBoundingClientRect().top;
                var delta = this._tops[1] - this._tops[0];
                var scroll_top = scroll_container.scrollTop;
                ele.addClass(HIGHLIGHTED_LINE_CLASSNAME);
                ele.style.cssText =
                  "background-size: 100% " + delta + "px;" +
                  "background-position: 0 " +
                    (this._tops[0] - container_top + scroll_top) + "px;";

                var scroll_position = scroll_top + this._tops[0] - container_top;
                if (scroll_position <= this._root_ele.parentNode.clientHeight)
                {
                  scroll_position-=64;
                }
                this._root_ele.scrollTop = scroll_position;
                this._line_found = true;
                return;
              }
            }
            if ((c == CR) && (value.charAt(pos+1) == LF))
            {
              pos++;
            }
          }
        }
      }
      child = child && child.nextSibling;
    }
  }

  this.clear_line_highlight = function(container)
  {
    // reset all properties
    this._line_count = 0;
    this._line_found = false;
    this._target_line = 0;
    this._tops = [];
    var _ele = container.querySelectorAll('.'+HIGHLIGHTED_LINE_CLASSNAME)[0];
    if (_ele)
      _ele.removeClass(HIGHLIGHTED_LINE_CLASSNAME)
  }

  this.go_to_line = function(container, data)
  {
    if (!data || !(data.lines && data.lines.length))
      return;

    this._root_ele = container.getElementsByClassName(RESOURCE_DETAIL_CONTAINER_CLASSNAME)[0];
    if (this._root_ele)
    {
      this.clear_line_highlight(this._root_ele)
      this._target_line = parseInt(data.lines[0]);
      this._highlight_line(this._root_ele);
    }
  };

  this._show_resource_by_instance = function(resource)
  {
    this.resource = resource;
    if (!resource || !resource.data)
      return false;

    this._service.highlight_resource(resource.id);

    if (resource.data)
      this.update();
    else
      this._show_resource_by_url(resource.url);
  };

  this._show_resource_by_id = function(id)
  {
    var resource = this._service.get_resource(id);

    this._show_resource_by_instance(resource);
  };

  this._show_resource_by_url = function(url)
  {
    var resource = this._service.get_resource_for_url(url);
    if (resource && resource.data)
      this._show_resource_by_instance(resource);
    else
      this._service.request_resource(url, this.show_resource.bind(this), this.data);
  };

  this.show_resource = function(resource, data)
  {
    this.data = data;
    this.resource = resource;

    if (resource instanceof cls.ResourceInfo)
      this._show_resource_by_instance(resource);
    else if (resource == Number(resource))
      this._show_resource_by_id(resource);
    else if (resource == String(resource))
      this._show_resource_by_url(resource);
    else
      this.update();

    window.UI.instance.show_view( this.id );
  };

  this.init(id, name, container_class, html, default_handler);
};

cls.ResourceDetailView.create_ui_widgets = function()
{
  new ToolbarConfig(
  {
    view:'resource_detail_view',
    groups:
    [
      {
        type: UI.TYPE_INPUT,
        items:
        [
          {
            handler: "resource-text-search",
            shortcuts: "resource-text-search",
            title: ui_strings.S_SEARCH_INPUT_TOOLTIP,
            label: ui_strings.S_INPUT_DEFAULT_TEXT_SEARCH
          }
        ]
      }
    ]
  });

  var text_search = window.views.resource_detail_view.text_search = new TextSearch();

  window.eventHandlers.input["resource-text-search"] = function(event, target)
  {
    text_search.searchDelayed(target.value);
  };

  ActionBroker.
    get_instance().
    get_global_handler().
      register_shortcut_listener
      (
        "resource-text-search",
        cls.Helpers.shortcut_search_cb.bind(text_search)
      );

  var on_view_created = function(msg)
  {
    if (msg.id === "resource_detail_view")
    {
      var scroll_container = msg.container.querySelector(".request-details");
      if (!scroll_container)
        scroll_container = msg.container.querySelector(".resource-detail-container");

      if (scroll_container)
      {
        text_search.setContainer(scroll_container);
        text_search.setFormInput(
          views.resource_detail_view.getToolbarControl(msg.container, "resource-text-search")
        );
      }
    }
  }

  var on_view_destroyed = function(msg)
  {
    if (msg.id == "resource_detail_view")
      text_search.cleanup();
  }

  window.messages.addListener("view-created", on_view_created);
  window.messages.addListener("view-destroyed", on_view_destroyed);
}

cls.ResourceDetailView.prototype = ViewBase;

<commit_msg>DRYed the _show_resource* code<commit_after>window.cls || (window.cls = {});

/**
 * @constructor
 * @extends ViewBase
 */
cls.ResourceDetailView = function(id, name, container_class, html, default_handler, network_logger) {
  if (cls.ResourceDetailView.instance)
  {
    return cls.ResourceDetailView.instance;
  }
  cls.ResourceDetailView.instance = this;

  this._service = new cls.ResourceManagerService(this, network_logger);

  this.createView = function(container)
  {
    if (this.resource && this.resource.data)
      container.clearAndRender( templates.resource_detail.formatting_data(this.resource) );

    container.clearAndRender( templates.resource_detail.update(this.resource) );
    if(this.data)
      this.go_to_line(container,this.data);

    this.text_search.update_search();
  };

  this.create_disabled_view = function(container)
  {
    container.clearAndRender(window.templates.disabled_view());
  };

  const HIGHLIGHTED_LINE_CLASSNAME = 'highlighted-line';
  const RESOURCE_DETAIL_CONTAINER_CLASSNAME = 'resource-detail-container';
  const TEXT = document.TEXT_NODE;
  const ELE  = document.ELEMENT_NODE;
  this._span = document.createElement('span');
  this._span.textContent = ' ';
  this._line_count = 0;
  this._line_found = false;
  this._target_line = 0;
  this._root_ele = null;
  this._tops = [];

  this._highlight_line = function(ele)
  {
    const CR = "\r";
    const LF = "\n";
    var child = ele.firstChild;
    while (child && !this._line_found)
    {
      if (child.nodeType == ELE)
      {
        this._highlight_line(child);
      }
      else if (child.nodeType == TEXT)
      {
        var value = child.nodeValue;
        for (var pos = 0, len = value.length; pos < len; pos++)
        {
          var c = value.charAt(pos);
          // Linefeed recognition will not support Acorn BBC spooled text output
          if ((c == CR ) || (c == LF))
          {
            this._line_count++;
            if (this._line_count == this._target_line)
            {
              var target_pos = child.splitText(pos);
              child.parentNode.insertBefore(this._span, target_pos);
              this._tops.push(this._span.getBoundingClientRect().top);
              child.parentNode.removeChild(this._span);
              child.parentNode.normalize();
              if (this._tops.length < 2)
              {
                this._target_line+=1;
              }
              else
              {
                var scroll_container = ele;
                var container_top = scroll_container.getBoundingClientRect().top;
                var delta = this._tops[1] - this._tops[0];
                var scroll_top = scroll_container.scrollTop;
                ele.addClass(HIGHLIGHTED_LINE_CLASSNAME);
                ele.style.cssText =
                  "background-size: 100% " + delta + "px;" +
                  "background-position: 0 " +
                    (this._tops[0] - container_top + scroll_top) + "px;";

                var scroll_position = scroll_top + this._tops[0] - container_top;
                if (scroll_position <= this._root_ele.parentNode.clientHeight)
                {
                  scroll_position-=64;
                }
                this._root_ele.scrollTop = scroll_position;
                this._line_found = true;
                return;
              }
            }
            if ((c == CR) && (value.charAt(pos+1) == LF))
            {
              pos++;
            }
          }
        }
      }
      child = child && child.nextSibling;
    }
  }

  this.clear_line_highlight = function(container)
  {
    // reset all properties
    this._line_count = 0;
    this._line_found = false;
    this._target_line = 0;
    this._tops = [];
    var _ele = container.querySelectorAll('.'+HIGHLIGHTED_LINE_CLASSNAME)[0];
    if (_ele)
      _ele.removeClass(HIGHLIGHTED_LINE_CLASSNAME)
  }

  this.go_to_line = function(container, data)
  {
    if (!data || !(data.lines && data.lines.length))
      return;

    this._root_ele = container.getElementsByClassName(RESOURCE_DETAIL_CONTAINER_CLASSNAME)[0];
    if (this._root_ele)
    {
      this.clear_line_highlight(this._root_ele)
      this._target_line = parseInt(data.lines[0]);
      this._highlight_line(this._root_ele);
    }
  };

  this._show_resource = function(resource)
  {
    if (!resource || !resource.data)
      return false;

    this.resource = resource;
    this._service.highlight_resource(resource.id);
    this.update();

    return true;
  };

  this._show_resource_by_instance = function(resource)
  {
    if (!this._show_resource(resource))
      this._show_resource_by_url(resource.url);
  };

  this._show_resource_by_id = function(id)
  {
    var resource = this._service.get_resource(id);

    this._show_resource_by_instance(resource);
  };

  this._show_resource_by_url = function(url)
  {
    var resource = this._service.get_resource_for_url(url);

    if (!this._show_resource(resource))
      this._service.request_resource(url, this.show_resource.bind(this), this.data);
  };

  this.show_resource = function(resource, data)
  {
    this.data = data;
    this.resource = resource;

    if (resource instanceof cls.ResourceInfo)
      this._show_resource_by_instance(resource);
    else if (resource == Number(resource))
      this._show_resource_by_id(resource);
    else if (resource == String(resource))
      this._show_resource_by_url(resource);
    else
      this.update();

    window.UI.instance.show_view( this.id );
  };

  this.init(id, name, container_class, html, default_handler);
};

cls.ResourceDetailView.create_ui_widgets = function()
{
  new ToolbarConfig(
  {
    view:'resource_detail_view',
    groups:
    [
      {
        type: UI.TYPE_INPUT,
        items:
        [
          {
            handler: "resource-text-search",
            shortcuts: "resource-text-search",
            title: ui_strings.S_SEARCH_INPUT_TOOLTIP,
            label: ui_strings.S_INPUT_DEFAULT_TEXT_SEARCH
          }
        ]
      }
    ]
  });

  var text_search = window.views.resource_detail_view.text_search = new TextSearch();

  window.eventHandlers.input["resource-text-search"] = function(event, target)
  {
    text_search.searchDelayed(target.value);
  };

  ActionBroker.
    get_instance().
    get_global_handler().
      register_shortcut_listener
      (
        "resource-text-search",
        cls.Helpers.shortcut_search_cb.bind(text_search)
      );

  var on_view_created = function(msg)
  {
    if (msg.id === "resource_detail_view")
    {
      var scroll_container = msg.container.querySelector(".request-details");
      if (!scroll_container)
        scroll_container = msg.container.querySelector(".resource-detail-container");

      if (scroll_container)
      {
        text_search.setContainer(scroll_container);
        text_search.setFormInput(
          views.resource_detail_view.getToolbarControl(msg.container, "resource-text-search")
        );
      }
    }
  }

  var on_view_destroyed = function(msg)
  {
    if (msg.id == "resource_detail_view")
      text_search.cleanup();
  }

  window.messages.addListener("view-created", on_view_created);
  window.messages.addListener("view-destroyed", on_view_destroyed);
}

cls.ResourceDetailView.prototype = ViewBase;

<|endoftext|>


<commit_before>/*
 * (c) Ricardo Moreno <morenoricardo237@gmail.com>
 *
 * For more details about the license of this source code,
 * please view the license file LICENSE.
 */

/**
 * ajax - Standalone object for ajax request.
 *
 * @method query make a ajax request especific.
 *   @param {Object} config - object that represent the settings of the request.
 *      @property {String} url - the url of the request.
 *      @property {String} method - the method of the request.
 *      @property {Object} params - the parameters of the url.
 *      @property {String} fragment - the fragment of the url.
 * @method get shorthand for make a ajax request with the method GET.
 *   @param {String|Object} url - string or object that represent the url.
 *      @property {String} url - the url of the GET request.
 *      @property {Object} params - the parameters of the url.
 *      @property {String} fragment - the fragment of the url.
 *   @param {Boolean} json - indicate if the response will be parse as json.
 * @method post shorthand for make a ajax request with the method POST.
 *   @param {String|Object} url - string or object that represent the url.
 *      @property {String} url - the url of the request.
 *      @property {Object} params - the parameters of the url.
 *      @property {String} fragment - the fragment of the url.
 *   @param {String|Any} data - the data of the POST request.
 *   @param {Boolean} json - indicate if the request data will be parse as json.
 */
const ajax = {
  _createXHR: function () {
    try {
      return new window.XMLHttpRequest()
    } catch (err) {
      throw new Error('Error creating the XMLHttpRequest object')
    }
  },
  _parseQuery: function (url, params, fragment) {
    let uri = url

    if (params) {
      uri += '?'

      for (let key in params) {
        uri += `${key}=${params[key]}&`
      }

      uri = uri.replace(/&$/, '')
    }

    if (fragment) {
      uri += `#${fragment}`
    }

    return uri
  },
  query: function (config) {
    const xhr = this._createXHR()
    const { url, method, params, fragment } = config

    let query = this._parseQuery(url, params, fragment)

    xhr.open(method, query, true)
    xhr.send()

    return new Promise(function (resolve, reject) {
      xhr.onreadystatechange = function () {
        if (this.readyState === 4) {
          resolve(this.responseText)
        } else if (this.status === 403 || this.status === 404) {
          reject(`Status code ${this.status}`)
        }
      }
    })
  },
  get: function (url, json = false) {
    const xhr = this._createXHR()
    const method = 'GET'

    if (typeof url === 'object') {
      const { params, fragment } = url
      url = this._parseQuery(url.url, params, fragment)
    }

    xhr.open(method, url, true)
    xhr.send()

    return new Promise(function (resolve, reject) {
      xhr.onreadystatechange = function () {
        if (this.readyState === 4) {
          let responseText = this.responseText
          let response = json ? JSON.parse(responseText) : responseText

          resolve(response)
        } else if (this.status === 403 || this.status === 404) {
          reject(`Status code ${this.status}`)
        }
      }
    })
  },
  post: function (url, data, json = false) {
    const xhr = this._createXHR()
    const method = 'POST'

    let contentType = 'application/'

    if (typeof url === 'object') {
      const { params, fragment } = url
      url = this._parseQuery(url.url, params, fragment)
    }

    if (json) {
      data = JSON.stringify(data)
      contentType += 'json'
    } else {
      contentType += 'x-www-form-urlencoded'
    }

    xhr.open(method, url, true)
    xhr.setRequestHeader('Content-Type', contentType)
    xhr.send(data)

    return new Promise(function (resolve, reject) {
      xhr.onreadystatechange = function () {
        if (this.readyState === 4) {
          resolve(this.responseText)
        } else if (this.status === 403 || this.status === 404) {
          reject(`Status code ${this.status}`)
        }
      }
    })
  }
}

module.exports = ajax
<commit_msg>Simple change in src/ajax.js<commit_after>/*
 * (c) Ricardo Moreno <morenoricardo237@gmail.com>
 *
 * For more details about the license of this source code,
 * please view the license file LICENSE.
 */

/**
 * ajax - Standalone object for ajax request.
 *
 * @method query make a ajax request especific.
 *   @param {Object} config - object that represent the settings of the request.
 *      @property {String} url - the url of the request.
 *      @property {String} method - the method of the request.
 *      @property {Object} params - the parameters of the url.
 *      @property {String} fragment - the fragment of the url.
 * @method get shorthand for make a ajax request with the method GET.
 *   @param {String|Object} url - string or object that represent the url.
 *      @property {String} url - the url of the GET request.
 *      @property {Object} params - the parameters of the url.
 *      @property {String} fragment - the fragment of the url.
 *   @param {Boolean} json - indicate if the response will be parse as json.
 * @method post shorthand for make a ajax request with the method POST.
 *   @param {String|Object} url - string or object that represent the url.
 *      @property {String} url - the url of the request.
 *      @property {Object} params - the parameters of the url.
 *      @property {String} fragment - the fragment of the url.
 *   @param {String|Any} data - the data of the POST request.
 *   @param {Boolean} json - indicate if the request data will be parse as json.
 */
const ajax = {
  _createXHR () {
    try {
      return new window.XMLHttpRequest()
    } catch (err) {
      throw new Error('Error creating the XMLHttpRequest object')
    }
  },
  _parseQuery (url, params, fragment) {
    let uri = url

    if (params) {
      uri += '?'

      for (let key in params) {
        uri += `${key}=${params[key]}&`
      }

      uri = uri.replace(/&$/, '')
    }

    if (fragment) {
      uri += `#${fragment}`
    }

    return uri
  },
  query (config) {
    const xhr = this._createXHR()
    const { url, method, params, fragment } = config

    let query = this._parseQuery(url, params, fragment)

    xhr.open(method, query, true)
    xhr.send()

    return new Promise(function (resolve, reject) {
      xhr.onreadystatechange = function () {
        if (this.readyState === 4) {
          resolve(this.responseText)
        } else if (this.status === 403 || this.status === 404) {
          reject(`Status code ${this.status}`)
        }
      }
    })
  },
  get (url, json = false) {
    const xhr = this._createXHR()
    const method = 'GET'

    if (typeof url === 'object') {
      const { params, fragment } = url
      url = this._parseQuery(url.url, params, fragment)
    }

    xhr.open(method, url, true)
    xhr.send()

    return new Promise(function (resolve, reject) {
      xhr.onreadystatechange = function () {
        if (this.readyState === 4) {
          let responseText = this.responseText
          let response = json ? JSON.parse(responseText) : responseText

          resolve(response)
        } else if (this.status === 403 || this.status === 404) {
          reject(`Status code ${this.status}`)
        }
      }
    })
  },
  post (url, data, json = false) {
    const xhr = this._createXHR()
    const method = 'POST'

    let contentType = 'application/'

    if (typeof url === 'object') {
      const { params, fragment } = url
      url = this._parseQuery(url.url, params, fragment)
    }

    if (json) {
      data = JSON.stringify(data)
      contentType += 'json'
    } else {
      contentType += 'x-www-form-urlencoded'
    }

    xhr.open(method, url, true)
    xhr.setRequestHeader('Content-Type', contentType)
    xhr.send(data)

    return new Promise(function (resolve, reject) {
      xhr.onreadystatechange = function () {
        if (this.readyState === 4) {
          resolve(this.responseText)
        } else if (this.status === 403 || this.status === 404) {
          reject(`Status code ${this.status}`)
        }
      }
    })
  }
}

module.exports = ajax
<|endoftext|>


<commit_before>/*!
 * ${copyright}
 */

sap.ui.define(['jquery.sap.global', 'sap/ui/core/IconPool'],
	function(jQuery, IconPool) {
	"use strict";

// TODO: consider making this conditional
	IconPool.insertFontFaceStyle();

	/**
	 * PullToRefresh renderer.
	 * @namespace
	 */
	var PullToRefreshRenderer = {
	};

	/**
	 * Renders the HTML for the given control, using the provided {@link sap.ui.core.RenderManager}.
	 *
	 * @param {sap.ui.core.RenderManager} oRm the RenderManager that can be used for writing to the render output buffer
	 * @param {sap.ui.core.Control} oControl an object representation of the control that should be rendered
	 */
	PullToRefreshRenderer.render = function(oRm, oControl){
		var bShowIcon = oControl.getShowIcon();
		var sCustomIcon = oControl.getCustomIcon();
		var sTooltip = oControl.getTooltip_AsString();
		var oResourceBundle = oControl._getRB();

		oRm.write("<div");
		oRm.writeControlData(oControl);
		oRm.addClass("sapMPullDown");
		if (!oControl._bTouchMode) {
			oRm.addClass("sapMPullDownNontouch");
		} else {
			oRm.addClass("sapMPullDownTouch");
		}
		if (bShowIcon && !sCustomIcon) { // if no custom icon is provided, use SAP logo as background
			oRm.addClass("sapMPullDownLogo");
		}
		oRm.writeClasses();

		if (sTooltip) {
			oRm.writeAttributeEscaped("title", sTooltip);
		}

		oRm.write(" tabindex=\"0\""); // div element
		oRm.write(" role='button' aria-controls='" + oControl.getParent().sId + "-cont'>"); // aria attribute

		if (bShowIcon && sCustomIcon) {
			var oCustomImage = oControl.getCustomIconImage();
			if (oCustomImage) {
				oRm.write("
");
				oRm.renderControl(oCustomImage);
				oRm.write("
");
			}
		}

		// Pull down arrow icon
		oRm.write("");

		// Busy Indicator
		oRm.write("");
		oRm.renderControl(oControl._oBusyIndicator);
		oRm.write("");

		// Text - Pull down to refresh
		oRm.write("");
		oRm.writeEscaped(oResourceBundle.getText(oControl._bTouchMode ? "PULL2REFRESH_PULLDOWN" : "PULL2REFRESH_REFRESH"));
		oRm.write("");

		// Info - last updated at xx:xx:xx
		oRm.write("");
		oRm.writeEscaped(oControl.getDescription());
		oRm.write("");

		oRm.write("
");
	};

	return PullToRefreshRenderer;

}, /* bExport= */ true);
<commit_msg>[INTERNAL][FIX] m.PullToRefresh loading text is now read by jaws<commit_after>/*!
 * ${copyright}
 */

sap.ui.define(['jquery.sap.global', 'sap/ui/core/IconPool'],
	function(jQuery, IconPool) {
	"use strict";

// TODO: consider making this conditional
	IconPool.insertFontFaceStyle();

	/**
	 * PullToRefresh renderer.
	 * @namespace
	 */
	var PullToRefreshRenderer = {
	};

	/**
	 * Renders the HTML for the given control, using the provided {@link sap.ui.core.RenderManager}.
	 *
	 * @param {sap.ui.core.RenderManager} oRm the RenderManager that can be used for writing to the render output buffer
	 * @param {sap.ui.core.Control} oControl an object representation of the control that should be rendered
	 */
	PullToRefreshRenderer.render = function(oRm, oControl){
		var bShowIcon = oControl.getShowIcon();
		var sCustomIcon = oControl.getCustomIcon();
		var sTooltip = oControl.getTooltip_AsString();
		var oResourceBundle = oControl._getRB();

		oRm.write("<div");
		oRm.writeControlData(oControl);
		oRm.addClass("sapMPullDown");
		if (!oControl._bTouchMode) {
			oRm.addClass("sapMPullDownNontouch");
		} else {
			oRm.addClass("sapMPullDownTouch");
		}
		if (bShowIcon && !sCustomIcon) { // if no custom icon is provided, use SAP logo as background
			oRm.addClass("sapMPullDownLogo");
		}
		oRm.writeClasses();

		if (sTooltip) {
			oRm.writeAttributeEscaped("title", sTooltip);
		}

		oRm.write(" tabindex=\"0\""); // div element
		oRm.write(" role='button' aria-controls='" + oControl.getParent().sId + "-cont'>"); // aria attribute

		if (bShowIcon && sCustomIcon) {
			var oCustomImage = oControl.getCustomIconImage();
			if (oCustomImage) {
				oRm.write("
");
				oRm.renderControl(oCustomImage);
				oRm.write("
");
			}
		}

		// Pull down arrow icon
		oRm.write("");

		// Busy Indicator
		oRm.write("");
		oRm.renderControl(oControl._oBusyIndicator);
		oRm.write("");

		// Text - Pull down to refresh
		oRm.write("");
		oRm.writeEscaped(oResourceBundle.getText(oControl._bTouchMode ? "PULL2REFRESH_PULLDOWN" : "PULL2REFRESH_REFRESH"));
		oRm.write("");

		// Info - last updated at xx:xx:xx
		oRm.write("");
		oRm.writeEscaped(oControl.getDescription());
		oRm.write("");

		oRm.write("
");
	};

	return PullToRefreshRenderer;

}, /* bExport= */ true);
<|endoftext|>