<commit_before>(function() {
/**
 * Transforms an array of features to a single feature with the merged
 * geometry of geom_type
 */
OpenLayers.Util.properFeatures = function(features, geom_type) {
    if (features.constructor == Array) {
        var geoms = [];
        for (var i=0; i<features.length; i++) {
            geoms.push(features[i].geometry);
        }
        var geom = new geom_type(geoms);
        features = new OpenLayers.Feature.Vector(geom);
    }
    return features;
}

/**
 * @requires OpenLayers/Format/WKT.js
 */

/**
 * Class: OpenLayers.Format.DjangoWKT
 * Class for reading Well-Known Text, with workarounds to successfully parse
 * geometries and collections as returned by django.contrib.gis.geos.
 *
 * Inherits from:
 *  - <OpenLayers.Format.WKT>
 */

OpenLayers.Format.DjangoWKT = OpenLayers.Class(OpenLayers.Format.WKT, {
    initialize: function(options) {
        OpenLayers.Format.WKT.prototype.initialize.apply(this, [options]);
        this.regExes.justComma = /\s*,\s*/;
    },

    parse: {
        'point': function(str) {
            var coords = OpenLayers.String.trim(str).split(this.regExes.spaces);
            return new OpenLayers.Feature.Vector(
                new OpenLayers.Geometry.Point(coords[0], coords[1])
            );
        },

        'multipoint': function(str) {
            var point;
            var points = OpenLayers.String.trim(str).split(this.regExes.justComma);
            var components = [];
            for(var i=0, len=points.length; i<len; ++i) {
                point = points[i].replace(this.regExes.trimParens, '$1');
                components.push(this.parse.point.apply(this, [point]).geometry);
            }
            return new OpenLayers.Feature.Vector(
                new OpenLayers.Geometry.MultiPoint(components)
            );
        },

        'linestring': function(str) {
            var points = OpenLayers.String.trim(str).split(',');
            var components = [];
            for(var i=0, len=points.length; i<len; ++i) {
                components.push(this.parse.point.apply(this, [points[i]]).geometry);
            }
            return new OpenLayers.Feature.Vector(
                new OpenLayers.Geometry.LineString(components)
            );
        },

        'multilinestring': function(str) {
            var line;
            var lines = OpenLayers.String.trim(str).split(this.regExes.parenComma);
            var components = [];
            for(var i=0, len=lines.length; i<len; ++i) {
                line = lines[i].replace(this.regExes.trimParens, '$1');
                components.push(this.parse.linestring.apply(this, [line]).geometry);
            }
            return new OpenLayers.Feature.Vector(
                new OpenLayers.Geometry.MultiLineString(components)
            );
        },

        'polygon': function(str) {
            var ring, linestring, linearring;
            var rings = OpenLayers.String.trim(str).split(this.regExes.parenComma);
            var components = [];
            for(var i=0, len=rings.length; i<len; ++i) {
                ring = rings[i].replace(this.regExes.trimParens, '$1');
                linestring = this.parse.linestring.apply(this, [ring]).geometry;
                linearring = new OpenLayers.Geometry.LinearRing(linestring.components);
                components.push(linearring);
            }
            return new OpenLayers.Feature.Vector(
                new OpenLayers.Geometry.Polygon(components)
            );
        },

        'multipolygon': function(str) {
            var polygon;
            var polygons = OpenLayers.String.trim(str).split(this.regExes.doubleParenComma);
            var components = [];
            for(var i=0, len=polygons.length; i<len; ++i) {
                polygon = polygons[i].replace(this.regExes.trimParens, '$1');
                components.push(this.parse.polygon.apply(this, [polygon]).geometry);
            }
            return new OpenLayers.Feature.Vector(
                new OpenLayers.Geometry.MultiPolygon(components)
            );
        },

        'geometrycollection': function(str) {
            // separate components of the collection with |
            str = str.replace(/,\s*([A-Za-z])/g, '|$1');
            var wktArray = OpenLayers.String.trim(str).split('|');
            var components = [];
            for(var i=0, len=wktArray.length; i<len; ++i) {
                components.push(OpenLayers.Format.WKT.prototype.read.apply(this,[wktArray[i]]));
            }
            return components;
        }
    },

    extractGeometry: function(geometry) {
        var type = geometry.CLASS_NAME.split('.')[2].toLowerCase();
        if (!this.extract[type]) {
            return null;
        }
        if (this.internalProjection && this.externalProjection) {
            geometry = geometry.clone();
            geometry.transform(this.internalProjection, this.externalProjection);
        }
        var wktType = type == 'collection' ? 'GEOMETRYCOLLECTION' : type.toUpperCase();
        var data = wktType + '(' + this.extract[type].apply(this, [geometry]) + ')';
        return data;
    },

    /**
     * Patched write: successfully writes WKT for geometries and
     * geometrycollections.
     */
    write: function(features) {
        var collection, geometry, type, data, isCollection;
        isCollection = features.geometry.CLASS_NAME == "OpenLayers.Geometry.Collection";
        var pieces = [];
        if (isCollection) {
            collection = features.geometry.components;
            pieces.push('GEOMETRYCOLLECTION(');
            for (var i=0, len=collection.length; i<len; ++i) {
                if (i>0) {
                    pieces.push(',');
                }
                pieces.push(this.extractGeometry(collection[i]));
            }
            pieces.push(')');
        } else {
            pieces.push(this.extractGeometry(features.geometry));
        }
        return pieces.join('');
    },

    CLASS_NAME: "OpenLayers.Format.DjangoWKT"
});

function MapWidget(options) {
    this.map = null;
    this.controls = null;
    this.panel = null;
    this.layers = {};
    this.wkt_f = new OpenLayers.Format.DjangoWKT();

    // Mapping from OGRGeomType name to OpenLayers.Geometry name
    if (options['geom_name'] == 'Unknown') options['geom_type'] = OpenLayers.Geometry;
    else if (options['geom_name'] == 'GeometryCollection') options['geom_type'] = OpenLayers.Geometry.Collection;
    else options['geom_type'] = eval('OpenLayers.Geometry.' + options['geom_name']);

    // Default options
    this.options = {
        color: 'ee9900',
        default_lat: 0,
        default_lon: 0,
        default_zoom: 4,
        is_collection: new options['geom_type']() instanceof OpenLayers.Geometry.Collection,
        layerswitcher: false,
        map_options: {},
        map_srid: 4326,
        modifiable: true,
        mouse_position: false,
        opacity: 0.4,
        point_zoom: 12,
        scale_text: false,
        scrollable: true
    };

    // Altering using user-provided options
    for (var property in options) {
        if (options.hasOwnProperty(property)) {
            this.options[property] = options[property];
        }
    }

    this.map = this.create_map();

    var defaults_style = {
        'fillColor': '#' + this.options.color,
        'fillOpacity': this.options.opacity,
        'strokeColor': '#' + this.options.color,
    };
    if (this.options.geom_name == 'LineString') {
        defaults_style['strokeWidth'] = 3;
    }
    var styleMap = new OpenLayers.StyleMap({'default': OpenLayers.Util.applyDefaults(defaults_style, OpenLayers.Feature.Vector.style['default'])});
    this.layers.vector = new OpenLayers.Layer.Vector(" " + this.options.name, {styleMap: styleMap});
    this.map.addLayer(this.layers.vector);
    var wkt = document.getElementById(this.options.id).value;
    if (wkt) {
        var feat = OpenLayers.Util.properFeatures(this.read_wkt(wkt), this.options.geom_type);
        this.write_wkt(feat);
        if (this.options.is_collection) {
            for (var i=0; i<this.num_geom; i++) {
                this.layers.vector.addFeatures([new OpenLayers.Feature.Vector(feat.geometry.components[i].clone())]);
            }
        } else {
            this.layers.vector.addFeatures([feat]);
        }
        this.map.zoomToExtent(feat.geometry.getBounds());
        if (this.options.geom_name == 'Point') {
            this.map.zoomTo(this.options.point_zoom);
        }
    } else {
        this.map.setCenter(this.defaultCenter(), this.options.default_zoom);
    }
    this.layers.vector.events.on({'featuremodified': this.modify_wkt, scope: this});
    this.layers.vector.events.on({'featureadded': this.add_wkt, scope: this});

    this.getControls(this.layers.vector);
    this.panel.addControls(this.controls);
    this.map.addControl(this.panel);
    this.addSelectControl();

    if (this.options.mouse_position) {
        this.map.addControl(new OpenLayers.Control.MousePosition());
    }
    if (this.options.scale_text) {
        this.map.addControl(new OpenLayers.Control.Scale());
    }
    if (this.options.layerswitcher) {
        this.map.addControl(new OpenLayers.Control.LayerSwitcher());
    }
    if (!this.options.scrollable) {
        this.map.getControlsByClass('OpenLayers.Control.Navigation')[0].disableZoomWheel();
    }
    if (wkt) {
        if (this.options.modifiable) {
            this.enableEditing();
        }
    } else {
        this.enableDrawing();
    }
}

MapWidget.prototype.create_map = function() {
    var map = new OpenLayers.Map(this.options.map_id, this.options.map_options);
    if (this.options.base_layer) this.layers.base = this.options.base_layer;
    else this.layers.base = new OpenLayers.Layer.WMS('OpenLayers WMS', 'http://vmap0.tiles.osgeo.org/wms/vmap0', {layers: 'basic'});
    map.addLayer(this.layers.base);
    return map
};

MapWidget.prototype.get_ewkt = function(feat) {
    return "SRID=" + this.options.map_srid + ";" + this.wkt_f.write(feat);
};

MapWidget.prototype.read_wkt = function(wkt) {
    var prefix = 'SRID=' + this.options.map_srid + ';'
    if (wkt.indexOf(prefix) === 0) {
        wkt = wkt.slice(prefix.length);
    }
    return this.wkt_f.read(wkt);
};

MapWidget.prototype.write_wkt = function(feat) {
    feat = OpenLayers.Util.properFeatures(feat, this.options.geom_type);
    if (this.options.is_collection) {
        this.num_geom = feat.geometry.components.length;
    } else {
        this.num_geom = 1;
    }
    document.getElementById(this.options.id).value = this.get_ewkt(feat);
};

MapWidget.prototype.add_wkt = function(event) {
    if (this.options.is_collection) {
        var feat = new OpenLayers.Feature.Vector(new this.options.geom_type());
        for (var i=0; i<this.layers.vector.features.length; i++) {
            feat.geometry.addComponents([this.layers.vector.features[i].geometry]);
        }
        this.write_wkt(feat);
    } else {
        if (this.layers.vector.features.length > 1) {
            old_feats = [this.layers.vector.features[0]];
            this.layers.vector.removeFeatures(old_feats);
            this.layers.vector.destroyFeatures(old_feats);
        }
        this.write_wkt(event.feature);
    }
};

MapWidget.prototype.modify_wkt = function(event) {
    if (this.options.is_collection) {
        if (this.options.geom_name == 'MultiPoint') {
            this.add_wkt(event);
            return;
        } else {
            var feat = new OpenLayers.Feature.Vector(new this.options.geom_type());
            for (var i=0; i<this.num_geom; i++) {
                feat.geometry.addComponents([this.layers.vector.features[i].geometry]);
            }
            this.write_wkt(feat);
        }
    } else {
        this.write_wkt(event.feature);
    }
};

MapWidget.prototype.deleteFeatures = function() {
    this.layers.vector.removeFeatures(this.layers.vector.features);
    this.layers.vector.destroyFeatures();
};

MapWidget.prototype.clearFeatures = function() {
    this.deleteFeatures();
    document.getElementById(this.options.id).value = '';
    this.map.setCenter(this.defaultCenter(), this.options.default_zoom);
};

MapWidget.prototype.defaultCenter = function() {
    var center = new OpenLayers.LonLat(this.options.default_lon, this.options.default_lat);
    if (this.options.map_srid) {
        return center.transform(new OpenLayers.Projection("EPSG:4326"), this.map.getProjectionObject());
    }
    return center;
};

MapWidget.prototype.addSelectControl = function() {
    var select = new OpenLayers.Control.SelectFeature(this.layers.vector, {'toggle': true, 'clickout': true});
    this.map.addControl(select);
    select.activate();
};

MapWidget.prototype.enableDrawing = function () {
    this.map.getControlsByClass('OpenLayers.Control.DrawFeature')[0].activate();
};

MapWidget.prototype.enableEditing = function () {
    this.map.getControlsByClass('OpenLayers.Control.ModifyFeature')[0].activate();
};

MapWidget.prototype.getControls = function(layer) {
    this.panel = new OpenLayers.Control.Panel({'displayClass': 'olControlEditingToolbar'});
    this.controls = [new OpenLayers.Control.Navigation()];
    if (!this.options.modifiable && layer.features.length)
        return;
    if (this.options.geom_name.indexOf('LineString') >= 0 || this.options.geom_name == 'Unknown') {
        this.controls.push(new OpenLayers.Control.DrawFeature(layer, OpenLayers.Handler.Path, {'displayClass': 'olControlDrawFeaturePath'}));
    }
    if (this.options.geom_name.indexOf('Polygon') >= 0 || this.options.geom_name == 'Unknown') {
        this.controls.push(new OpenLayers.Control.DrawFeature(layer, OpenLayers.Handler.Polygon, {'displayClass': 'olControlDrawFeaturePolygon'}));
    }
    if (this.options.geom_name.indexOf('Point') >= 0 || this.options.geom_name == 'Unknown') {
        this.controls.push(new OpenLayers.Control.DrawFeature(layer, OpenLayers.Handler.Point, {'displayClass': 'olControlDrawFeaturePoint'}));
    }
    if (this.options.modifiable) {
        this.controls.push(new OpenLayers.Control.ModifyFeature(layer, {'displayClass': 'olControlModifyFeature'}));
    }
};
window.MapWidget = MapWidget;
})();
<commit_msg>Removed erroneous trailing comma in OLMapWidget.js.<commit_after>(function() {
/**
 * Transforms an array of features to a single feature with the merged
 * geometry of geom_type
 */
OpenLayers.Util.properFeatures = function(features, geom_type) {
    if (features.constructor == Array) {
        var geoms = [];
        for (var i=0; i<features.length; i++) {
            geoms.push(features[i].geometry);
        }
        var geom = new geom_type(geoms);
        features = new OpenLayers.Feature.Vector(geom);
    }
    return features;
}

/**
 * @requires OpenLayers/Format/WKT.js
 */

/**
 * Class: OpenLayers.Format.DjangoWKT
 * Class for reading Well-Known Text, with workarounds to successfully parse
 * geometries and collections as returned by django.contrib.gis.geos.
 *
 * Inherits from:
 *  - <OpenLayers.Format.WKT>
 */

OpenLayers.Format.DjangoWKT = OpenLayers.Class(OpenLayers.Format.WKT, {
    initialize: function(options) {
        OpenLayers.Format.WKT.prototype.initialize.apply(this, [options]);
        this.regExes.justComma = /\s*,\s*/;
    },

    parse: {
        'point': function(str) {
            var coords = OpenLayers.String.trim(str).split(this.regExes.spaces);
            return new OpenLayers.Feature.Vector(
                new OpenLayers.Geometry.Point(coords[0], coords[1])
            );
        },

        'multipoint': function(str) {
            var point;
            var points = OpenLayers.String.trim(str).split(this.regExes.justComma);
            var components = [];
            for(var i=0, len=points.length; i<len; ++i) {
                point = points[i].replace(this.regExes.trimParens, '$1');
                components.push(this.parse.point.apply(this, [point]).geometry);
            }
            return new OpenLayers.Feature.Vector(
                new OpenLayers.Geometry.MultiPoint(components)
            );
        },

        'linestring': function(str) {
            var points = OpenLayers.String.trim(str).split(',');
            var components = [];
            for(var i=0, len=points.length; i<len; ++i) {
                components.push(this.parse.point.apply(this, [points[i]]).geometry);
            }
            return new OpenLayers.Feature.Vector(
                new OpenLayers.Geometry.LineString(components)
            );
        },

        'multilinestring': function(str) {
            var line;
            var lines = OpenLayers.String.trim(str).split(this.regExes.parenComma);
            var components = [];
            for(var i=0, len=lines.length; i<len; ++i) {
                line = lines[i].replace(this.regExes.trimParens, '$1');
                components.push(this.parse.linestring.apply(this, [line]).geometry);
            }
            return new OpenLayers.Feature.Vector(
                new OpenLayers.Geometry.MultiLineString(components)
            );
        },

        'polygon': function(str) {
            var ring, linestring, linearring;
            var rings = OpenLayers.String.trim(str).split(this.regExes.parenComma);
            var components = [];
            for(var i=0, len=rings.length; i<len; ++i) {
                ring = rings[i].replace(this.regExes.trimParens, '$1');
                linestring = this.parse.linestring.apply(this, [ring]).geometry;
                linearring = new OpenLayers.Geometry.LinearRing(linestring.components);
                components.push(linearring);
            }
            return new OpenLayers.Feature.Vector(
                new OpenLayers.Geometry.Polygon(components)
            );
        },

        'multipolygon': function(str) {
            var polygon;
            var polygons = OpenLayers.String.trim(str).split(this.regExes.doubleParenComma);
            var components = [];
            for(var i=0, len=polygons.length; i<len; ++i) {
                polygon = polygons[i].replace(this.regExes.trimParens, '$1');
                components.push(this.parse.polygon.apply(this, [polygon]).geometry);
            }
            return new OpenLayers.Feature.Vector(
                new OpenLayers.Geometry.MultiPolygon(components)
            );
        },

        'geometrycollection': function(str) {
            // separate components of the collection with |
            str = str.replace(/,\s*([A-Za-z])/g, '|$1');
            var wktArray = OpenLayers.String.trim(str).split('|');
            var components = [];
            for(var i=0, len=wktArray.length; i<len; ++i) {
                components.push(OpenLayers.Format.WKT.prototype.read.apply(this,[wktArray[i]]));
            }
            return components;
        }
    },

    extractGeometry: function(geometry) {
        var type = geometry.CLASS_NAME.split('.')[2].toLowerCase();
        if (!this.extract[type]) {
            return null;
        }
        if (this.internalProjection && this.externalProjection) {
            geometry = geometry.clone();
            geometry.transform(this.internalProjection, this.externalProjection);
        }
        var wktType = type == 'collection' ? 'GEOMETRYCOLLECTION' : type.toUpperCase();
        var data = wktType + '(' + this.extract[type].apply(this, [geometry]) + ')';
        return data;
    },

    /**
     * Patched write: successfully writes WKT for geometries and
     * geometrycollections.
     */
    write: function(features) {
        var collection, geometry, type, data, isCollection;
        isCollection = features.geometry.CLASS_NAME == "OpenLayers.Geometry.Collection";
        var pieces = [];
        if (isCollection) {
            collection = features.geometry.components;
            pieces.push('GEOMETRYCOLLECTION(');
            for (var i=0, len=collection.length; i<len; ++i) {
                if (i>0) {
                    pieces.push(',');
                }
                pieces.push(this.extractGeometry(collection[i]));
            }
            pieces.push(')');
        } else {
            pieces.push(this.extractGeometry(features.geometry));
        }
        return pieces.join('');
    },

    CLASS_NAME: "OpenLayers.Format.DjangoWKT"
});

function MapWidget(options) {
    this.map = null;
    this.controls = null;
    this.panel = null;
    this.layers = {};
    this.wkt_f = new OpenLayers.Format.DjangoWKT();

    // Mapping from OGRGeomType name to OpenLayers.Geometry name
    if (options['geom_name'] == 'Unknown') options['geom_type'] = OpenLayers.Geometry;
    else if (options['geom_name'] == 'GeometryCollection') options['geom_type'] = OpenLayers.Geometry.Collection;
    else options['geom_type'] = eval('OpenLayers.Geometry.' + options['geom_name']);

    // Default options
    this.options = {
        color: 'ee9900',
        default_lat: 0,
        default_lon: 0,
        default_zoom: 4,
        is_collection: new options['geom_type']() instanceof OpenLayers.Geometry.Collection,
        layerswitcher: false,
        map_options: {},
        map_srid: 4326,
        modifiable: true,
        mouse_position: false,
        opacity: 0.4,
        point_zoom: 12,
        scale_text: false,
        scrollable: true
    };

    // Altering using user-provided options
    for (var property in options) {
        if (options.hasOwnProperty(property)) {
            this.options[property] = options[property];
        }
    }

    this.map = this.create_map();

    var defaults_style = {
        'fillColor': '#' + this.options.color,
        'fillOpacity': this.options.opacity,
        'strokeColor': '#' + this.options.color
    };
    if (this.options.geom_name == 'LineString') {
        defaults_style['strokeWidth'] = 3;
    }
    var styleMap = new OpenLayers.StyleMap({'default': OpenLayers.Util.applyDefaults(defaults_style, OpenLayers.Feature.Vector.style['default'])});
    this.layers.vector = new OpenLayers.Layer.Vector(" " + this.options.name, {styleMap: styleMap});
    this.map.addLayer(this.layers.vector);
    var wkt = document.getElementById(this.options.id).value;
    if (wkt) {
        var feat = OpenLayers.Util.properFeatures(this.read_wkt(wkt), this.options.geom_type);
        this.write_wkt(feat);
        if (this.options.is_collection) {
            for (var i=0; i<this.num_geom; i++) {
                this.layers.vector.addFeatures([new OpenLayers.Feature.Vector(feat.geometry.components[i].clone())]);
            }
        } else {
            this.layers.vector.addFeatures([feat]);
        }
        this.map.zoomToExtent(feat.geometry.getBounds());
        if (this.options.geom_name == 'Point') {
            this.map.zoomTo(this.options.point_zoom);
        }
    } else {
        this.map.setCenter(this.defaultCenter(), this.options.default_zoom);
    }
    this.layers.vector.events.on({'featuremodified': this.modify_wkt, scope: this});
    this.layers.vector.events.on({'featureadded': this.add_wkt, scope: this});

    this.getControls(this.layers.vector);
    this.panel.addControls(this.controls);
    this.map.addControl(this.panel);
    this.addSelectControl();

    if (this.options.mouse_position) {
        this.map.addControl(new OpenLayers.Control.MousePosition());
    }
    if (this.options.scale_text) {
        this.map.addControl(new OpenLayers.Control.Scale());
    }
    if (this.options.layerswitcher) {
        this.map.addControl(new OpenLayers.Control.LayerSwitcher());
    }
    if (!this.options.scrollable) {
        this.map.getControlsByClass('OpenLayers.Control.Navigation')[0].disableZoomWheel();
    }
    if (wkt) {
        if (this.options.modifiable) {
            this.enableEditing();
        }
    } else {
        this.enableDrawing();
    }
}

MapWidget.prototype.create_map = function() {
    var map = new OpenLayers.Map(this.options.map_id, this.options.map_options);
    if (this.options.base_layer) this.layers.base = this.options.base_layer;
    else this.layers.base = new OpenLayers.Layer.WMS('OpenLayers WMS', 'http://vmap0.tiles.osgeo.org/wms/vmap0', {layers: 'basic'});
    map.addLayer(this.layers.base);
    return map
};

MapWidget.prototype.get_ewkt = function(feat) {
    return "SRID=" + this.options.map_srid + ";" + this.wkt_f.write(feat);
};

MapWidget.prototype.read_wkt = function(wkt) {
    var prefix = 'SRID=' + this.options.map_srid + ';'
    if (wkt.indexOf(prefix) === 0) {
        wkt = wkt.slice(prefix.length);
    }
    return this.wkt_f.read(wkt);
};

MapWidget.prototype.write_wkt = function(feat) {
    feat = OpenLayers.Util.properFeatures(feat, this.options.geom_type);
    if (this.options.is_collection) {
        this.num_geom = feat.geometry.components.length;
    } else {
        this.num_geom = 1;
    }
    document.getElementById(this.options.id).value = this.get_ewkt(feat);
};

MapWidget.prototype.add_wkt = function(event) {
    if (this.options.is_collection) {
        var feat = new OpenLayers.Feature.Vector(new this.options.geom_type());
        for (var i=0; i<this.layers.vector.features.length; i++) {
            feat.geometry.addComponents([this.layers.vector.features[i].geometry]);
        }
        this.write_wkt(feat);
    } else {
        if (this.layers.vector.features.length > 1) {
            old_feats = [this.layers.vector.features[0]];
            this.layers.vector.removeFeatures(old_feats);
            this.layers.vector.destroyFeatures(old_feats);
        }
        this.write_wkt(event.feature);
    }
};

MapWidget.prototype.modify_wkt = function(event) {
    if (this.options.is_collection) {
        if (this.options.geom_name == 'MultiPoint') {
            this.add_wkt(event);
            return;
        } else {
            var feat = new OpenLayers.Feature.Vector(new this.options.geom_type());
            for (var i=0; i<this.num_geom; i++) {
                feat.geometry.addComponents([this.layers.vector.features[i].geometry]);
            }
            this.write_wkt(feat);
        }
    } else {
        this.write_wkt(event.feature);
    }
};

MapWidget.prototype.deleteFeatures = function() {
    this.layers.vector.removeFeatures(this.layers.vector.features);
    this.layers.vector.destroyFeatures();
};

MapWidget.prototype.clearFeatures = function() {
    this.deleteFeatures();
    document.getElementById(this.options.id).value = '';
    this.map.setCenter(this.defaultCenter(), this.options.default_zoom);
};

MapWidget.prototype.defaultCenter = function() {
    var center = new OpenLayers.LonLat(this.options.default_lon, this.options.default_lat);
    if (this.options.map_srid) {
        return center.transform(new OpenLayers.Projection("EPSG:4326"), this.map.getProjectionObject());
    }
    return center;
};

MapWidget.prototype.addSelectControl = function() {
    var select = new OpenLayers.Control.SelectFeature(this.layers.vector, {'toggle': true, 'clickout': true});
    this.map.addControl(select);
    select.activate();
};

MapWidget.prototype.enableDrawing = function () {
    this.map.getControlsByClass('OpenLayers.Control.DrawFeature')[0].activate();
};

MapWidget.prototype.enableEditing = function () {
    this.map.getControlsByClass('OpenLayers.Control.ModifyFeature')[0].activate();
};

MapWidget.prototype.getControls = function(layer) {
    this.panel = new OpenLayers.Control.Panel({'displayClass': 'olControlEditingToolbar'});
    this.controls = [new OpenLayers.Control.Navigation()];
    if (!this.options.modifiable && layer.features.length)
        return;
    if (this.options.geom_name.indexOf('LineString') >= 0 || this.options.geom_name == 'Unknown') {
        this.controls.push(new OpenLayers.Control.DrawFeature(layer, OpenLayers.Handler.Path, {'displayClass': 'olControlDrawFeaturePath'}));
    }
    if (this.options.geom_name.indexOf('Polygon') >= 0 || this.options.geom_name == 'Unknown') {
        this.controls.push(new OpenLayers.Control.DrawFeature(layer, OpenLayers.Handler.Polygon, {'displayClass': 'olControlDrawFeaturePolygon'}));
    }
    if (this.options.geom_name.indexOf('Point') >= 0 || this.options.geom_name == 'Unknown') {
        this.controls.push(new OpenLayers.Control.DrawFeature(layer, OpenLayers.Handler.Point, {'displayClass': 'olControlDrawFeaturePoint'}));
    }
    if (this.options.modifiable) {
        this.controls.push(new OpenLayers.Control.ModifyFeature(layer, {'displayClass': 'olControlModifyFeature'}));
    }
};
window.MapWidget = MapWidget;
})();
<|endoftext|>


<commit_before>/**
 * @fileoverview
 * Helper function prototypes related to DOM objects and the DOM
 * fixme: Christian should document the template syntax
 * templating system.
 *
 */

Element.prototype.___add=Document.prototype.___add=function()
{
  if(arguments.length)
  {
    if(arguments[0])
    {
      var doc=this.nodeType==9?this:this.ownerDocument;
      var i=0, ele=(typeof arguments[0])=='string'?doc.createElement(arguments[i++]):this;
      var prop='', is_array=false, arg=arguments[i];
      while((is_array=arg instanceof  Array) ||
       (((typeof arg=='string') || (typeof arg=='number')) && (((arguments.length-i)%2)|| arguments[i+1] instanceof  Array ))
      )
      {
        if(is_array)
        {
          ele.___add.apply(ele, arg);
        }
        else if(arg)
        {
          ele.appendChild(doc.createTextNode(arg));
        }
        arg=arguments[++i];
      }
      for( ;arguments[i] ; i+=2)
      {
        if(/string/.test(typeof arguments[i+1]))
        {
          ele.setAttribute(arguments[i], arguments[i+1]);
        }
        else
        {
          ele[arguments[i]]=arguments[i+1];
        }
      }
      if(this.nodeType==1 && (this!=ele))
      {
        this.appendChild(ele);
      }
      return ele;
    }
    else
    {
      return this.appendChild(doc.createTextNode(arguments[1]));
    }
  }
  return null;
}

Element.prototype.___add_inner = Document.prototype.___add_inner = function()
{
  if(arguments.length)
  {
    if(arguments[0])
    {
      var i=1;
      var prop='', is_array=false, arg=arguments[i];
      var head = "<" + arguments[0];
      var content = '';
      var attrs = ' ';
      while((is_array=arg instanceof  Array) ||
       (((typeof arg=='string') || (typeof arg=='number')) && (((arguments.length-i)%2)|| arguments[i+1] instanceof  Array ))
      )
      {
        if(is_array)
        {
          content += Element.prototype.___add_inner.apply(null, arg);
        }
        else if(arg)
        {
          content += arg.replace(/</g, "<").replace(/>/g, ">");
        }
        arg=arguments[++i];
      }
      for( ;arguments[i] ; i+=2)
      {
        attrs += arguments[i] + "=\u0022" + arguments[i+1] + "\u0022";
      }
      head += attrs + ">" + content + "</" + arguments[0] +">";
      if(this && this.nodeType == 1 )
      {
        this.innerHTML += head;
      }
      return head;
    }
  }
  return '';
}

/**
 * Render template into the body of the element, keeping the existing condent
 */
Element.prototype.render=Document.prototype.render=function(template)
{
  return this.___add.apply(this, template);
}

Element.prototype.renderInner = Document.prototype.renderInner = function(template)
{
  return this.___add_inner.apply(this, template);
}

/**
 * Clear the element and render the template into it
 */
Element.prototype.clearAndRender=function(template)
{
  this.innerHTML='';
  return this.___add.apply(this, template);
}

/**
 * Add the css class "name" to the element's list of classes
 * fixme: Does not work with dashes in the name!
 */
Element.prototype.addClass=function(name)
{
  if(!(new RegExp('\\b'+name+'\\b')).test(this.className))
  {
    this.className=(this.className?this.className+' ':'')+name;
  }
  return this;
}

/**
 * Remove the css class "name" from the elements list of classes
 */
Element.prototype.removeClass=function(name)
{
  var re=new RegExp(name+' ?| ?'+name);
  if(re.test(this.className))
  {
    this.className=this.className.replace(re, '');
  }
  return this;
}

/**
 * Check if the element has the class "name" set
 */
Element.prototype.hasClass=function(name)
{
  return (new RegExp('(?:^| +)'+name+'(?: +|$)')).test(this.className)
}

/**
 * Swap class "from" with class "to"
 */
Element.prototype.swapClass=function(from, to)
{
  if (this.hasClass(from))
  {
    this.removeClass(from);
    this.addClass(to);
  }
}

/**
 * Returns the next sibling of the element that is an element. Ignores
 * nodes that are not elements
 */
Element.prototype.getNextSiblingElement = function()
{
  var next = this.nextSibling;
  while( next && next.nodeType != 1 )
  {
    next = next.nextSibling;
  }
  return next;
}

Element.prototype.getTop = function()
{
  var c = this, o_p = null, top = c.offsetTop;
  while( o_p = c.offsetParent )
  {
    top += o_p.offsetTop;
    c = o_p;
  }
  return top;
}

/**
 * Insert node after target in the tree.
 */
Element.prototype.insertAfter = function(node, target)
{
  var nextElement = target.nextSibling;
  while( nextElement && nextElement.nodeType != 1 )
  {
    nextElement = nextElement.nextSibling;
  }
  if( nextElement )
  {
    this.insertBefore(node, nextElement);
  }
  else
  {
    this.appendChild(node);
  }
}

/**
 * Returns an array of all children on the element that are also elements
 */
Element.prototype.getChildElements = function()
{
  var children = this.childNodes, ret = [], c = null, i=0;
  for( ; c = children[i]; i++)
  {
    if(c.nodeType == 1)
    {
      ret[ret.length] = c;
    }
  }
  return ret;
}

/**
 * Dispatches an event on the element with the name "name" and and properties
 * that are set in the "custom_props" object
 */
Element.prototype.releaseEvent =  function(name, custom_props)
{
  var event=document.createEvent('Events'), prop = '';
  event.initEvent(name, true, true);
  if( custom_props )
  {
    for( prop in custom_props )
    {
      event[prop] = custom_props[prop];
    }
  }
  this.dispatchEvent(event);
}

/* currently broken in Opera */
Element.prototype.getWidth=function(e)
{
  var style = window.getComputedStyle(this, null);
  return this.offsetWidth
    - parseInt(style['paddingLeft'])
    - parseInt(style['paddingRight'])
    - parseInt(style['borderLeftWidth'])
    - parseInt(style['borderRightWidth']);
}

Element.prototype.spliceInnerHTML = function(str)
{
  this.insertAdjacentHTML('afterEnd', str);
  /*
  var
  temp = this.ownerDocument.createElement('div-parser'),
  range = this.ownerDocument.createRange();
  temp.innerHTML = str;
  if(this.nextSibling)
  {
    range.selectNodeContents(this.parentNode.insertBefore(temp, this.nextSibling));
  }
  else
  {
    range.selectNodeContents(this.parentNode.appendChild(temp));
  }
  this.parentNode.replaceChild(range.extractContents(), temp);
  */
}

/**
 * Get the first contained element with name nodeName
 */
Element.prototype.getFirst = function(nodeName)
{
  return this.getElementsByTagName(nodeName)[0];
}

/**
 * Get the last contained element with name nodeName
 */
Element.prototype.getLast = function(nodeName)
{
  var all = this.getElementsByTagName(nodeName);
  return all[all.length - 1];
}

/**
 * Get the previous element of the same name as "current" that is a
 * child of the element. Return null if there is no such element.
 */
Element.prototype.getPreviousSameNamed = function(current)
{
  var
  nodeName = current && current.nodeName,
  all = this.getElementsByTagName(nodeName),
  cur = null,
  i = 0;

  for( ; ( cur = all[i] ) && cur != current; i++);
  return cur && all[i-1] || null;

}

/**
 * Same as getPreviousSameNamed but finds the next element
 */
Element.prototype.getNextSameNamed = function(current)
{
  var
  nodeName = current && current.nodeName,
  all = this.getElementsByTagName(nodeName),
  cur = null,
  i = 0;

  for( ; ( cur = all[i] ) && cur != current; i++);
  return cur && all[i+1] || null;
}

/**
 * Get the next element of the same name as "target" that is a
 * sibling of the element. Return null if there is no such element.
 */
Element.prototype.getNextSameNamedSibling = function(target)
{
  var
  next = this.nextSibling,
  name = this.nodeName;

  while( next && next.nodeName != name )
  {
    next = next.nextSibling;
  }

  return next;
}

/**
 * Same as getNextSameNamedSibling but finds previous sibling
 */
Element.prototype.getPreviousSameNamedSibling = function(target)
{
  var
  previous = this.previousSibling,
  name = this.nodeName;

  while( previous && previous.nodeName != name )
  {
    previous = previous.previousSibling;
  }

  return previous;
}

/**
 * Returns the next element for which the function "filter" returns true.
 * The filter functions is passed two arguments, the current candidate element
 * and the element on which the method was called
 */
Element.prototype.getNextWithFilter = function(root_context, filter)
{
  var cursor = this;
  while(( cursor = cursor.getNextInFlow(root_context) ) && !filter(cursor, this) );
  return cursor;
}

/**
 * Same as getNextWithFilter but finds previous element
 */
Element.prototype.getPreviousWithFilter = function(root_context, filter)
{
  var cursor = this;
  while( ( cursor = cursor.getPreviousInFlow(root_context) ) && !filter(cursor, this) );
  return cursor;
}

Element.prototype.getNextInFlow = function(root_context)
{
  var
  next = this.firstElementChild || this.nextElementSibling,
  cursor = this;

  while(!next && ( cursor = cursor.parentNode ) && cursor != root_context  )
  {
    next = cursor.nextElementSibling;
  }
  return next;
}

Element.prototype.getPreviousInFlow = function(root_context)
{
  var
  previous = this.previousElementSibling,
  parent = this.parentNode,
  cursor = previous;

  while( cursor && cursor.lastElementChild && ( cursor = cursor.lastElementChild ) );
  return cursor || previous || parent != root_context && parent || null;
}

Element.prototype.scrollSoftIntoView = function()
{
  // just checking the first offsetParent to keep it simple
  var scrollContainer = this.offsetParent;
  var min_top = 20;
  if( scrollContainer && scrollContainer.offsetHeight < scrollContainer.scrollHeight )
  {
    if( this.offsetTop < scrollContainer.scrollTop + min_top )
    {
      scrollContainer.scrollTop = this.offsetTop - min_top;
    }
    else if( this.offsetTop + this.offsetHeight > scrollContainer.scrollTop + scrollContainer.offsetHeight - min_top )
    {
      scrollContainer.scrollTop =
        this.offsetTop + this.offsetHeight - scrollContainer.offsetHeight + min_top;
    }
  }
}

/**
 * Get the text content of the first node in Node with the name nodeName
 * Escapes opening angle brackets into less than entities. If node is not
 * found, returns null
 * @argument nodeName {string} node name
 * @returns {Element}
 */
Node.prototype.getNodeData=function(nodeName)
{
  var node=this.getElementsByTagName(nodeName)[0];
  if(node)
  {
    return node.textContent.replace(/</g, '<');
  }
  return null;
}

/**
 * Get the value of an attribute called attr from the first child node called
 * nodeName. If node is not found, returns null
 * @argument nodeName {string} node name
 * @argument attr {string} attribute name
 * @returns {string}
 */
Node.prototype.getAttributeFromNode=function(nodeName, attr)
{
  var node=this.getElementsByTagName(nodeName)[0];
  if(node)
  {
    return node.getAttribute(attr);
  }
  return null;
};

/**
 * Returns the index of item in the nodelist
 * (The same behaviour as js1.6 array.indexOf)
 * @argument item {Element}
 */
NodeList.prototype.indexOf = function(item)
{
  for( var cursor = null, i = 0; cursor = this[i]; i++)
  {
    if( cursor == item )
    {
      return i;
    }
  }
  return -1;
}

StyleSheetList.prototype.getPropertyValue = function(selector, property)
{
  var sheet = null, i = 0, j = 0, rules = null, rule = null;
  for( ; sheet = this[i]; i++ )
  {
    rules = sheet.cssRules;
    // does not take into account import rules
    for( j = 0; ( rule = rules[j] ) && !( rule.type == 1 && rule.selectorText == selector ); j++);
    if( rule )
    {
      return rule.style.getPropertyValue(property);
    }
  }
  return '';
};

/**
 * Make sure there is a getElementsByClassName method if there is no native
 * implementation of it
 * @deprecated All verison of opera in which the dragonfly client runs should have this by now
 */
(function(){
  if( !document.getElementsByClassName )
  {
    Document.prototype.getElementsByClassName=Element.prototype.getElementsByClassName=function()
    {
      var eles = this.getElementsByTagName("*"),
        ele = null, ret =[], c_n = '', cursor = null, i = 0, j = 0;
      for( ; c_n = arguments[i]; i++)
      {
        arguments[i] = new RegExp('(?:^| +)' + c_n + '(?: +|$)');
      }
      for (i=0; ele=eles[i]; i++)
      {
        c_n = ele.className;
        for ( j=0; ( cursor = arguments[j] ) && cursor.test(c_n); j++);
        if( !cursor )
        {
          ret[ret.length] = ele;
        }
      }
      return ret;
    }
  }
})();

<commit_msg>Added elem.scrollSoftIntoContainerView method<commit_after>/**
 * @fileoverview
 * Helper function prototypes related to DOM objects and the DOM
 * fixme: Christian should document the template syntax
 * templating system.
 *
 */

Element.prototype.___add=Document.prototype.___add=function()
{
  if(arguments.length)
  {
    if(arguments[0])
    {
      var doc=this.nodeType==9?this:this.ownerDocument;
      var i=0, ele=(typeof arguments[0])=='string'?doc.createElement(arguments[i++]):this;
      var prop='', is_array=false, arg=arguments[i];
      while((is_array=arg instanceof  Array) ||
       (((typeof arg=='string') || (typeof arg=='number')) && (((arguments.length-i)%2)|| arguments[i+1] instanceof  Array ))
      )
      {
        if(is_array)
        {
          ele.___add.apply(ele, arg);
        }
        else if(arg)
        {
          ele.appendChild(doc.createTextNode(arg));
        }
        arg=arguments[++i];
      }
      for( ;arguments[i] ; i+=2)
      {
        if(/string/.test(typeof arguments[i+1]))
        {
          ele.setAttribute(arguments[i], arguments[i+1]);
        }
        else
        {
          ele[arguments[i]]=arguments[i+1];
        }
      }
      if(this.nodeType==1 && (this!=ele))
      {
        this.appendChild(ele);
      }
      return ele;
    }
    else
    {
      return this.appendChild(doc.createTextNode(arguments[1]));
    }
  }
  return null;
}

Element.prototype.___add_inner = Document.prototype.___add_inner = function()
{
  if(arguments.length)
  {
    if(arguments[0])
    {
      var i=1;
      var prop='', is_array=false, arg=arguments[i];
      var head = "<" + arguments[0];
      var content = '';
      var attrs = ' ';
      while((is_array=arg instanceof  Array) ||
       (((typeof arg=='string') || (typeof arg=='number')) && (((arguments.length-i)%2)|| arguments[i+1] instanceof  Array ))
      )
      {
        if(is_array)
        {
          content += Element.prototype.___add_inner.apply(null, arg);
        }
        else if(arg)
        {
          content += arg.replace(/</g, "<").replace(/>/g, ">");
        }
        arg=arguments[++i];
      }
      for( ;arguments[i] ; i+=2)
      {
        attrs += arguments[i] + "=\u0022" + arguments[i+1] + "\u0022";
      }
      head += attrs + ">" + content + "</" + arguments[0] +">";
      if(this && this.nodeType == 1 )
      {
        this.innerHTML += head;
      }
      return head;
    }
  }
  return '';
}

/**
 * Render template into the body of the element, keeping the existing condent
 */
Element.prototype.render=Document.prototype.render=function(template)
{
  return this.___add.apply(this, template);
}

Element.prototype.renderInner = Document.prototype.renderInner = function(template)
{
  return this.___add_inner.apply(this, template);
}

/**
 * Clear the element and render the template into it
 */
Element.prototype.clearAndRender=function(template)
{
  this.innerHTML='';
  return this.___add.apply(this, template);
}

/**
 * Add the css class "name" to the element's list of classes
 * fixme: Does not work with dashes in the name!
 */
Element.prototype.addClass=function(name)
{
  if(!(new RegExp('\\b'+name+'\\b')).test(this.className))
  {
    this.className=(this.className?this.className+' ':'')+name;
  }
  return this;
}

/**
 * Remove the css class "name" from the elements list of classes
 */
Element.prototype.removeClass=function(name)
{
  var re=new RegExp(name+' ?| ?'+name);
  if(re.test(this.className))
  {
    this.className=this.className.replace(re, '');
  }
  return this;
}

/**
 * Check if the element has the class "name" set
 */
Element.prototype.hasClass=function(name)
{
  return (new RegExp('(?:^| +)'+name+'(?: +|$)')).test(this.className)
}

/**
 * Swap class "from" with class "to"
 */
Element.prototype.swapClass=function(from, to)
{
  if (this.hasClass(from))
  {
    this.removeClass(from);
    this.addClass(to);
  }
}

/**
 * Returns the next sibling of the element that is an element. Ignores
 * nodes that are not elements
 */
Element.prototype.getNextSiblingElement = function()
{
  var next = this.nextSibling;
  while( next && next.nodeType != 1 )
  {
    next = next.nextSibling;
  }
  return next;
}

Element.prototype.getTop = function()
{
  var c = this, o_p = null, top = c.offsetTop;
  while( o_p = c.offsetParent )
  {
    top += o_p.offsetTop;
    c = o_p;
  }
  return top;
}

/**
 * Insert node after target in the tree.
 */
Element.prototype.insertAfter = function(node, target)
{
  var nextElement = target.nextSibling;
  while( nextElement && nextElement.nodeType != 1 )
  {
    nextElement = nextElement.nextSibling;
  }
  if( nextElement )
  {
    this.insertBefore(node, nextElement);
  }
  else
  {
    this.appendChild(node);
  }
}

/**
 * Returns an array of all children on the element that are also elements
 */
Element.prototype.getChildElements = function()
{
  var children = this.childNodes, ret = [], c = null, i=0;
  for( ; c = children[i]; i++)
  {
    if(c.nodeType == 1)
    {
      ret[ret.length] = c;
    }
  }
  return ret;
}

/**
 * Dispatches an event on the element with the name "name" and and properties
 * that are set in the "custom_props" object
 */
Element.prototype.releaseEvent =  function(name, custom_props)
{
  var event=document.createEvent('Events'), prop = '';
  event.initEvent(name, true, true);
  if( custom_props )
  {
    for( prop in custom_props )
    {
      event[prop] = custom_props[prop];
    }
  }
  this.dispatchEvent(event);
}

/* currently broken in Opera */
Element.prototype.getWidth=function(e)
{
  var style = window.getComputedStyle(this, null);
  return this.offsetWidth
    - parseInt(style['paddingLeft'])
    - parseInt(style['paddingRight'])
    - parseInt(style['borderLeftWidth'])
    - parseInt(style['borderRightWidth']);
}

Element.prototype.spliceInnerHTML = function(str)
{
  this.insertAdjacentHTML('afterEnd', str);
  /*
  var
  temp = this.ownerDocument.createElement('div-parser'),
  range = this.ownerDocument.createRange();
  temp.innerHTML = str;
  if(this.nextSibling)
  {
    range.selectNodeContents(this.parentNode.insertBefore(temp, this.nextSibling));
  }
  else
  {
    range.selectNodeContents(this.parentNode.appendChild(temp));
  }
  this.parentNode.replaceChild(range.extractContents(), temp);
  */
}

/**
 * Get the first contained element with name nodeName
 */
Element.prototype.getFirst = function(nodeName)
{
  return this.getElementsByTagName(nodeName)[0];
}

/**
 * Get the last contained element with name nodeName
 */
Element.prototype.getLast = function(nodeName)
{
  var all = this.getElementsByTagName(nodeName);
  return all[all.length - 1];
}

/**
 * Get the previous element of the same name as "current" that is a
 * child of the element. Return null if there is no such element.
 */
Element.prototype.getPreviousSameNamed = function(current)
{
  var
  nodeName = current && current.nodeName,
  all = this.getElementsByTagName(nodeName),
  cur = null,
  i = 0;

  for( ; ( cur = all[i] ) && cur != current; i++);
  return cur && all[i-1] || null;

}

/**
 * Same as getPreviousSameNamed but finds the next element
 */
Element.prototype.getNextSameNamed = function(current)
{
  var
  nodeName = current && current.nodeName,
  all = this.getElementsByTagName(nodeName),
  cur = null,
  i = 0;

  for( ; ( cur = all[i] ) && cur != current; i++);
  return cur && all[i+1] || null;
}

/**
 * Get the next element of the same name as "target" that is a
 * sibling of the element. Return null if there is no such element.
 */
Element.prototype.getNextSameNamedSibling = function(target)
{
  var
  next = this.nextSibling,
  name = this.nodeName;

  while( next && next.nodeName != name )
  {
    next = next.nextSibling;
  }

  return next;
}

/**
 * Same as getNextSameNamedSibling but finds previous sibling
 */
Element.prototype.getPreviousSameNamedSibling = function(target)
{
  var
  previous = this.previousSibling,
  name = this.nodeName;

  while( previous && previous.nodeName != name )
  {
    previous = previous.previousSibling;
  }

  return previous;
}

/**
 * Returns the next element for which the function "filter" returns true.
 * The filter functions is passed two arguments, the current candidate element
 * and the element on which the method was called
 */
Element.prototype.getNextWithFilter = function(root_context, filter)
{
  var cursor = this;
  while(( cursor = cursor.getNextInFlow(root_context) ) && !filter(cursor, this) );
  return cursor;
}

/**
 * Same as getNextWithFilter but finds previous element
 */
Element.prototype.getPreviousWithFilter = function(root_context, filter)
{
  var cursor = this;
  while( ( cursor = cursor.getPreviousInFlow(root_context) ) && !filter(cursor, this) );
  return cursor;
}

Element.prototype.getNextInFlow = function(root_context)
{
  var
  next = this.firstElementChild || this.nextElementSibling,
  cursor = this;

  while(!next && ( cursor = cursor.parentNode ) && cursor != root_context  )
  {
    next = cursor.nextElementSibling;
  }
  return next;
}

Element.prototype.getPreviousInFlow = function(root_context)
{
  var
  previous = this.previousElementSibling,
  parent = this.parentNode,
  cursor = previous;

  while( cursor && cursor.lastElementChild && ( cursor = cursor.lastElementChild ) );
  return cursor || previous || parent != root_context && parent || null;
}

/**
 * Make sure the element is visible in its scoll context.
 * @see Element.prototype.scrollSoftIntoContainerView
 */
Element.prototype.scrollSoftIntoView = function()
{
  // just checking the first offsetParent to keep it simple
  var scrollContainer = this.offsetParent;
  var min_top = 20;
  if( scrollContainer && scrollContainer.offsetHeight < scrollContainer.scrollHeight )
  {
    if( this.offsetTop < scrollContainer.scrollTop + min_top )
    {
      scrollContainer.scrollTop = this.offsetTop - min_top;
    }
    else if( this.offsetTop + this.offsetHeight > scrollContainer.scrollTop + scrollContainer.offsetHeight - min_top )
    {
      scrollContainer.scrollTop =
        this.offsetTop + this.offsetHeight - scrollContainer.offsetHeight + min_top;
    }
  }
}

/**
 * Make sure the element is visible in the container. The container is the
 * first <container> element found in the offsetParent chain, or body if no
 * container element is found.
 */
Element.prototype.scrollSoftIntoContainerView = function()
{
  var scrollContainer = this.offsetParent;
  while (scrollContainer && scrollContainer != document.body && scrollContainer.nodeName != "container")
  {
    scrollContainer = scrollContainer.offsetParent;
  }

  var min_top = 20;
  if( scrollContainer && scrollContainer.offsetHeight < scrollContainer.scrollHeight )
  {
    if( this.offsetTop < scrollContainer.scrollTop + min_top )
    {
      scrollContainer.scrollTop = this.offsetTop - min_top;
    }
    else if( this.offsetTop + this.offsetHeight > scrollContainer.scrollTop + scrollContainer.offsetHeight - min_top )
    {
      scrollContainer.scrollTop =
        this.offsetTop + this.offsetHeight - scrollContainer.offsetHeight + min_top;
    }
  }
}

/**
 * Get the text content of the first node in Node with the name nodeName
 * Escapes opening angle brackets into less than entities. If node is not
 * found, returns null
 * @argument nodeName {string} node name
 * @returns {Element}
 */
Node.prototype.getNodeData=function(nodeName)
{
  var node=this.getElementsByTagName(nodeName)[0];
  if(node)
  {
    return node.textContent.replace(/</g, '<');
  }
  return null;
}

/**
 * Get the value of an attribute called attr from the first child node called
 * nodeName. If node is not found, returns null
 * @argument nodeName {string} node name
 * @argument attr {string} attribute name
 * @returns {string}
 */
Node.prototype.getAttributeFromNode=function(nodeName, attr)
{
  var node=this.getElementsByTagName(nodeName)[0];
  if(node)
  {
    return node.getAttribute(attr);
  }
  return null;
};

/**
 * Returns the index of item in the nodelist
 * (The same behaviour as js1.6 array.indexOf)
 * @argument item {Element}
 */
NodeList.prototype.indexOf = function(item)
{
  for( var cursor = null, i = 0; cursor = this[i]; i++)
  {
    if( cursor == item )
    {
      return i;
    }
  }
  return -1;
}

StyleSheetList.prototype.getPropertyValue = function(selector, property)
{
  var sheet = null, i = 0, j = 0, rules = null, rule = null;
  for( ; sheet = this[i]; i++ )
  {
    rules = sheet.cssRules;
    // does not take into account import rules
    for( j = 0; ( rule = rules[j] ) && !( rule.type == 1 && rule.selectorText == selector ); j++);
    if( rule )
    {
      return rule.style.getPropertyValue(property);
    }
  }
  return '';
};

/**
 * Make sure there is a getElementsByClassName method if there is no native
 * implementation of it
 * @deprecated All verison of opera in which the dragonfly client runs should have this by now
 */
(function(){
  if( !document.getElementsByClassName )
  {
    Document.prototype.getElementsByClassName=Element.prototype.getElementsByClassName=function()
    {
      var eles = this.getElementsByTagName("*"),
        ele = null, ret =[], c_n = '', cursor = null, i = 0, j = 0;
      for( ; c_n = arguments[i]; i++)
      {
        arguments[i] = new RegExp('(?:^| +)' + c_n + '(?: +|$)');
      }
      for (i=0; ele=eles[i]; i++)
      {
        c_n = ele.className;
        for ( j=0; ( cursor = arguments[j] ) && cursor.test(c_n); j++);
        if( !cursor )
        {
          ret[ret.length] = ele;
        }
      }
      return ret;
    }
  }
})();

<|endoftext|>


<commit_before>var AV = require('leanengine');
var http = require('https');
var cheerio = require('cheerio');

AV.Cloud.define('hello', function(req, res){
    console.log(req);
    res.success('Hello world in cloud function');
});

AV.Cloud.define('doubanMusic', function(req, res) {
    http.get("https://music.douban.com/chart", function(response) {
        var html = "";
        response.on('data', function(data) {
            html += data;
        });

        response.on('end', function() {
            callback(html);
        });
    });
} );

var DoubanMusic = AV.Object.extend("DoubanMusic");

function callback(html) {
    var $ = cheerio.load(html);
    var result = [];

    $("ul.col5 li.clearfix").each(function(index, element) {
        var url = $(element).find("a.face").attr("href");
        result.push('url');
        var doubanMusic = new DoubanMusic();
        doubanMusic.save({
            "icon": url
        }).then(function(object) {
            console.log("success");
        });

    })
}

AV.Cloud.beforeSave('Review', function(request, response) {
    response.error(JSON.stringify({
        code: 123,
        message: '自定义错误信息'
    }));
});

module.exports = AV.Cloud;
<commit_msg>新增妹子图抓取代码<commit_after>var AV = require('leanengine');
var http = require('http');
var cheerio = require('cheerio');

AV.Cloud.define('hello', function(req, res){
    console.log(req);
    res.success('Hello world in cloud function');
});

var baseUrl = "http://www.meizitu.com/a/";
AV.Cloud.define("meiziSpider", function(request, response) {
    var query = new AV.Query("meiziIndex");
    query.equalTo("name", "meizitucom");
    query.first().then(function(obj) {
       var sInd = obj.get("lastIndex");
        var index = parseInt(sInd);
        index += 1;
        requestMeizitu(index);

    }, function(error) {
        requestMeizitu(1);
    });
});

function requestMeizitu(index) {
    var mUrl = baseUrl + index + ".html";
    http.get(mUrl, function(res) {

        var html = "";
        response.on('data', function(data) {
            html += data;
        });

        response.on('end', function() {
            parsehtml(index, html);
            var query = new AV.Query("meiziIndex");
            query.equalTo("name", "meizitucom");
            query.first().then(function(obj) {
                var index = parseInt(obj.get("lastIndex"));
                index += 1;
                obj.set("lastIndex", inde);
                obj.save();
                index += 1;
                requestMeizitu(index);

            }, function(error) {
                var obj = new MeiziIndex();
                obj.set("name", "meizitucom");
                obj.set("lastIndex", 1);
                obj.save();
                requestMeizitu(2);
            });
        });
    });
}

function parsehtml(oid, htmlContent) {
    var $ = cheerio.load(htmlContent);
    var mzObj = new Meizitu();
    var titleName = $("div.metaRight h2 a").text();
    mzObj.set("title", titleName);
    var tags = $("div.metaRight p").text();
    tags = tags.replace("Tags:", "");
    var tagArray = tags.split(" , ");
    mzObj.set("tags", tagArray);
    var imageLinks = [];
    mzObj.set("mzId", oid);
    $("div.postConttent p img").each(function(index, element) {
        var imgUrl = $(element).attr("src");
        imageLinks.push(imgUrl);
    });
    mzObj.set("imgs", imageLinks);
    var otherText = $("div.postContent p").text();
    mzObj.set("text", otherText);
    mzObj.save();
}

var DoubanMusic = AV.Object.extend("DoubanMusic");
var Meizitu = AV.Object.extend("meizitu");
var MeiziIndex = AV.Object.extend("meiziIndex");

module.exports = AV.Cloud;
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2017 NAVER Corp.
 * billboard.js project is licensed under the MIT license
 */
/* eslint-disable */
/* global describe, beforeEach, it, expect */
import util from "./assets/util";
import CLASS from "../src/config/classes";
import {isString} from "../src/internals/util";

describe("COLOR", () => {
	let chart;
	let args;

	beforeEach(() => {
		chart = util.generate(args);
	});

	describe("tiles", () => {
		before(() => {
			args = {
				data: {
					columns: [
						["data1", 30, 200, -100, 400, -150, 250],
						["data2", 50, 20, 10, 40, 15, 25]
					],
					type: "bar"
				},
				color: {
					tiles: function() {
						function circlePattern(fillColor, opacity, radiusMin, radiusMax) {
							const pattern = d3.select(document.createElementNS(d3.namespaces.svg, "pattern"))
								.attr("patternUnits", "userSpaceOnUse")
								.attr("width", "32")
								.attr("height", "32");

							const g = pattern
								.append("g")
								.style("fill", fillColor || "#000")
								.style("opactiy", opacity || "0.2");

							g
								.append("circle")
								.attr("cx", "3")
								.attr("cy", "3")
								.attr("r", radiusMin || "3");

							g
								.append("circle")
								.attr("cx", "13")
								.attr("cy", "13")
								.attr("r", radiusMax || "9");

							return pattern.node();
						}

						return [
							circlePattern("#FFF", "0.2", "3", "10"),
							circlePattern("yellow", "0.3", "3", "3")
						];
					}
				}
			};
		});

		it("should create patterns property", () => {
			expect(chart.internal.patterns).to.be.an('array');
		});

		it("patterns should be an array with id and pattern objects", () => {
			const patterns = chart.internal.patterns;
			const numPatterns = patterns.length;

			const valid = patterns.map(p => {
				return isString(p.id) && p.node.nodeName.toLowerCase() === 'pattern';
			});

			expect(valid.length).to.be.equal(numPatterns);
		});

		it("check for legend color tiles", () => {
			const colors = [chart.color("data1"), chart.color("data2")];

			d3.selectAll(`.${CLASS.legendItem} .${CLASS.legendItemTile}`)
				.each(function(v, i) {
					const stroke = d3.select(this).style("stroke").replace(/\"/g, "");

					expect(stroke).to.be.equal(colors[i]);
			});
		});

		it("check for tooltip color tiles", () => {
			const colors = [chart.color("data1"), chart.color("data2")];
			const eventRect = chart.internal.main
				.select(`.${CLASS.eventRect}-1`)
				.node();

			util.fireEvent(eventRect, "mousemove", {
				clientX: 100,
				clientY: 100
			}, chart);

			d3.select(chart.element)
				.selectAll(`.${CLASS.tooltip} td rect`)
				.each(function(v, i) {
					const fill = d3.select(this).style("fill").replace(/\"/g, "");

					expect(fill).to.be.equal(colors[i]);
				});
		});

		describe("pattern names", () => {
			before(() => {
				args.color.pattern = ['red', 'gold', 'green'];
			});

			it("should create correct pattern names", () => {
				const internal = chart.internal;
				const datetimeId = internal.datetimeId;
				const expectedIds = [
					`${datetimeId}-pattern-red`,
					`${datetimeId}-pattern-gold`,
					`${datetimeId}-pattern-green`
				];

				internal.patterns.forEach((p, idx) => {
					const id = `${expectedIds[idx]}-${idx}`;

					expect(p.id).to.be.equal(id);
					expect(p.node.id).to.be.equal(id);
				});
			});
		});

		describe("pattern shouldn't be applying for line types", () => {
			const checkStroke = (path=[false, false]) => {
				const internal = chart.internal;
				const rx = /#bb-\d+-pattern-/;

				chart.data().forEach(v => {
					const id = v.id;
					const isLine = internal.isTypeOf(id, ["line", "spline", "step"]) || !internal.config.data_types[id];
					const stroke = internal.main.select(`.bb-shapes-${id} path`).style("stroke");

					expect(rx.test(stroke)).to.be[!isLine];
				})
			};

			it("set options data.type=undefined", () => {
				args.data.type = undefined;
			});

			it("check for stroke", checkStroke);

			it("set options data.type=line", () => {
				args.data.type = "line";
			});

			it("check for stroke", checkStroke);

			it("set options data.type=spline", () => {
				args.data.type = "spline";
			});

			it("check for stroke", checkStroke);

			it("set options data.type=step", () => {
				args.data.type = "step";
			});

			it("check for stroke", checkStroke);

			it("set options data.type", () => {
				args.data.type = undefined;
				args.data.types = {
					data1: "bar",
					data2: "line"
				};
			});

			it("check for stroke", checkStroke);
		});
	});
});
<commit_msg>skip: remove unnecessary param code<commit_after>/**
 * Copyright (c) 2017 NAVER Corp.
 * billboard.js project is licensed under the MIT license
 */
/* eslint-disable */
/* global describe, beforeEach, it, expect */
import util from "./assets/util";
import CLASS from "../src/config/classes";
import {isString} from "../src/internals/util";

describe("COLOR", () => {
	let chart;
	let args;

	beforeEach(() => {
		chart = util.generate(args);
	});

	describe("tiles", () => {
		before(() => {
			args = {
				data: {
					columns: [
						["data1", 30, 200, -100, 400, -150, 250],
						["data2", 50, 20, 10, 40, 15, 25]
					],
					type: "bar"
				},
				color: {
					tiles: function() {
						function circlePattern(fillColor, opacity, radiusMin, radiusMax) {
							const pattern = d3.select(document.createElementNS(d3.namespaces.svg, "pattern"))
								.attr("patternUnits", "userSpaceOnUse")
								.attr("width", "32")
								.attr("height", "32");

							const g = pattern
								.append("g")
								.style("fill", fillColor || "#000")
								.style("opactiy", opacity || "0.2");

							g
								.append("circle")
								.attr("cx", "3")
								.attr("cy", "3")
								.attr("r", radiusMin || "3");

							g
								.append("circle")
								.attr("cx", "13")
								.attr("cy", "13")
								.attr("r", radiusMax || "9");

							return pattern.node();
						}

						return [
							circlePattern("#FFF", "0.2", "3", "10"),
							circlePattern("yellow", "0.3", "3", "3")
						];
					}
				}
			};
		});

		it("should create patterns property", () => {
			expect(chart.internal.patterns).to.be.an('array');
		});

		it("patterns should be an array with id and pattern objects", () => {
			const patterns = chart.internal.patterns;
			const numPatterns = patterns.length;

			const valid = patterns.map(p => {
				return isString(p.id) && p.node.nodeName.toLowerCase() === 'pattern';
			});

			expect(valid.length).to.be.equal(numPatterns);
		});

		it("check for legend color tiles", () => {
			const colors = [chart.color("data1"), chart.color("data2")];

			d3.selectAll(`.${CLASS.legendItem} .${CLASS.legendItemTile}`)
				.each(function(v, i) {
					const stroke = d3.select(this).style("stroke").replace(/\"/g, "");

					expect(stroke).to.be.equal(colors[i]);
			});
		});

		it("check for tooltip color tiles", () => {
			const colors = [chart.color("data1"), chart.color("data2")];
			const eventRect = chart.internal.main
				.select(`.${CLASS.eventRect}-1`)
				.node();

			util.fireEvent(eventRect, "mousemove", {
				clientX: 100,
				clientY: 100
			}, chart);

			d3.select(chart.element)
				.selectAll(`.${CLASS.tooltip} td rect`)
				.each(function(v, i) {
					const fill = d3.select(this).style("fill").replace(/\"/g, "");

					expect(fill).to.be.equal(colors[i]);
				});
		});

		describe("pattern names", () => {
			before(() => {
				args.color.pattern = ['red', 'gold', 'green'];
			});

			it("should create correct pattern names", () => {
				const internal = chart.internal;
				const datetimeId = internal.datetimeId;
				const expectedIds = [
					`${datetimeId}-pattern-red`,
					`${datetimeId}-pattern-gold`,
					`${datetimeId}-pattern-green`
				];

				internal.patterns.forEach((p, idx) => {
					const id = `${expectedIds[idx]}-${idx}`;

					expect(p.id).to.be.equal(id);
					expect(p.node.id).to.be.equal(id);
				});
			});
		});

		describe("pattern shouldn't be applying for line types", () => {
			const checkStroke = () => {
				const internal = chart.internal;
				const rx = /#bb-\d+-pattern-/;

				chart.data().forEach(v => {
					const id = v.id;
					const isLine = internal.isTypeOf(id, ["line", "spline", "step"]) || !internal.config.data_types[id];
					const stroke = internal.main.select(`.${CLASS.shapes}-${id} path`).style("stroke");

					expect(rx.test(stroke)).to.be[!isLine];
				})
			};

			it("set options data.type=undefined", () => {
				args.data.type = undefined;
			});

			it("check for stroke", checkStroke);

			it("set options data.type=line", () => {
				args.data.type = "line";
			});

			it("check for stroke", checkStroke);

			it("set options data.type=spline", () => {
				args.data.type = "spline";
			});

			it("check for stroke", checkStroke);

			it("set options data.type=step", () => {
				args.data.type = "step";
			});

			it("check for stroke", checkStroke);

			it("set options data.type", () => {
				args.data.type = undefined;
				args.data.types = {
					data1: "bar",
					data2: "line"
				};
			});

			it("check for stroke", checkStroke);
		});
	});
});
<|endoftext|>


<commit_before>function editRelated (collectionId, data, templateData, field, idField) {
  var list = templateData[field];
  var dataTemplate = createRelatedTemplate(idField, list);
  var html = templates.editorRelated(dataTemplate);
  $('#'+ idField).replaceWith(html);
  initialiseRelated(collectionId, data, templateData, field, idField);
}

function refreshRelated(collectionId, data, templateData, field, idField) {
  var list = templateData[field];
  var dataTemplate = createRelatedTemplate(idField, list);
  var html = templates.editorRelated(dataTemplate);
  $('#sortable-'+ idField).replaceWith($(html).find('#sortable-'+ idField));
  initialiseRelated(collectionId, data, templateData, field, idField);
}

function createRelatedTemplate(idField, list) {
  var dataTemplate;
  if (idField === 'article') {
    dataTemplate = {list: list, idField: idField, idPlural: 'articles'};
  } else if (idField === 'bulletin') {
    dataTemplate = {list: list, idField: idField, idPlural: 'bulletins'};
  } else if (idField === 'dataset') {
    dataTemplate = {list: list, idField: idField, idPlural: 'datasets'};
  } else if (idField === 'document') {
    dataTemplate = {list: list, idField: idField, idPlural: 'documents'};
  } else if (idField === 'methodology') {
    dataTemplate = {list: list, idField: idField, idPlural: 'methodologies'};
  } else {
    dataTemplate = {list: list, idField: idField};
  }
  return dataTemplate;
}

function initialiseRelated(collectionId, data, templateData, field, idField) {
  // Load
  if (!data[field] || data[field].length === 0) {
    editRelated['lastIndex' + field] = 0;
  } else {
    $(data[field]).each(function (index, value) {
      editRelated['lastIndex' + field] = index + 1;

      // Delete
      $('#' + idField + '-delete_' + index).click(function () {
        var result = confirm("Are you sure you want to delete this link?");
        if (result === true) {
          var position = $(".workspace-edit").scrollTop();
          Florence.globalVars.pagePos = position;
          $(this).parent().remove();
          data[field].splice(index, 1);
          templateData[field].splice(index, 1);
          postContent(collectionId, data.uri, JSON.stringify(data),
            success = function (response) {
              Florence.Editor.isDirty = false;
              refreshPreview(data.uri);
              refreshRelated(collectionId, data, templateData, field, idField)
            },
            error = function (response) {
              if (response.status === 400) {
                alert("Cannot edit this file. It is already part of another collection.");
              }
              else if (response.status === 401) {
                alert("You are not authorised to update content.");
              }
              else {
                handleApiError(response);
              }
            }
          );
        }
      });
    });
  }

  //Add
  $('#add-' + idField).off().one('click', function () {
    var latestCheck = true;
    var position = $(".workspace-edit").scrollTop();
    Florence.globalVars.pagePos = position;
    var iframeEvent = document.getElementById('iframe').contentWindow;
    iframeEvent.removeEventListener('click', Florence.Handler, true);
    createWorkspace(data.uri, collectionId, '', true);

    $('#sortable-' + idField).append(
      '
' +
      '  <textarea id="' + idField + '-uri_' + editRelated['lastIndex' + field] + '" placeholder="Go to the related data and click Get"></textarea>' +
      '

' +
      '  <button class="btn-page-get" id="' + idField + '-get_' + editRelated['lastIndex' + field] + '">Get</button>' +
      '  <button class="btn-page-cancel" id="' + idField + '-cancel_' + editRelated['lastIndex' + field] + '">Cancel</button>' +
      '
').trigger('create');

    if (idField === 'article' || idField === 'bulletin' || idField === 'document') {
      $('#latest-container').append('Link to latest' +
        '<input id="latest" type="checkbox" value="value" checked/>');
    }

    $('#' + idField + '-cancel_' + editRelated['lastIndex' + field]).one('click', function () {
      createWorkspace(data.uri, collectionId, 'edit');
    });

    $('#latest-container input:checkbox').change(function () {
      latestCheck = $(this).prop('checked');
    });

    $('#' + idField  + '-get_' + editRelated['lastIndex' + field]).one('click', function () {
      var baseUrl = $('#' + idField + '-uri_'+editRelated['lastIndex' + field]).val();
      if (!baseUrl) {
        baseUrl = getPathNameTrimLast();
      } else {
        baseUrl = checkPathParsed(baseUrl);
      }
      var dataUrlData = baseUrl + "/data";
      var latestUrl;
      if (latestCheck) {
        var tempUrl = baseUrl.split('/');
        tempUrl.pop();
        tempUrl.push('latest');
        latestUrl = tempUrl.join('/');
      } else {
        latestUrl = baseUrl;
      }

      $.ajax({
        url: dataUrlData,
        dataType: 'json',
        crossDomain: true,
        success: function (result) {
          if ((field === 'relatedBulletins' || field === 'statsBulletins') && result.type === 'bulletin') {
            if (!data[field]) {
              data[field] = [];
            }
          }

          else if (field === 'relatedArticles' && result.type === 'article') {
            if (!data[field]) {
              data[field] = [];
            }
          }

          else if ((field === 'relatedDocuments') && (result.type === 'article' || result.type === 'bulletin' || result.type === 'compendium_landing_page')) {
            if (!data[field]) {
              data[field] = [];
            }
          }

          else if ((field === 'relatedDatasets' || field === 'datasets') && (result.type === 'dataset' || result.type === 'reference_tables')) {
            if (!data[field]) {
              data[field] = [];
            }
          }

          else if ((field === 'items') && (result.type === 'timeseries')) {
            if (!data[field]) {
              data[field] = [];
            }
          }

          else if ((field === 'relatedData') && (result.type === 'timeseries' || result.type === 'dataset' || result.type === 'reference_tables')) {
            if (!data[field]) {
              data[field] = [];
            }
          }

          else if (field === 'relatedMethodology' && result.type === 'static_methodology') {
            if (!data[field]) {
              data[field] = [];
            }
          }

          else {
            alert("This is not a valid document");
            return;
          }

          data[field].push({uri: latestUrl});
          saveRelated(collectionId, data.uri, data, field, idField);

        },
        error: function () {
          console.log('No page data returned');
        }
      });
    });
  });

  function sortable() {
    $('#sortable-' + idField).sortable();
  }
  sortable();
}
<commit_msg>Change latest check to work with articles and bulletins<commit_after>function editRelated (collectionId, data, templateData, field, idField) {
  var list = templateData[field];
  var dataTemplate = createRelatedTemplate(idField, list);
  var html = templates.editorRelated(dataTemplate);
  $('#'+ idField).replaceWith(html);
  initialiseRelated(collectionId, data, templateData, field, idField);
}

function refreshRelated(collectionId, data, templateData, field, idField) {
  var list = templateData[field];
  var dataTemplate = createRelatedTemplate(idField, list);
  var html = templates.editorRelated(dataTemplate);
  $('#sortable-'+ idField).replaceWith($(html).find('#sortable-'+ idField));
  initialiseRelated(collectionId, data, templateData, field, idField);
}

function createRelatedTemplate(idField, list) {
  var dataTemplate;
  if (idField === 'article') {
    dataTemplate = {list: list, idField: idField, idPlural: 'articles'};
  } else if (idField === 'bulletin') {
    dataTemplate = {list: list, idField: idField, idPlural: 'bulletins'};
  } else if (idField === 'dataset') {
    dataTemplate = {list: list, idField: idField, idPlural: 'datasets'};
  } else if (idField === 'document') {
    dataTemplate = {list: list, idField: idField, idPlural: 'documents'};
  } else if (idField === 'methodology') {
    dataTemplate = {list: list, idField: idField, idPlural: 'methodologies'};
  } else {
    dataTemplate = {list: list, idField: idField};
  }
  return dataTemplate;
}

function initialiseRelated(collectionId, data, templateData, field, idField) {
  // Load
  if (!data[field] || data[field].length === 0) {
    editRelated['lastIndex' + field] = 0;
  } else {
    $(data[field]).each(function (index, value) {
      editRelated['lastIndex' + field] = index + 1;

      // Delete
      $('#' + idField + '-delete_' + index).click(function () {
        var result = confirm("Are you sure you want to delete this link?");
        if (result === true) {
          var position = $(".workspace-edit").scrollTop();
          Florence.globalVars.pagePos = position;
          $(this).parent().remove();
          data[field].splice(index, 1);
          templateData[field].splice(index, 1);
          postContent(collectionId, data.uri, JSON.stringify(data),
            success = function (response) {
              Florence.Editor.isDirty = false;
              refreshPreview(data.uri);
              refreshRelated(collectionId, data, templateData, field, idField)
            },
            error = function (response) {
              if (response.status === 400) {
                alert("Cannot edit this file. It is already part of another collection.");
              }
              else if (response.status === 401) {
                alert("You are not authorised to update content.");
              }
              else {
                handleApiError(response);
              }
            }
          );
        }
      });
    });
  }

  //Add
  $('#add-' + idField).off().one('click', function () {
    var latestCheck;
    var position = $(".workspace-edit").scrollTop();
    Florence.globalVars.pagePos = position;
    var iframeEvent = document.getElementById('iframe').contentWindow;
    iframeEvent.removeEventListener('click', Florence.Handler, true);
    createWorkspace(data.uri, collectionId, '', true);

    $('#sortable-' + idField).append(
      '
' +
      '  <textarea id="' + idField + '-uri_' + editRelated['lastIndex' + field] + '" placeholder="Go to the related data and click Get"></textarea>' +
      '

' +
      '  <button class="btn-page-get" id="' + idField + '-get_' + editRelated['lastIndex' + field] + '">Get</button>' +
      '  <button class="btn-page-cancel" id="' + idField + '-cancel_' + editRelated['lastIndex' + field] + '">Cancel</button>' +
      '
').trigger('create');

    if (idField === 'article' || idField === 'bulletin' || idField === 'document') {
      $('#latest-container').append('Link to latest' +
        '<input id="latest" type="checkbox" value="value" checked/>');
      latestCheck = true;
    }

    $('#' + idField + '-cancel_' + editRelated['lastIndex' + field]).one('click', function () {
      createWorkspace(data.uri, collectionId, 'edit');
    });

    $('#latest-container input:checkbox').change(function () {
      latestCheck = $(this).prop('checked');
    });

    $('#' + idField  + '-get_' + editRelated['lastIndex' + field]).one('click', function () {
      var baseUrl = $('#' + idField + '-uri_'+editRelated['lastIndex' + field]).val();
      if (!baseUrl) {
        baseUrl = getPathNameTrimLast();
      } else {
        baseUrl = checkPathParsed(baseUrl);
      }
      var dataUrlData = baseUrl + "/data";
      var latestUrl;
      if (latestCheck) {
        var tempUrl = baseUrl.split('/');
        tempUrl.pop();
        tempUrl.push('latest');
        latestUrl = tempUrl.join('/');
      } else {
        latestUrl = baseUrl;
      }

      $.ajax({
        url: dataUrlData,
        dataType: 'json',
        crossDomain: true,
        success: function (result) {
          if ((field === 'relatedBulletins' || field === 'statsBulletins') && result.type === 'bulletin') {
            if (!data[field]) {
              data[field] = [];
            }
          }

          else if (field === 'relatedArticles' && result.type === 'article') {
            if (!data[field]) {
              data[field] = [];
            }
          }

          else if ((field === 'relatedDocuments') && (result.type === 'article' || result.type === 'bulletin' || result.type === 'compendium_landing_page')) {
            if (!data[field]) {
              data[field] = [];
            }
          }

          else if ((field === 'relatedDatasets' || field === 'datasets') && (result.type === 'dataset' || result.type === 'reference_tables')) {
            if (!data[field]) {
              data[field] = [];
            }
          }

          else if ((field === 'items') && (result.type === 'timeseries')) {
            if (!data[field]) {
              data[field] = [];
            }
          }

          else if ((field === 'relatedData') && (result.type === 'timeseries' || result.type === 'dataset' || result.type === 'reference_tables')) {
            if (!data[field]) {
              data[field] = [];
            }
          }

          else if (field === 'relatedMethodology' && result.type === 'static_methodology') {
            if (!data[field]) {
              data[field] = [];
            }
          }

          else {
            alert("This is not a valid document");
            return;
          }

          data[field].push({uri: latestUrl});
          saveRelated(collectionId, data.uri, data, field, idField);

        },
        error: function () {
          console.log('No page data returned');
        }
      });
    });
  });

  function sortable() {
    $('#sortable-' + idField).sortable();
  }
  sortable();
}
<|endoftext|>


<commit_before>'use strict';

/**
 * Imports.
 */
const express = require('express');
const winston = require('winston');

/**
 * Constants declarations.
 */
const LISTEN_PORT = process.env.LISTEN_PORT || 5050;
const LOGGING_LEVEL = process.env.LOGGING_LEVEL || 'info';

/**
 * Dependencies initializations.
 */
const app = express();

// Logger:
app.locals.logger = new winston.Logger({
  transports: [
    new winston.transports.Console({ prettyPrint: true, colorize: true, level: LOGGING_LEVEL }),
  ],
  exceptionHandlers: [
    new winston.transports.Console({ prettyPrint: true, colorize: true }),
  ],
});
// Just a shortcut.
const logger = app.locals.logger;

app.get('/', (req, res) => {
  res.send('Hello World!');
});

app.listen(LISTEN_PORT, () => {
  logger.info(`Blink is listening on port:${LISTEN_PORT} env:${app.get('env')}`);
});

module.exports = app;
<commit_msg>Prepend logs with date timestamp<commit_after>'use strict';

/**
 * Imports.
 */
const express = require('express');
const winston = require('winston');

/**
 * Constants declarations.
 */
const LISTEN_PORT = process.env.LISTEN_PORT || 5050;
const LOGGER_LEVEL = process.env.LOGGER_LEVEL || 'info';
const LOGGER_TIMESTAMP = !(process.env.LOGGER_TIMESTAMP === 'false');

/**
 * Dependencies initializations.
 */
const app = express();

// Logger:
app.locals.logger = new winston.Logger({
  transports: [
    new winston.transports.Console({
      prettyPrint: true,
      colorize: true,
      level: LOGGER_LEVEL,
      timestamp: LOGGER_TIMESTAMP,
    }),
  ],
  exceptionHandlers: [
    new winston.transports.Console({ prettyPrint: true, colorize: true }),
  ],
});
// Just a shortcut.
const logger = app.locals.logger;

app.get('/', (req, res) => {
  res.send('Hello World!');
});

app.listen(LISTEN_PORT, () => {
  logger.info(`Blink is listening on port:${LISTEN_PORT} env:${app.get('env')}`);
});

module.exports = app;
<|endoftext|>