<commit_before>// ==UserScript==
// @id             iitc-plugin-add-remove-marker@hayeswise
// @name           IITC plugin: Add and Remove Marker
// @category       Layer
// @version        1.0.0.0
// @namespace      https://github.com/jonatkins/ingress-intel-total-conversion
// @description    Adds an Add Marker and Remove Marker control to the toolbox.
// @updateURL      https://github.com/hayeswise/iitc-addremovemarker/raw/master/wise-addRemoveMarker.user.js
// @downloadURL	   https://github.com/hayeswise/iitc-addremovemarker/raw/master/wise-addRemoveMarker.user.js
// @include        https://*.ingress.com/intel*
// @include        http://*.ingress.com/intel*
// @match          https://*.ingress.com/intel*
// @match          http://*.ingress.com/intel*
// @author         Hayeswise
// @grant          none
// ==/UserScript==
// MIT License, Copyright (c) 2016 Brian Hayes ("Hayeswise")
// For more information, visit https://github.com/hayeswise/iitc-addremovemarker.

function wrapper() {
    // In case IITC is not available yet, define the base plugin object
    if (typeof window.plugin !== "function") {
        window.plugin = function () {};
    }
    // Base context for plugin
    window.plugin.addRemoveMarker = function () {};
    var self = window.plugin.addRemoveMarker;

    // Plugin level properties
    self.portalDataInPortalDetails = null;
    self.autoMarkEnabled = false;
    self.autoRemoveMarkEnabled = false;
    self.poiColor = "#AAAAAA";
    // Portals of interest conditions (OR conditions)
    self.minHubLinks = 6;
    self.minPortalLevel = 7.5;
    self.minAXAs = 1;
    //
    // Add marker
    //
    self.addMarker = function () {
        var fname = "plugin.addRemoveMarker.addMarker";
        var count = 0,
            data = [], // For layer data
            item,
            portalDetails,
            title;
        if (!self.portalDataInPortalDetails) {
            alert("Select a portal to load the portal details before attempting to add a marker.");
            return;
        }
        title = (self.portalDataInPortalDetails && self.portalDataInPortalDetails.portalDetails.title) ? self.portalDataInPortalDetails.portalDetails.title : "[NO PORTAL DATA]";
        console.log(fname + ": guid:=" + self.portalDataInPortalDetails.guid + ", title:=" + title + ", have portal details=" + !!self.portalDataInPortalDetails);
        portalDetails = self.portalDataInPortalDetails.portalDetails;
        item = {
            type: 'marker',
            latLng: {
                lat: portalDetails.latE6 / 1E6,
                lng: portalDetails.lngE6 / 1E6
            },
        };
        window.plugin.drawTools.import([item]); // requires an array of items
        window.plugin.drawTools.save();
    };
    //
    // Save the portal details.
    //
    // @param data Object containing the guid, portal object, portalData object, and a portalDetails object.
    //
    self.checkPortalDetailsUpdated = function (data) {
        var fname = "plugin.addRemoveMarker.checkPortalDetailsUpdated";
        var title;
        self.portalDataInPortalDetails = data;
        title = data.portalData.title ? data.portalData.title : "[NO PORTAL DATA FOR portalDetailsUpdated RUNHOOK]";
        console.log(fname + "(data.guid:=" + data.guid + ", data.portalData.title:=" + title + ")");
        console.log(fname + ": Done.");
    };
    //
    // Remove the marker on the portal shown in the sidebar portal details.
    //
    self.removeMarker = function () {
        var fname = "plugin.addRemoveMarker.removeMarker";
        var count = 0,
            data = [], // For layer data
            portalDetails,
            refreshLayers = false,
            title;
        // 1. Get the marker data. In this case, the addRemoveMarker.checkPortalDetailLoaded() hook
        //    will have saved it when it was loaded into the sidebar portal details area.
        if (!self.portalDataInPortalDetails) {
            alert("Select a portal to load the portal details before attempting to remove a marker.");
            return;
        }
        title = (self.portalDataInPortalDetails && self.portalDataInPortalDetails.portalDetails.title) ? self.portalDataInPortalDetails.portalDetails.title : "[NO PORTAL DATA]";
        console.log(fname + ": guid:=" + self.portalDataInPortalDetails.guid + ", title:=" + title + ", have portal details=" + !!self.portalDataInPortalDetails);
        portalDetails = self.portalDataInPortalDetails.portalDetails;
        // 2. Save all but the marker.
        window.plugin.drawTools.drawnItems.eachLayer(function (layer) { // drawnItems is a leaflet FeatureGroup.  See window.plugin.drawTools.boot().
            var foundMarker = false,
                item = {};
            count++;
            if (layer instanceof L.GeodesicCircle || layer instanceof L.Circle) {
                item.type = 'circle';
                item.latLng = layer.getLatLng();
                item.radius = layer.getRadius();
                item.color = layer.options.color;
            } else if (layer instanceof L.GeodesicPolygon || layer instanceof L.Polygon) {
                item.type = 'polygon';
                item.latLngs = layer.getLatLngs();
                item.color = layer.options.color;
            } else if (layer instanceof L.GeodesicPolyline || layer instanceof L.Polyline) {
                item.type = 'polyline';
                item.latLngs = layer.getLatLngs();
                item.color = layer.options.color;
            } else if (layer instanceof L.Marker) {
                item.type = 'marker';
                item.latLng = layer.getLatLng();
                item.color = layer.options.icon.options.color;
                foundMarker = ((item.latLng.lat == portalDetails.latE6 / 1E6) &&
                               (item.latLng.lng == portalDetails.lngE6 / 1E6));
           } else {
                console.warn('Unknown layer type when saving draw tools layer');
                return; //.eachLayer 'continue'
            }
            if (!foundMarker) {
                data.push(item);
            } else {
                console.log(fname + " [" + count + "] " + JSON.stringify(item) + ", foundMarker=" + foundMarker);
                refreshLayers = true; // We do not break from the loop since we need to save all the other items/layers for the refresh
            }
        });
        // TODO: Investigate using Leaflet removeLayer (use drawnItems.getLayers() with drawnItems.removeLayer(...)
        if (refreshLayers) {
            console.log(fname + ": Marker found on portal " + title);
            // 3. Save the layer data (which doesn't contain the marker) to local storage
            localStorage['plugin-draw-tools-layer'] = JSON.stringify(data); //  markers and other stuff saved here
            // 4. Refresh the layers
            window.plugin.drawTools.drawnItems.clearLayers();
            window.plugin.drawTools.import(data);
            window.plugin.drawTools.save();
        }
    };
	//
    // Setup function called by IITC.
	//
    self.setup = function init() {
        var fname = "plugin.addRemoveMarker.setup";
        var controlsHTML;
        if (window.plugin.drawTools === undefined) {
            alert("IITC plugin \"Add and Remove Marker\" requires IITC plugin \"draw tools\".");
            return;
        }
        // Link to Google Material icons.
        $("head").append("<link rel=\"stylesheet\" href=\"https://fonts.googleapis.com/icon?family\=Material+Icons\">");
		// Add toolbox controls.
        controlsHTML = "
" +
				"" +
				"add_location Add Marker" +
                "  " +
                "format_color_reset" +
                " Remove Marker" +
             "
";
        $("#toolbox").append(controlsHTML);
		// Add hook for portal details updated.
		window.addHook('portalDetailsUpdated', self.checkPortalDetailsUpdated);
        console.log(fname + ": Done.");
        delete self.setup; // delete setup to ensure init can't be run again
    };
    // IITC plugin setup
    if (window.iitcLoaded && typeof self.setup === "function") {
        self.setup();
    } else if (window.bootPlugins) {
        window.bootPlugins.push(self.setup);
    } else {
        window.bootPlugins = [self.setup];
    }
}

var script = document.createElement("script");
script.appendChild(document.createTextNode("(" + wrapper + ")();"));
(document.body || document.head || document.documentElement).appendChild(script);
<commit_msg>More efficient remove method<commit_after>// ==UserScript==
// @id             iitc-plugin-add-remove-marker@hayeswise
// @name           IITC plugin: Add and Remove Marker
// @category       Layer
// @version        1.2016.12.6
// @namespace      https://github.com/hayeswise/iitc-addremovemarker
// @description    Adds an Add Marker and Remove Marker control to the toolbox.
// @updateURL      https://github.com/hayeswise/iitc-addremovemarker/raw/master/wise-addRemoveMarker.user.js
// @downloadURL	   https://github.com/hayeswise/iitc-addremovemarker/raw/master/wise-addRemoveMarker.user.js
// @include        https://*.ingress.com/intel*
// @include        http://*.ingress.com/intel*
// @match          https://*.ingress.com/intel*
// @match          http://*.ingress.com/intel*
// @author         Hayeswise
// @grant          none
// ==/UserScript==
// MIT License, Copyright (c) 2016 Brian Hayes ("Hayeswise")
// For more information, visit https://github.com/hayeswise/iitc-addremovemarker

//
// Standard IITC wrapper pattern (and JavaScript encapsulation pattern).
// See last three lines of this file where it is used.
//
function wrapper() {
    // In case IITC is not available yet, define the base plugin object
    if (typeof window.plugin !== "function") {
        window.plugin = function () {};
    }
    // Base context/namespace for plugin
    window.plugin.addRemoveMarker = function () {};
    var self = window.plugin.addRemoveMarker;

    // Plugin level properties
    self.portalDataInPortalDetails = null;

    //
    // Add marker
    //
    self.addMarker = function () {
        var fname = "plugin.addRemoveMarker.addMarker";
        var count = 0,
            data = [], // For layer data
            item,
            portalDetails,
            title;
        if (!self.portalDataInPortalDetails) {
            alert("Select a portal to load the portal details before attempting to add a marker.");
            return;
        }
        title = (self.portalDataInPortalDetails && self.portalDataInPortalDetails.portalDetails.title) ? self.portalDataInPortalDetails.portalDetails.title : "[NO PORTAL DATA]";
        console.log(fname + ": guid:=" + self.portalDataInPortalDetails.guid + ", title:=" + title + ", have portal details=" + !!self.portalDataInPortalDetails);
        portalDetails = self.portalDataInPortalDetails.portalDetails;
        item = {
            type: 'marker',
            latLng: {
                lat: portalDetails.latE6 / 1E6,
                lng: portalDetails.lngE6 / 1E6
            },
        };
        window.plugin.drawTools.import([item]); // requires an array of items
        window.plugin.drawTools.save();
    };
    //
    // Save the portal details.
    //
    // @param data Object containing the guid, portal object, portalData object, and a portalDetails object.
    //
    self.checkPortalDetailsUpdated = function (data) {
        var fname = "plugin.addRemoveMarker.checkPortalDetailsUpdated";
        var title;
        self.portalDataInPortalDetails = data;
        title = data.portalData.title ? data.portalData.title : "[NO PORTAL DATA FOR portalDetailsUpdated RUNHOOK]";
        console.log(fname + "(data.guid:=" + data.guid + ", data.portalData.title:=" + title + ")");
        console.log(fname + ": Done.");
    };
     //
    // Removes the marker (map pin) on the portal shown in the sidebar portal details.
    //
    self.removeMarker = function () {
        var fname = "plugin.poiMarker.removeMarker";
        var count = 0,
            data = [], // For layer data
			maker = null, //Leaflet Layer()
            portalDetails,
            refreshLayers = false,
            title;
        // 1. Get the marker data. In this case, the poiMarker.checkPortalDetailLoaded() hook
        //    will have saved it when it was loaded into the sidebar portal details area.
        if (!self.portalDataInPortalDetails) {
            alert("Select a portal to load the portal details before attempting to remove a marker.");
            return;
        }
        title = (self.portalDataInPortalDetails && self.portalDataInPortalDetails.portalDetails.title) ? self.portalDataInPortalDetails.portalDetails.title : "[NO PORTAL DATA]";
        console.log(fname + ": guid:=" + self.portalDataInPortalDetails.guid + ", title:=" + title + ", have portal details=" + !!self.portalDataInPortalDetails);
        portalDetails = self.portalDataInPortalDetails.portalDetails;
        // 2. Find the marker
		marker = window.plugin.drawTools.drawnItems.getLayers().find (function(layer) {
			var latLng;
            if (layer.getLatLng) {
            latLng = layer.getLatLng();
            return (latLng.lat == portalDetails.latE6 / 1E6) &&
                   (latLng.lng == portalDetails.lngE6 / 1E6);
            } else {
                return false;
            }
		});
		// 3. If marker found, remove the marker, save, run draw hooks, and notify the ingress planner if it's being used.
		if (marker) { // if not undefined
		    console.log(fname + ": Removing marker for portal " + title);
			window.plugin.drawTools.drawnItems.removeLayer(marker);
            window.plugin.drawTools.save();
            runHooks('pluginDrawTools', {
                event: 'import' //event: 'layersDeleted'
            });
			if (window.plugin.ingressplanner) {
				window.plugin.ingressplanner.sendMessage('update-drawing',localStorage['plugin-draw-tools-layer']);
			}
        } else {
            console.log(fname + ": Portal marker not found. Portal title: " + title);
        }
    };
	//
    // Setup function called by IITC.
	//
    self.setup = function init() {
        var fname = "plugin.addRemoveMarker.setup";
        var controlsHTML;
        if (window.plugin.drawTools === undefined) {
            alert('IITC plugin "Add and Remove Marker" requires IITC plugin "draw tools".');
            return;
        }
        // Link to Google Material icons.
        $("head").append('<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family\=Material+Icons">');
		// Add toolbox controls.
        controlsHTML = '
' +
				'' +
				'add_location Add Marker' +
                '  ' +
                'format_color_reset' +
                ' Remove Marker' +
             '
';
        $("#toolbox").append(controlsHTML);
		// Add hook for portal details updated.
		window.addHook('portalDetailsUpdated', self.checkPortalDetailsUpdated);
        console.log(fname + ": Done.");
        delete self.setup; // Delete setup to ensure init can't be run again.
    };
    // IITC plugin setup
    if (window.iitcLoaded && typeof self.setup === "function") {
        self.setup();
    } else if (window.bootPlugins) {
        window.bootPlugins.push(self.setup);
    } else {
        window.bootPlugins = [self.setup];
    }
}

var script = document.createElement("script");
script.appendChild(document.createTextNode("(" + wrapper + ")();"));
(document.body || document.head || document.documentElement).appendChild(script);
<|endoftext|>


<commit_before>'use strict'

import test from 'tape'
import Grid from '../../'

test('create grid', async t => {
  t.plan(2)
  const width = 1600
  const height = 900
  try {
    const grid = new Grid({width, height})
    t.deepEquals(grid.size, {width, height}, 'grid created with correct initial size')
    t.equals(grid.windows.length, 0, 'grid created with no windows')
  } catch (e) {
    t.fail(e)
    t.end()
  }
})
<commit_msg>added negative grid create test case<commit_after>'use strict'

import test from 'tape'
import Grid from '../../'

test('can create grid', async t => {
  t.plan(2)
  const width = 1600
  const height = 900
  try {
    const grid = new Grid({width, height})
    t.deepEquals(grid.size, {width, height}, 'grid created with correct initial size')
    t.equals(grid.windows.length, 0, 'grid created with no windows')
  } catch (e) {
    t.fail(e)
    t.end()
  }
})

test.skip('cannot create grid with bad parameters', async t => {
  // TBD
})
<|endoftext|>


<commit_before>/**
 * Pimcore
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://www.pimcore.org/license
 *
 * @copyright  Copyright (c) 2009-2010 elements.at New Media Solutions GmbH (http://www.elements.at)
 * @license    http://www.pimcore.org/license     New BSD License
 */

pimcore.registerNS("pimcore.object.tags.wysiwyg");
pimcore.object.tags.wysiwyg = Class.create(pimcore.object.tags.abstract, {

    type: "wysiwyg",

    initialize: function (data, fieldConfig) {
        this.data = "";
        if (data) {
            this.data = data;
        }
        this.fieldConfig = fieldConfig;

        if (intval(this.fieldConfig.width) < 1) {
            this.fieldConfig.width = 400;
        }
        if (intval(this.fieldConfig.height) < 1) {
            this.fieldConfig.height = 300;
        }

        this.editableDivId = "object_wysiwyg_" + uniqid();
        this.previewIframeId = "object_wysiwyg_iframe_" + uniqid();

    },

    getGridColumnEditor: function(field) {
        var editorConfig = {};

        if (field.config) {
            if (field.config.width) {
                if (intval(field.config.width) > 10) {
                    editorConfig.width = field.config.width;
                }
            }
        }

        if(field.layout.noteditable) {
            return null;
        }
        // WYSIWYG
        if (field.type == "wysiwyg") {
            return new Ext.form.HtmlEditor({
                width: 500,
                height: 300
            });
        }
    },

    getGridColumnFilter: function(field) {
        return {type: 'string', dataIndex: field.key};
    },

    getLayoutEdit: function () {
        this.getLayout();
        this.disableEditing = false;
        this.component.on("afterrender", this.getPreview.bind(this));
        return this.component;
    },

    getLayout: function () {
        var pConf = {
            title: this.fieldConfig.title,
            width: this.fieldConfig.width,
            html: '

',
            cls: "object_field"
        };

        this.component = new Ext.Panel(pConf);
    },

    getPreview: function() {

        var iframe = document.createElement("iframe");
        iframe.setAttribute("frameborder", "0");
        iframe.setAttribute("id", this.previewIframeId);
        iframe.onload = function () {
            var document = Ext.get(this.previewIframeId).dom.contentWindow.document;
            var iframeContent = this.data;
            iframeContent += '<link href="/pimcore/static/js/lib/ckeditor/contents.css" rel="stylesheet" type="text/css" />';
            document.body.innerHTML = iframeContent;
            document.body.setAttribute("style", "height: 80%; cursor: pointer;");

            if(this.disableEditing == false) {
                Ext.get(document.body).on("click", this.initCkEditor.bind(this));
            }

        }.bind(this);

        Ext.get(this.editableDivId).dom.innerHTML = "";
        Ext.get(this.editableDivId).dom.appendChild(iframe);

        // set dimensions of iframe
        if (this.fieldConfig.height) {
            Ext.get(this.previewIframeId).setStyle({
                height: this.fieldConfig.height + "px"
            });
        }
        if (this.fieldConfig.width) {
            Ext.get(this.previewIframeId).setStyle({
                width: this.fieldConfig.width + "px"
            });
        }
    },

    getLayoutShow: function () {
        this.getLayout();
        this.disableEditing = true;
        this.component.on("afterrender", this.getPreview.bind(this));
        return this.component;
    },

    initCkEditor: function () {

        var toolbar_Full = [
            ["close_object",'Cut','Copy','Paste','PasteText','PasteFromWord','-', 'SpellChecker'],
            ['Undo','Redo','-','Find','Replace','-','SelectAll','RemoveFormat'],
            '/',
            ['Bold','Italic','Underline','Strike','-','Subscript','Superscript'],
            ['NumberedList','BulletedList','-','Outdent','Indent','Blockquote'],
            ['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'],
            ['Link','Unlink','Anchor'],
            ['Image','Flash','Table','HorizontalRule','SpecialChar','PageBreak'],
            '/',
            ['Styles','Format','Font','FontSize'],
            ['TextColor','BGColor'],
            ['Maximize', 'ShowBlocks','Source']
        ];

        var eConfig = {
            uiColor: "#f2f2f2",
            toolbar: toolbar_Full,
            width: this.fieldConfig.width,
            height: this.fieldConfig.height,
            resize_enabled: false
        };

        eConfig.extraPlugins = "close_object";

        if (intval(this.fieldConfig.width) > 1) {
            eConfig.width = this.fieldConfig.width;
        }
        if (intval(this.fieldConfig.height) > 1) {
            eConfig.height = this.fieldConfig.height;
        }

        Ext.get(this.editableDivId).update(this.data);
        this.ckeditor = CKEDITOR.replace(this.editableDivId, eConfig);
        this.ckeditor.pimcore_tag_instance = this;
    },

    mask: function () {
        try {
            var pan = this.component.el;

            if (pan) {
                pan.setStyle({
                    position: "relative"
                });

                var maskEl = pan.createChild({
                    tag: "div",
                    id: Ext.id()
                })

                maskEl = Ext.get(maskEl.id);

                maskEl.addClass("pimcore_wysiwyg_mask");
                maskEl.setStyle({
                    top: 0,
                    left: 0,
                    zIndex: 10000,
                    width: pan.getWidth() + "px",
                    height: pan.getHeight() + "px",
                    position: "absolute"
                });

                this.maskEl = maskEl.dom;

                // add drop zone
                var dd = new Ext.dd.DropZone(this.maskEl, {
                    ddGroup: "element",

                    getTargetFromEvent: function(e) {
                        return this.getEl();
                    },

                    onNodeOver : function(target, dd, e, data) {
                        return Ext.dd.DropZone.prototype.dropAllowed;
                    },

                    onNodeDrop : this.onNodeDrop.bind(this)
                });
            }
        }
        catch (e) {
            console.log(e);
        }
    },

    unmask: function () {
        if (this.maskEl) {
            Ext.get(this.maskEl).remove();
        }
    },

    onNodeDrop: function (target, dd, e, data) {

        if (!this.ckeditor) {
            return;
        }

        var wrappedText = data.node.attributes.text;
        var textIsSelected = false;

        try {
            var selection = this.ckeditor.getSelection();
            var bookmarks = selection.createBookmarks();
            var range = selection.getRanges()[ 0 ];
            var fragment = range.clone().cloneContents();

            selection.selectBookmarks(bookmarks);
            var retval = "";
            var childList = fragment.getChildren();
            var childCount = childList.count();

            for (var i = 0; i < childCount; i++) {
                var child = childList.getItem(i);
                retval += ( child.getOuterHtml ?
                        child.getOuterHtml() : child.getText() );
            }

            if (retval.length > 0) {
                wrappedText = retval;
                textIsSelected = true;
            }
        }
        catch (e) {
        }

        // remove existing links out of the wrapped text
        wrappedText = wrappedText.replace(/<\/?([a-z][a-z0-9]*)\b[^>]*>/gi, function ($0, $1) {
            if($1.toLowerCase() == "a") {
                return "";
            }
            return $0;
        });

        var id = data.node.attributes.id;
        var uri = data.node.attributes.path;

        if (data.node.attributes.elementType == "asset") {
            if (data.node.attributes.type == "image" && textIsSelected == false) {
                // only use thumbnails
                var defaultWidth = 400;
                uri = "/admin/asset/get-image-thumbnail/id/" + id + "/width/" + defaultWidth + "/aspectratio/true";
                this.ckeditor.insertHtml('');
                return true;
            }
            else {
                this.ckeditor.insertHtml('' + wrappedText + '');
                return true;
            }
        }

        if (data.node.attributes.type == "page") {
            this.ckeditor.insertHtml('' + wrappedText + '');
            return true;
        }

    },

    getValue: function () {

        var data = this.data;
        try {
            if (this.ckeditor) {
                data = this.ckeditor.getData();
            }
        }
        catch (e) {
        }

        this.data = data;

        return this.data;
    },

    getName: function () {
        return this.fieldConfig.name;
    },

    isDirty: function() {
        if(!this.isRendered()) {
            return false;
        }

        if(this.dirty) {
            return this.dirty;
        }

        if(this.ckeditor) {
            return this.ckeditor.checkDirty();
        }
        return false;
//        return this.ckeditor.IsDirty();
    }
});

// add close button plugin
var ckeditor_close_objectplugin_button ='close_object';
CKEDITOR.plugins.add(ckeditor_close_objectplugin_button,{
    init:function(editor){
        editor.addCommand(ckeditor_close_objectplugin_button, {
            exec:function(editor){
                window.setTimeout(function () {
                    try {
                        this.data = this.ckeditor.getData();
                        this.ckeditor.destroy();
                        this.ckeditor = null;
                        this.dirty = true;

                        this.getPreview();
                    } catch (e) {
                        console.log(e);
                    }
                }.bind(editor.pimcore_tag_instance), 10);
            }
        });
        editor.ui.addButton("close_object",{
            label:t('close'),
            icon: "/pimcore/static/img/icon/cross.png",
            command: ckeditor_close_objectplugin_button
        });
    }
});
<commit_msg>fixed problem with wysiwyg and IE8 in objects<commit_after>/**
 * Pimcore
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://www.pimcore.org/license
 *
 * @copyright  Copyright (c) 2009-2010 elements.at New Media Solutions GmbH (http://www.elements.at)
 * @license    http://www.pimcore.org/license     New BSD License
 */

pimcore.registerNS("pimcore.object.tags.wysiwyg");
pimcore.object.tags.wysiwyg = Class.create(pimcore.object.tags.abstract, {

    type: "wysiwyg",

    initialize: function (data, fieldConfig) {
        this.data = "";
        if (data) {
            this.data = data;
        }
        this.fieldConfig = fieldConfig;

        if (intval(this.fieldConfig.width) < 1) {
            this.fieldConfig.width = 400;
        }
        if (intval(this.fieldConfig.height) < 1) {
            this.fieldConfig.height = 300;
        }

        this.editableDivId = "object_wysiwyg_" + uniqid();
        this.previewIframeId = "object_wysiwyg_iframe_" + uniqid();

    },

    getGridColumnEditor: function(field) {
        var editorConfig = {};

        if (field.config) {
            if (field.config.width) {
                if (intval(field.config.width) > 10) {
                    editorConfig.width = field.config.width;
                }
            }
        }

        if(field.layout.noteditable) {
            return null;
        }
        // WYSIWYG
        if (field.type == "wysiwyg") {
            return new Ext.form.HtmlEditor({
                width: 500,
                height: 300
            });
        }
    },

    getGridColumnFilter: function(field) {
        return {type: 'string', dataIndex: field.key};
    },

    getLayoutEdit: function () {
        this.getLayout();
        this.disableEditing = false;
        this.component.on("afterrender", this.getPreview.bind(this));
        return this.component;
    },

    getLayout: function () {
        var pConf = {
            title: this.fieldConfig.title,
            width: this.fieldConfig.width,
            html: '

',
            cls: "object_field"
        };

        this.component = new Ext.Panel(pConf);
    },

    getPreview: function() {

        var iframe = document.createElement("iframe");
        iframe.setAttribute("frameborder", "0");
        iframe.setAttribute("id", this.previewIframeId);

        // unfortunately iframe.onload doesn't work in IE8, so that we have to use setTimeout()
        window.setTimeout(function () {
            var document = Ext.get(this.previewIframeId).dom.contentWindow.document;
            var iframeContent = this.data;
            iframeContent += '<link href="/pimcore/static/js/lib/ckeditor/contents.css" rel="stylesheet" type="text/css" />';
            document.body.innerHTML = iframeContent;
            document.body.setAttribute("style", "height: 80%; cursor: pointer;");

            if(this.disableEditing == false) {
                Ext.get(document.body).on("click", this.initCkEditor.bind(this));
            }
        }.bind(this), 500);

        Ext.get(this.editableDivId).update("");
        Ext.get(this.editableDivId).dom.appendChild(iframe);

        // set dimensions of iframe
        if (this.fieldConfig.height) {
            Ext.get(this.previewIframeId).setStyle({
                height: this.fieldConfig.height + "px"
            });
        }
        if (this.fieldConfig.width) {
            Ext.get(this.previewIframeId).setStyle({
                width: this.fieldConfig.width + "px"
            });
        }
    },

    getLayoutShow: function () {
        this.getLayout();
        this.disableEditing = true;
        this.component.on("afterrender", this.getPreview.bind(this));
        return this.component;
    },

    initCkEditor: function () {

        var toolbar_Full = [
            ["close_object",'Cut','Copy','Paste','PasteText','PasteFromWord','-', 'SpellChecker'],
            ['Undo','Redo','-','Find','Replace','-','SelectAll','RemoveFormat'],
            '/',
            ['Bold','Italic','Underline','Strike','-','Subscript','Superscript'],
            ['NumberedList','BulletedList','-','Outdent','Indent','Blockquote'],
            ['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'],
            ['Link','Unlink','Anchor'],
            ['Image','Flash','Table','HorizontalRule','SpecialChar','PageBreak'],
            '/',
            ['Styles','Format','Font','FontSize'],
            ['TextColor','BGColor'],
            ['Maximize', 'ShowBlocks','Source']
        ];

        var eConfig = {
            uiColor: "#f2f2f2",
            toolbar: toolbar_Full,
            width: this.fieldConfig.width,
            height: this.fieldConfig.height,
            resize_enabled: false
        };

        eConfig.extraPlugins = "close_object";

        if (intval(this.fieldConfig.width) > 1) {
            eConfig.width = this.fieldConfig.width;
        }
        if (intval(this.fieldConfig.height) > 1) {
            eConfig.height = this.fieldConfig.height;
        }

        Ext.get(this.editableDivId).update(this.data);
        this.ckeditor = CKEDITOR.replace(this.editableDivId, eConfig);
        this.ckeditor.pimcore_tag_instance = this;
    },

    mask: function () {
        try {
            var pan = this.component.el;

            if (pan) {
                pan.setStyle({
                    position: "relative"
                });

                var maskEl = pan.createChild({
                    tag: "div",
                    id: Ext.id()
                })

                maskEl = Ext.get(maskEl.id);

                maskEl.addClass("pimcore_wysiwyg_mask");
                maskEl.setStyle({
                    top: 0,
                    left: 0,
                    zIndex: 10000,
                    width: pan.getWidth() + "px",
                    height: pan.getHeight() + "px",
                    position: "absolute"
                });

                this.maskEl = maskEl.dom;

                // add drop zone
                var dd = new Ext.dd.DropZone(this.maskEl, {
                    ddGroup: "element",

                    getTargetFromEvent: function(e) {
                        return this.getEl();
                    },

                    onNodeOver : function(target, dd, e, data) {
                        return Ext.dd.DropZone.prototype.dropAllowed;
                    },

                    onNodeDrop : this.onNodeDrop.bind(this)
                });
            }
        }
        catch (e) {
            console.log(e);
        }
    },

    unmask: function () {
        if (this.maskEl) {
            Ext.get(this.maskEl).remove();
        }
    },

    onNodeDrop: function (target, dd, e, data) {

        if (!this.ckeditor) {
            return;
        }

        var wrappedText = data.node.attributes.text;
        var textIsSelected = false;

        try {
            var selection = this.ckeditor.getSelection();
            var bookmarks = selection.createBookmarks();
            var range = selection.getRanges()[ 0 ];
            var fragment = range.clone().cloneContents();

            selection.selectBookmarks(bookmarks);
            var retval = "";
            var childList = fragment.getChildren();
            var childCount = childList.count();

            for (var i = 0; i < childCount; i++) {
                var child = childList.getItem(i);
                retval += ( child.getOuterHtml ?
                        child.getOuterHtml() : child.getText() );
            }

            if (retval.length > 0) {
                wrappedText = retval;
                textIsSelected = true;
            }
        }
        catch (e) {
        }

        // remove existing links out of the wrapped text
        wrappedText = wrappedText.replace(/<\/?([a-z][a-z0-9]*)\b[^>]*>/gi, function ($0, $1) {
            if($1.toLowerCase() == "a") {
                return "";
            }
            return $0;
        });

        var id = data.node.attributes.id;
        var uri = data.node.attributes.path;

        if (data.node.attributes.elementType == "asset") {
            if (data.node.attributes.type == "image" && textIsSelected == false) {
                // only use thumbnails
                var defaultWidth = 400;
                uri = "/admin/asset/get-image-thumbnail/id/" + id + "/width/" + defaultWidth + "/aspectratio/true";
                this.ckeditor.insertHtml('');
                return true;
            }
            else {
                this.ckeditor.insertHtml('' + wrappedText + '');
                return true;
            }
        }

        if (data.node.attributes.type == "page") {
            this.ckeditor.insertHtml('' + wrappedText + '');
            return true;
        }

    },

    getValue: function () {

        var data = this.data;
        try {
            if (this.ckeditor) {
                data = this.ckeditor.getData();
            }
        }
        catch (e) {
        }

        this.data = data;

        return this.data;
    },

    getName: function () {
        return this.fieldConfig.name;
    },

    isDirty: function() {
        if(!this.isRendered()) {
            return false;
        }

        if(this.dirty) {
            return this.dirty;
        }

        if(this.ckeditor) {
            return this.ckeditor.checkDirty();
        }
        return false;
//        return this.ckeditor.IsDirty();
    }
});

// add close button plugin
var ckeditor_close_objectplugin_button ='close_object';
CKEDITOR.plugins.add(ckeditor_close_objectplugin_button,{
    init:function(editor){
        editor.addCommand(ckeditor_close_objectplugin_button, {
            exec:function(editor){
                window.setTimeout(function () {
                    try {
                        this.data = this.ckeditor.getData();
                        this.ckeditor.destroy();
                        this.ckeditor = null;
                        this.dirty = true;

                        this.getPreview();
                    } catch (e) {
                        console.log(e);
                    }
                }.bind(editor.pimcore_tag_instance), 10);
            }
        });
        editor.ui.addButton("close_object",{
            label:t('close'),
            icon: "/pimcore/static/img/icon/cross.png",
            command: ckeditor_close_objectplugin_button
        });
    }
});
<|endoftext|>


<commit_before>(function (angular) {
    'use strict';
    var archivoPerfilControllerApp = angular.module('archivoPerfil', ['ngAnimate', 'ngSanitize', 'ui.bootstrap', 'ui.grid', 'ngTouch', 'ui.grid.edit', 'ui.grid.autoResize', 'ui.grid.selection', 'ui.grid.cellNav', 'xeditable'])
    .controller('archivoPerfilController', ['$scope', '$http', '$window', '$location', '$filter', 'uiGridConstants', 'i18nService', '$scope', function ($scope, $http, $window, $location, $filter, i18nService, uiGridConstants) {
        var init = function () {
            $scope.archivoID = $window.localStorage.getItem("archivoID");
            // DATOS PRINCIPALES
            $scope.cargarDatosPrincipales();
            // ANOTACIONES
            $scope.cargarNotas();
        };

        //Datos principales
        $scope.archivoDatos = {};
        $scope.datosPrincipales = {};
        $scope.datosPrincipales.archivoTitulo = "";
        $scope.datosPrincipales.archivoNombre = "";
        $scope.datosPrincipales.institucionFondo = "";
        $scope.datosPrincipales.seccion = "";
        $scope.datosPrincipales.numRefDentroFondo = "";
        $scope.datosPrincipales.archivoFecha = "";
        $scope.datosPrincipales.folioInicial = "";
        $scope.datosPrincipales.folioFinal = "";
        $scope.datosPrincipales.legajo = "";
        $scope.datosPrincipales.numOrden = "";
        $scope.datosPrincipales.numPaginas = "";
        $scope.datosPrincipales.palabrasClaves = {};
        $scope.datosPrincipales.disponibilidad = "";

        //Bandera para saber cuando guardar o no
        $scope.datosPrincipales.editado = false;

        $scope.cargarDatosPrincipales = function () {
            $http.get('http://monsalvediaz.com:5000/PIMC0.1/ConsultaArchivo?archivoID=' + $scope.archivoID).then(function (data) {
                //Obtener los datos JSON
                $scope.archivoDatos = data.data[0];
                //Log
                console.log($scope.archivoDatos);

                //Llenamos los datos del archivo
                $scope.datosPrincipales.archivoTitulo = $scope.archivoDatos.titulo;
                $scope.datosPrincipales.archivoNombre = $scope.archivoDatos.fondo;
                $scope.datosPrincipales.institucionFondo = $scope.archivoDatos.institucionFondo;
                $scope.datosPrincipales.seccion = $scope.archivoDatos.seccion;
                $scope.datosPrincipales.numRefDentroFondo = $scope.archivoDatos.numRefDentroFondo;
                $scope.datosPrincipales.archivoFecha = $filter('date')(new Date($scope.archivoDatos.fechaInicial), String($scope.archivoDatos.fechaInicialFormato).toLowerCase()) + " - " + $filter('date')(new Date($scope.archivoDatos.fechaFinal), String($scope.archivoDatos.fechaFinalFormato).toLowerCase());
                $scope.datosPrincipales.folioInicial = $scope.archivoDatos.folioInicial;
                $scope.datosPrincipales.folioFinal = $scope.archivoDatos.folioFinal;
                $scope.datosPrincipales.legajo = $scope.archivoDatos.legajo;
                $scope.datosPrincipales.numOrden = $scope.archivoDatos.numOrden;
                $scope.datosPrincipales.numPaginas = $scope.archivoDatos.numPaginas;
                $scope.datosPrincipales.palabrasClaves = $scope.archivoDatos.palabrasClaves.split(",");
                $scope.datosPrincipales.palabrasClaves = $scope.datosPrincipales.palabrasClaves.map(function (e) { return e.trim(); });

                $scope.datosPrincipales.disponibilidad = $scope.archivoDatos.disponibilidad;
                //Limpiamos la bandera de editado
                $scope.datosPrincipales.editado = false;

                //Para palabras claves
                $scope.palabraNueva = {mensaje:"+Agregar"};

            });
        };

        // Anotaciones
        $scope.notas = "";
        $scope.notasAgregadas = false;
        $scope.cargarNotas = function () {
            $http.get('http://monsalvediaz.com:5000/PIMC0.1/Consulta/ArchivosNotas?archivoID=' + $scope.archivoID).then(function (data) {
                if (String(data).startsWith("[WARNING]")) {
                    $scope.notas = data.data;
                    // LOG
                    console.log($scope.notas);
                }
            });

        };
        $scope.agregarNotaVacia = function () {
            if ($scope.notas === "") {
                $scope.notas = [{
                    nota:"",
                    referencia:"",
                    fechaHistorica:"",
                    fechaHistFormato:""
                }];
            } else {
                $scope.notas.push({
                nota:"",
                referencia:"",
                fechaHistorica:"",
                fechaHistFormato:""
            });
            }
            $scope.notasAgregadas = true;
        }

        // Initialization fucntion
        init();

        // Para borrar palabras claves
        $scope.borrarSiVacio = function (indexEditada, palabra) {
            if (palabra == "") {
                $scope.datosPrincipales.palabrasClaves.splice(indexEditada,1);
            }
        }
        //Para agregar palabras claves
        $scope.palabraNueva = {mensaje: '+Agregar'};

        $scope.borrarCampo = function () {
            $scope.palabraNueva.mensaje = "";
        }
        $scope.mostrarCampo = function () {
            $scope.palabraNueva.mensaje = "+Agregar";
        }
        $scope.agregarPalabraNueva = function (palabra) {
            if (!$scope.datosPrincipales.palabrasClaves.includes(palabra) && palabra.length != 0) {
                $scope.datosPrincipales.palabrasClaves.push(palabra);
            }
            $scope.palabraNueva.mensaje = "+Agregar";
        }

        //Para guardar borrar y barra
        $scope.ultimaAccion = "";
        // Button functions
        $scope.borrarCambios = function () {
            if (window.confirm("Esta Seguro que quiere borrar los cambios?") === true) {
                init();
            }
        };
        $scope.guardarCambios = function () {
            if($scope.notasAgregadas) {
                $scope.notas.forEach(function (nota) {
                    if (nota.nota.length() != 0)
                        $http.get('http://monsalvediaz.com:5000/PIMC0.1/Modificar/ArchivosNotas?idUnico=archivoID&nota=' + nota.nota + '&referencia='  + nota.referencia).then(function (data) {

                        };
                })
            }
            //Revisamos datos principales editados
            if ($scope.datosPrincipales.editado) {

            }
        };

    }]);
    archivoPerfilControllerApp.run(function (editableOptions,editableThemes) {
        editableThemes.bs3.inputClass = 'input-sm';
        editableThemes.bs3.buttonsClass = 'btn-sm';
        editableOptions.theme = 'bs3';
        editableOptions.buttons = 'no';
    });
})(window.angular);

<commit_msg>Agregar Notas<commit_after>(function (angular) {
    'use strict';
    var archivoPerfilControllerApp = angular.module('archivoPerfil', ['ngAnimate', 'ngSanitize', 'ui.bootstrap', 'ui.grid', 'ngTouch', 'ui.grid.edit', 'ui.grid.autoResize', 'ui.grid.selection', 'ui.grid.cellNav', 'xeditable'])
    .controller('archivoPerfilController', ['$scope', '$http', '$window', '$location', '$filter', 'uiGridConstants', 'i18nService', '$scope', function ($scope, $http, $window, $location, $filter, i18nService, uiGridConstants) {
        var init = function () {
            $scope.archivoID = $window.localStorage.getItem("archivoID");
            // DATOS PRINCIPALES
            $scope.cargarDatosPrincipales();
            // ANOTACIONES
            $scope.cargarNotas();
        };

        //Datos principales
        $scope.archivoDatos = {};
        $scope.datosPrincipales = {};
        $scope.datosPrincipales.archivoTitulo = "";
        $scope.datosPrincipales.archivoNombre = "";
        $scope.datosPrincipales.institucionFondo = "";
        $scope.datosPrincipales.seccion = "";
        $scope.datosPrincipales.numRefDentroFondo = "";
        $scope.datosPrincipales.archivoFecha = "";
        $scope.datosPrincipales.folioInicial = "";
        $scope.datosPrincipales.folioFinal = "";
        $scope.datosPrincipales.legajo = "";
        $scope.datosPrincipales.numOrden = "";
        $scope.datosPrincipales.numPaginas = "";
        $scope.datosPrincipales.palabrasClaves = {};
        $scope.datosPrincipales.disponibilidad = "";

        //Bandera para saber cuando guardar o no
        $scope.datosPrincipales.editado = false;

        $scope.cargarDatosPrincipales = function () {
            $http.get('http://monsalvediaz.com:5000/PIMC0.1/ConsultaArchivo?archivoID=' + $scope.archivoID).then(function (data) {
                //Obtener los datos JSON
                $scope.archivoDatos = data.data[0];
                //Log
                console.log($scope.archivoDatos);

                //Llenamos los datos del archivo
                $scope.datosPrincipales.archivoTitulo = $scope.archivoDatos.titulo;
                $scope.datosPrincipales.archivoNombre = $scope.archivoDatos.fondo;
                $scope.datosPrincipales.institucionFondo = $scope.archivoDatos.institucionFondo;
                $scope.datosPrincipales.seccion = $scope.archivoDatos.seccion;
                $scope.datosPrincipales.numRefDentroFondo = $scope.archivoDatos.numRefDentroFondo;
                $scope.datosPrincipales.archivoFecha = $filter('date')(new Date($scope.archivoDatos.fechaInicial), String($scope.archivoDatos.fechaInicialFormato).toLowerCase()) + " - " + $filter('date')(new Date($scope.archivoDatos.fechaFinal), String($scope.archivoDatos.fechaFinalFormato).toLowerCase());
                $scope.datosPrincipales.folioInicial = $scope.archivoDatos.folioInicial;
                $scope.datosPrincipales.folioFinal = $scope.archivoDatos.folioFinal;
                $scope.datosPrincipales.legajo = $scope.archivoDatos.legajo;
                $scope.datosPrincipales.numOrden = $scope.archivoDatos.numOrden;
                $scope.datosPrincipales.numPaginas = $scope.archivoDatos.numPaginas;
                $scope.datosPrincipales.palabrasClaves = $scope.archivoDatos.palabrasClaves.split(",");
                $scope.datosPrincipales.palabrasClaves = $scope.datosPrincipales.palabrasClaves.map(function (e) { return e.trim(); });

                $scope.datosPrincipales.disponibilidad = $scope.archivoDatos.disponibilidad;
                //Limpiamos la bandera de editado
                $scope.datosPrincipales.editado = false;

                //Para palabras claves
                $scope.palabraNueva = {mensaje:"+Agregar"};

            });
        };

        // Anotaciones
        $scope.notas = "";
        $scope.notasAgregadas = false;
        $scope.cargarNotas = function () {
            $http.get('http://monsalvediaz.com:5000/PIMC0.1/Consulta/ArchivosNotas?archivoID=' + $scope.archivoID).then(function (data) {
                if (String(data).startsWith("[WARNING]")) {
                    $scope.notas = data.data;
                    // LOG
                    console.log($scope.notas);
                }
            });

        };
        $scope.agregarNotaVacia = function () {
            if ($scope.notas === "") {
                $scope.notas = [{
                    nota:"",
                    referencia:"",
                    fechaHistorica:"",
                    fechaHistFormato:""
                }];
            } else {
                $scope.notas.push({
                nota:"",
                referencia:"",
                fechaHistorica:"",
                fechaHistFormato:""
            });
            }
            $scope.notasAgregadas = true;
        }

        // Initialization fucntion
        init();

        // Para borrar palabras claves
        $scope.borrarSiVacio = function (indexEditada, palabra) {
            if (palabra == "") {
                $scope.datosPrincipales.palabrasClaves.splice(indexEditada,1);
            }
        }
        //Para agregar palabras claves
        $scope.palabraNueva = {mensaje: '+Agregar'};

        $scope.borrarCampo = function () {
            $scope.palabraNueva.mensaje = "";
        }
        $scope.mostrarCampo = function () {
            $scope.palabraNueva.mensaje = "+Agregar";
        }
        $scope.agregarPalabraNueva = function (palabra) {
            if (!$scope.datosPrincipales.palabrasClaves.includes(palabra) && palabra.length != 0) {
                $scope.datosPrincipales.palabrasClaves.push(palabra);
            }
            $scope.palabraNueva.mensaje = "+Agregar";
        }

        //Para guardar borrar y barra
        $scope.ultimaAccion = "";
        // Button functions
        $scope.borrarCambios = function () {
            if (window.confirm("Esta Seguro que quiere borrar los cambios?") === true) {
                init();
            }
        };
        $scope.guardarCambios = function () {
            if($scope.notasAgregadas) {
                $scope.notas.forEach(function (nota) {
                    if (nota.nota.length() != 0)
                        $http.get('http://monsalvediaz.com:5000/PIMC0.1/Modificar/ArchivosNotas?idUnico=archivoID&nota="' + nota.nota + '"&referencia="'  + nota.referencia + '"').then(function (data) {
                            console.log(data);
                        };
                })
            }
            //Revisamos datos principales editados
            if ($scope.datosPrincipales.editado) {

            }
        };

    }]);
    archivoPerfilControllerApp.run(function (editableOptions,editableThemes) {
        editableThemes.bs3.inputClass = 'input-sm';
        editableThemes.bs3.buttonsClass = 'btn-sm';
        editableOptions.theme = 'bs3';
        editableOptions.buttons = 'no';
    });
})(window.angular);

<|endoftext|>


<commit_before>/**
 * jQuery yiiactiveform plugin file.
 *
 * @author Qiang Xue <qiang.xue@gmail.com>
 * @link http://www.yiiframework.com/
 * @copyright Copyright © 2008-2010 Yii Software LLC
 * @license http://www.yiiframework.com/license/
 * @version $Id$
 * @since 1.1.1
 */

;(function ($) {
	/*
	 * returns the value of the CActiveForm input field
	 * performs additional checks to get proper values for checkbox / radiobutton / checkBoxList / radioButtonList
	 * @param o object the jQuery object of the input element
	 */
	var getAFValue = function (o) {
		var type = o.attr('type');
		if(o[0].tagName.toLowerCase()=='span') {
			var c = [];
			o.find(':checked').each(function () {
				c.push(this.value);
			});
			return c.join(',');
		}
		if (type === 'checkbox' || type === 'radio') {
			return o.filter(':checked').val();
		} else {
			return o.val();
		}
	};

	/**
	 * yiiactiveform set function.
	 * @param options map settings for the active form plugin. Please see {@link CActiveForm::options} for availablel options.
	 */
	$.fn.yiiactiveform = function (options) {
		return this.each(function () {
			var settings = $.extend({}, $.fn.yiiactiveform.defaults, options || {}),
				$form = $(this);

			if (settings.validationUrl === undefined) {
				settings.validationUrl = $form.attr('action');
			}
			$.each(settings.attributes, function () {
				$.extend(this, {
					validationDelay : settings.validationDelay,
					validateOnChange : settings.validateOnChange,
					validateOnType : settings.validateOnType,
					hideErrorMessage : settings.hideErrorMessage,
					inputContainer : settings.inputContainer,
					errorCssClass : settings.errorCssClass,
					successCssClass : settings.successCssClass,
					beforeValidateAttribute : settings.beforeValidateAttribute,
					afterValidateAttribute : settings.afterValidateAttribute,
					validatingCssClass : settings.validatingCssClass
				});
				this.value = getAFValue($('#' + this.inputID, $form));
			});
			$(this).data('settings', settings);

			settings.submitting = false;  // whether it is waiting for ajax submission result
			var validate = function (attribute) {
				var changed = false;
				$.each(settings.attributes, function () {
					if (this.value !== getAFValue($('#' + this.inputID, $form))) {
						this.status = 2;
						changed = true;
					}
				});
				if (!changed) {
					return;
				}

				if (settings.timer !== undefined) {
					clearTimeout(settings.timer);
				}
				settings.timer = setTimeout(function () {
					if (settings.submitting || $form.is(':hidden')) {
						return;
					}
					if (attribute.beforeValidateAttribute === undefined || attribute.beforeValidateAttribute($form, attribute)) {
						$.each(settings.attributes, function () {
							if (this.status === 2) {
								this.status = 3;
								$.fn.yiiactiveform.getInputContainer(this, $form).addClass(this.validatingCssClass);
							}
						});
						$.fn.yiiactiveform.validate($form, function (data) {
							var hasError = false;
							$.each(settings.attributes, function () {
								if (this.status === 2 || this.status === 3) {
									hasError = $.fn.yiiactiveform.updateInput(this, data, $form) || hasError;
								}
							});
							if (attribute.afterValidateAttribute !== undefined) {
								attribute.afterValidateAttribute($form, attribute, data, hasError);
							}
						});
					}
				}, attribute.validationDelay);
			};

			$.each(settings.attributes, function () {
				if (this.validateOnChange) {
					$('#' + this.inputID, $form).change(function () {
						validate(this);
					}).blur(function () {
						if (this.status !== 2 && this.status !== 3) {
							validate(this);
						}
					});
				}
				if (this.validateOnType) {
					$('#' + this.inputID, $form).keyup(function () {
						if (this.value !== getAFValue($(this))) {
							validate(this);
						}
					});
				}
			});

			if (settings.validateOnSubmit) {
				$form.find(':submit').live('mouseup keyup', function () {
					$form.data('submitObject', $(this));
				});
				var validated = false;
				$form.submit(function () {
					if (validated) {
						return true;
					}
					if (settings.timer !== undefined) {
						clearTimeout(settings.timer);
					}
					settings.submitting = true;
					if (settings.beforeValidate === undefined || settings.beforeValidate($form)) {
						$.fn.yiiactiveform.validate($form, function (data) {
							var hasError = false;
							$.each(settings.attributes, function () {
								hasError = $.fn.yiiactiveform.updateInput(this, data, $form) || hasError;
							});
							$.fn.yiiactiveform.updateSummary($form, data);
							if (settings.afterValidate === undefined || settings.afterValidate($form, data, hasError)) {
								if (!hasError) {
									validated = true;
									var $button = $form.data('submitObject') || $form.find(':submit:first');
									// TODO: if the submission is caused by "change" event, it will not work
									if ($button.length) {
										$button.click();
									} else {  // no submit button in the form
										$form.submit();
									}
									return;
								}
							}
							settings.submitting = false;
						});
					}
					else {
						settings.submitting = false;
					}
					return false;
				});
			}

			/*
			 * In case of reseting the form we need to reset error messages
			 * NOTE1: $form.reset - does not exist
			 * NOTE2: $form.live('reset', ...) does not work
			 */
			$form.bind('reset', function () {
				/*
				 * because we bind directly to a form reset event, not to a reset button (that could or could not exist),
				 * when this function is executed form elements values have not been reset yet,
				 * because of that we use the setTimeout
				 */
				setTimeout(function () {
					$.each(settings.attributes, function () {
						this.status = 0;
						var $error = $('#' + this.errorID, $form),
							$container = $.fn.yiiactiveform.getInputContainer(this, $form);

						$container.removeClass(
							this.validatingCssClass + ' ' +
							this.errorCssClass + ' ' +
							this.successCssClass
						);

						$error.html('').hide();

						/*
						 * without the setTimeout() we would get here the current entered value before the reset instead of the reseted value
						 */
						this.value = getAFValue($('#' + this.inputID, $form));
					});
					/*
					 * If the form is submited (non ajax) with errors, labels and input gets the class 'error'
					 */
					$('label, input', $form).each(function () {
						$(this).removeClass('error');
					});
					$('#' + settings.summaryID + ' ul').html('');
					$('#' + settings.summaryID).hide();
					//.. set to initial focus on reset
					if (settings.focus !== undefined && !window.location.hash) {
						$(settings.focus).focus();
					}
				}, 1);
			});

			/*
			 * set to initial focus
			 */
			if (settings.focus !== undefined && !window.location.hash) {
				$(settings.focus).focus();
			}
		});
	};

	/**
	 * Returns the container element of the specified attribute.
	 * @param attribute object the configuration for a particular attribute.
	 * @param form the form jQuery object
	 * @return jquery the jquery representation of the container
	 */
	$.fn.yiiactiveform.getInputContainer = function (attribute, form) {
		if (attribute.inputContainer === undefined) {
			return $('#' + attribute.inputID, form).closest('div');
		} else {
			return $(attribute.inputContainer).filter(':has("#' + attribute.inputID + '")');
		}
	};

	/**
	 * updates the error message and the input container for a particular attribute.
	 * @param attribute object the configuration for a particular attribute.
	 * @param messages array the json data obtained from the ajax validation request
	 * @param form the form jQuery object
	 * @return boolean whether there is a validation error for the specified attribute
	 */
	$.fn.yiiactiveform.updateInput = function (attribute, messages, form) {
		attribute.status = 1;
		var hasError = messages !== null && $.isArray(messages[attribute.id]) && messages[attribute.id].length > 0,
			$error = $('#' + attribute.errorID, form),
			$container = $.fn.yiiactiveform.getInputContainer(attribute, form);

		$container.removeClass(
			attribute.validatingCssClass + ' ' +
			attribute.errorCssClass + ' ' +
			attribute.successCssClass
		);

		if (hasError) {
			$error.html(messages[attribute.id][0]);
			$container.addClass(attribute.errorCssClass);
		}
		else if (attribute.enableAjaxValidation || attribute.clientValidation) {
			$container.addClass(attribute.successCssClass);
		}
		if (!attribute.hideErrorMessage) {
			$error.toggle(hasError);
		}

		attribute.value = getAFValue($('#' + attribute.inputID, form));
		return hasError;
	};

	/**
	 * updates the error summary, if any.
	 * @param form jquery the jquery representation of the form
	 * @param messages array the json data obtained from the ajax validation request
	 */
	$.fn.yiiactiveform.updateSummary = function (form, messages) {
		var settings = $(form).data('settings'),
			content = '';
		if (settings.summaryID === undefined) {
			return;
		}
		$.each(settings.attributes, function () {
			if (messages && $.isArray(messages[this.id])) {
				$.each(messages[this.id], function (j, message) {
					content = content + '<li>' + message + '</li>';
				});
			}
		});
		$('#' + settings.summaryID + ' ul').html(content);
		$('#' + settings.summaryID).toggle(content !== '');
	};

	/**
	 * Performs the ajax validation request.
	 * This method is invoked internally to trigger the ajax validation.
	 * @param form jquery the jquery representation of the form
	 * @param successCallback function the function to be invoked if the ajax request succeeds
	 * @param errorCallback function the function to be invoked if the ajax request fails
	 */
	$.fn.yiiactiveform.validate = function (form, successCallback, errorCallback) {
		var $form = $(form),
			settings = $form.data('settings'),
			needAjaxValidation = false,
			messages = {};
		$.each(settings.attributes, function () {
			var value,
				msg = [];
			if (this.clientValidation !== undefined && (settings.submitting || this.status === 2 || this.status === 3)) {
				value = getAFValue($('#' + this.inputID, $form));
				this.clientValidation(value, msg, this);
				if (msg.length) {
					messages[this.id] = msg;
				}
			}
			if (this.enableAjaxValidation && !msg.length && (settings.submitting || this.status === 2 || this.status === 3)) {
				needAjaxValidation = true;
			}
		});

		if (!needAjaxValidation || settings.submitting && !$.isEmptyObject(messages)) {
			if (settings.submitting) {
				// delay callback so that the form can be submitted without problem
				setTimeout(function () {
					successCallback(messages);
				}, 200);
			}
			else {
				successCallback(messages);
			}
			return;
		}

		var $button = $form.data('submitObject'),
			extData = '&' + settings.ajaxVar + '=' + $form.attr('id');
		if ($button && $button.length) {
			extData += '&' + $button.attr('name') + '=' + $button.attr('value');
		}

		$.ajax({
			url : settings.validationUrl,
			type : $form.attr('method'),
			data : $form.serialize() + extData,
			dataType : 'json',
			success : function (data) {
				if (data !== null && typeof data === 'object') {
					$.each(settings.attributes, function () {
						if (!this.enableAjaxValidation) {
							delete data[this.id];
						}
					});
					successCallback($.extend({}, messages, data));
				}
				else {
					successCallback(messages);
				}
			},
			error : function () {
				if (errorCallback !== undefined) {
					errorCallback();
				}
			}
		});
	};

	/**
	 * Returns the configuration for the specified form.
	 * The configuration contains all needed information to perform ajax-based validation.
	 * @param form jquery the jquery representation of the form
	 * @return object the configuration for the specified form.
	 */
	$.fn.yiiactiveform.getSettings = function (form) {
		return $(form).data('settings');
	};

	$.fn.yiiactiveform.defaults = {
		ajaxVar: 'ajax',
		validationUrl: undefined,
		validationDelay: 200,
		validateOnSubmit : false,
		validateOnChange : true,
		validateOnType : false,
		hideErrorMessage : false,
		inputContainer : undefined,
		errorCssClass : 'error',
		successCssClass : 'success',
		validatingCssClass : 'validating',
		summaryID : undefined,
		timer: undefined,
		beforeValidateAttribute: undefined, // function (form, attribute) : boolean
		afterValidateAttribute: undefined,  // function (form, attribute, data, hasError)
		beforeValidate: undefined, // function (form) : boolean
		afterValidate: undefined,  // function (form, data, hasError) : boolean
		/**
		 * list of attributes to be validated. Each array element is of the following structure:
		 * {
		 *     id : 'ModelClass_attribute', // the unique attribute ID
		 *     model : 'ModelClass', // the model class name
		 *     name : 'name', // attribute name
		 *     inputID : 'input-tag-id',
		 *     errorID : 'error-tag-id',
		 *     value : undefined,
		 *     status : 0,  // 0: empty, not entered before,  1: validated, 2: pending validation, 3: validating
		 *     focus : undefined,  // jquery selector that indicates which element to receive input focus initially
		 *     validationDelay: 200,
		 *     validateOnChange : true,
		 *     validateOnType : false,
		 *     hideErrorMessage : false,
		 *     inputContainer : undefined,
		 *     errorCssClass : 'error',
		 *     successCssClass : 'success',
		 *     validatingCssClass : 'validating',
		 *     enableAjaxValidation : true,
		 *     enableClientValidation : true,
		 *     clientValidation : undefined, // function (value, messages, attribute) : client-side validation
		 *     beforeValidateAttribute: undefined, // function (form, attribute) : boolean
		 *     afterValidateAttribute: undefined,  // function (form, attribute, data, hasError)
		 * }
		 */
		attributes : []
	};
})(jQuery);<commit_msg>jquery.yiiactiveform.js - optimizations<commit_after>/**
 * jQuery yiiactiveform plugin file.
 *
 * @author Qiang Xue <qiang.xue@gmail.com>
 * @link http://www.yiiframework.com/
 * @copyright Copyright © 2008-2010 Yii Software LLC
 * @license http://www.yiiframework.com/license/
 * @version $Id$
 * @since 1.1.1
 */

(function ($) {
	/*
	 * returns the value of the CActiveForm input field
	 * performs additional checks to get proper values for checkbox / radiobutton / checkBoxList / radioButtonList
	 * @param o object the jQuery object of the input element
	 */
	var getAFValue = function (o) {
		var type = o.attr('type');
		if(o[0].tagName.toLowerCase()=='span') {
			var c = [];
			o.find(':checked').each(function () {
				c.push(this.value);
			});
			return c.join(',');
		}
		if (type === 'checkbox' || type === 'radio') {
			return o.filter(':checked').val();
		} else {
			return o.val();
		}
	};

	/**
	 * yiiactiveform set function.
	 * @param options map settings for the active form plugin. Please see {@link CActiveForm::options} for availablel options.
	 */
	$.fn.yiiactiveform = function (options) {
		return this.each(function () {
			var settings = $.extend({}, $.fn.yiiactiveform.defaults, options || {}),
				$form = $(this);

			if (settings.validationUrl === undefined) {
				settings.validationUrl = $form.attr('action');
			}
			$.each(settings.attributes, function () {
				$.extend(this, {
					validationDelay : settings.validationDelay,
					validateOnChange : settings.validateOnChange,
					validateOnType : settings.validateOnType,
					hideErrorMessage : settings.hideErrorMessage,
					inputContainer : settings.inputContainer,
					errorCssClass : settings.errorCssClass,
					successCssClass : settings.successCssClass,
					beforeValidateAttribute : settings.beforeValidateAttribute,
					afterValidateAttribute : settings.afterValidateAttribute,
					validatingCssClass : settings.validatingCssClass
				});
				this.value = getAFValue($form.find('#' + this.inputID));
			});
			$form.data('settings', settings);

			settings.submitting = false;  // whether it is waiting for ajax submission result
			var validate = function (attribute) {
				var changed = false;
				$.each(settings.attributes, function () {
					if (this.value !== getAFValue($form.find('#' + this.inputID))) {
						this.status = 2;
						changed = true;
					}
				});
				if (!changed) {
					return;
				}

				if (settings.timer !== undefined) {
					clearTimeout(settings.timer);
				}
				settings.timer = setTimeout(function () {
					if (settings.submitting || $form.is(':hidden')) {
						return;
					}
					if (attribute.beforeValidateAttribute === undefined || attribute.beforeValidateAttribute($form, attribute)) {
						$.each(settings.attributes, function () {
							if (this.status === 2) {
								this.status = 3;
								$.fn.yiiactiveform.getInputContainer(this, $form).addClass(this.validatingCssClass);
							}
						});
						$.fn.yiiactiveform.validate($form, function (data) {
							var hasError = false;
							$.each(settings.attributes, function () {
								if (this.status === 2 || this.status === 3) {
									hasError = $.fn.yiiactiveform.updateInput(this, data, $form) || hasError;
								}
							});
							if (attribute.afterValidateAttribute !== undefined) {
								attribute.afterValidateAttribute($form, attribute, data, hasError);
							}
						});
					}
				}, attribute.validationDelay);
			};

			$.each(settings.attributes, function () {
				if (this.validateOnChange) {
					$form.find('#' + this.inputID).change(function () {
						validate(this);
					}).blur(function () {
						if (this.status !== 2 && this.status !== 3) {
							validate(this);
						}
					});
				}
				if (this.validateOnType) {
					$form.find('#' + this.inputID).keyup(function () {
						if (this.value !== getAFValue($(this))) {
							validate(this);
						}
					});
				}
			});

			if (settings.validateOnSubmit) {
				$form.find(':submit').live('mouseup keyup', function () {
					$form.data('submitObject', $(this));
				});
				var validated = false;
				$form.submit(function () {
					if (validated) {
						return true;
					}
					if (settings.timer !== undefined) {
						clearTimeout(settings.timer);
					}
					settings.submitting = true;
					if (settings.beforeValidate === undefined || settings.beforeValidate($form)) {
						$.fn.yiiactiveform.validate($form, function (data) {
							var hasError = false;
							$.each(settings.attributes, function () {
								hasError = $.fn.yiiactiveform.updateInput(this, data, $form) || hasError;
							});
							$.fn.yiiactiveform.updateSummary($form, data);
							if (settings.afterValidate === undefined || settings.afterValidate($form, data, hasError)) {
								if (!hasError) {
									validated = true;
									var $button = $form.data('submitObject') || $form.find(':submit:first');
									// TODO: if the submission is caused by "change" event, it will not work
									if ($button.length) {
										$button.click();
									} else {  // no submit button in the form
										$form.submit();
									}
									return;
								}
							}
							settings.submitting = false;
						});
					}
					else {
						settings.submitting = false;
					}
					return false;
				});
			}

			/*
			 * In case of reseting the form we need to reset error messages
			 * NOTE1: $form.reset - does not exist
			 * NOTE2: $form.live('reset', ...) does not work
			 */
			$form.bind('reset', function () {
				/*
				 * because we bind directly to a form reset event, not to a reset button (that could or could not exist),
				 * when this function is executed form elements values have not been reset yet,
				 * because of that we use the setTimeout
				 */
				setTimeout(function () {
					$.each(settings.attributes, function () {
						this.status = 0;
						var $error = $form.find('#' + this.errorID),
							$container = $.fn.yiiactiveform.getInputContainer(this, $form);

						$container.removeClass(
							this.validatingCssClass + ' ' +
							this.errorCssClass + ' ' +
							this.successCssClass
						);

						$error.html('').hide();

						/*
						 * without the setTimeout() we would get here the current entered value before the reset instead of the reseted value
						 */
						this.value = getAFValue($form.find('#' + this.inputID));
					});
					/*
					 * If the form is submited (non ajax) with errors, labels and input gets the class 'error'
					 */
					$form.find('label, input').each(function () {
						$(this).removeClass('error');
					});
					$('#' + settings.summaryID).hide().find('ul').html('');
					//.. set to initial focus on reset
					if (settings.focus !== undefined && !window.location.hash) {
						$form.find(settings.focus).focus();
					}
				}, 1);
			});

			/*
			 * set to initial focus
			 */
			if (settings.focus !== undefined && !window.location.hash) {
				$form.find(settings.focus).focus();
			}
		});
	};

	/**
	 * Returns the container element of the specified attribute.
	 * @param attribute object the configuration for a particular attribute.
	 * @param form the form jQuery object
	 * @return jquery the jquery representation of the container
	 */
	$.fn.yiiactiveform.getInputContainer = function (attribute, form) {
		if (attribute.inputContainer === undefined) {
			return form.find('#' + attribute.inputID).closest('div');
		} else {
			return form.find(attribute.inputContainer).filter(':has("#' + attribute.inputID + '")');
		}
	};

	/**
	 * updates the error message and the input container for a particular attribute.
	 * @param attribute object the configuration for a particular attribute.
	 * @param messages array the json data obtained from the ajax validation request
	 * @param form the form jQuery object
	 * @return boolean whether there is a validation error for the specified attribute
	 */
	$.fn.yiiactiveform.updateInput = function (attribute, messages, form) {
		attribute.status = 1;
		var hasError = messages !== null && $.isArray(messages[attribute.id]) && messages[attribute.id].length > 0,
			$error = form.find('#' + attribute.errorID),
			$container = $.fn.yiiactiveform.getInputContainer(attribute, form);

		$container.removeClass(
			attribute.validatingCssClass + ' ' +
			attribute.errorCssClass + ' ' +
			attribute.successCssClass
		);

		if (hasError) {
			$error.html(messages[attribute.id][0]);
			$container.addClass(attribute.errorCssClass);
		}
		else if (attribute.enableAjaxValidation || attribute.clientValidation) {
			$container.addClass(attribute.successCssClass);
		}
		if (!attribute.hideErrorMessage) {
			$error.toggle(hasError);
		}

		attribute.value = getAFValue(form.find('#' + attribute.inputID));
		return hasError;
	};

	/**
	 * updates the error summary, if any.
	 * @param form jquery the jquery representation of the form
	 * @param messages array the json data obtained from the ajax validation request
	 */
	$.fn.yiiactiveform.updateSummary = function (form, messages) {
		var settings = $(form).data('settings'),
			content = '';
		if (settings.summaryID === undefined) {
			return;
		}
		$.each(settings.attributes, function () {
			if (messages && $.isArray(messages[this.id])) {
				$.each(messages[this.id], function (j, message) {
					content = content + '<li>' + message + '</li>';
				});
			}
		});
		$('#' + settings.summaryID).toggle(content !== '').find('ul').html(content);
	};

	/**
	 * Performs the ajax validation request.
	 * This method is invoked internally to trigger the ajax validation.
	 * @param form jquery the jquery representation of the form
	 * @param successCallback function the function to be invoked if the ajax request succeeds
	 * @param errorCallback function the function to be invoked if the ajax request fails
	 */
	$.fn.yiiactiveform.validate = function (form, successCallback, errorCallback) {
		var $form = $(form),
			settings = $form.data('settings'),
			needAjaxValidation = false,
			messages = {};
		$.each(settings.attributes, function () {
			var value,
				msg = [];
			if (this.clientValidation !== undefined && (settings.submitting || this.status === 2 || this.status === 3)) {
				value = getAFValue($form.find('#' + this.inputID));
				this.clientValidation(value, msg, this);
				if (msg.length) {
					messages[this.id] = msg;
				}
			}
			if (this.enableAjaxValidation && !msg.length && (settings.submitting || this.status === 2 || this.status === 3)) {
				needAjaxValidation = true;
			}
		});

		if (!needAjaxValidation || settings.submitting && !$.isEmptyObject(messages)) {
			if (settings.submitting) {
				// delay callback so that the form can be submitted without problem
				setTimeout(function () {
					successCallback(messages);
				}, 200);
			}
			else {
				successCallback(messages);
			}
			return;
		}

		var $button = $form.data('submitObject'),
			extData = '&' + settings.ajaxVar + '=' + $form.attr('id');
		if ($button && $button.length) {
			extData += '&' + $button.attr('name') + '=' + $button.attr('value');
		}

		$.ajax({
			url : settings.validationUrl,
			type : $form.attr('method'),
			data : $form.serialize() + extData,
			dataType : 'json',
			success : function (data) {
				if (data !== null && typeof data === 'object') {
					$.each(settings.attributes, function () {
						if (!this.enableAjaxValidation) {
							delete data[this.id];
						}
					});
					successCallback($.extend({}, messages, data));
				}
				else {
					successCallback(messages);
				}
			},
			error : function () {
				if (errorCallback !== undefined) {
					errorCallback();
				}
			}
		});
	};

	/**
	 * Returns the configuration for the specified form.
	 * The configuration contains all needed information to perform ajax-based validation.
	 * @param form jquery the jquery representation of the form
	 * @return object the configuration for the specified form.
	 */
	$.fn.yiiactiveform.getSettings = function (form) {
		return $(form).data('settings');
	};

	$.fn.yiiactiveform.defaults = {
		ajaxVar: 'ajax',
		validationUrl: undefined,
		validationDelay: 200,
		validateOnSubmit : false,
		validateOnChange : true,
		validateOnType : false,
		hideErrorMessage : false,
		inputContainer : undefined,
		errorCssClass : 'error',
		successCssClass : 'success',
		validatingCssClass : 'validating',
		summaryID : undefined,
		timer: undefined,
		beforeValidateAttribute: undefined, // function (form, attribute) : boolean
		afterValidateAttribute: undefined,  // function (form, attribute, data, hasError)
		beforeValidate: undefined, // function (form) : boolean
		afterValidate: undefined,  // function (form, data, hasError) : boolean
		/**
		 * list of attributes to be validated. Each array element is of the following structure:
		 * {
		 *     id : 'ModelClass_attribute', // the unique attribute ID
		 *     model : 'ModelClass', // the model class name
		 *     name : 'name', // attribute name
		 *     inputID : 'input-tag-id',
		 *     errorID : 'error-tag-id',
		 *     value : undefined,
		 *     status : 0,  // 0: empty, not entered before,  1: validated, 2: pending validation, 3: validating
		 *     focus : undefined,  // jquery selector that indicates which element to receive input focus initially
		 *     validationDelay: 200,
		 *     validateOnChange : true,
		 *     validateOnType : false,
		 *     hideErrorMessage : false,
		 *     inputContainer : undefined,
		 *     errorCssClass : 'error',
		 *     successCssClass : 'success',
		 *     validatingCssClass : 'validating',
		 *     enableAjaxValidation : true,
		 *     enableClientValidation : true,
		 *     clientValidation : undefined, // function (value, messages, attribute) : client-side validation
		 *     beforeValidateAttribute: undefined, // function (form, attribute) : boolean
		 *     afterValidateAttribute: undefined,  // function (form, attribute, data, hasError)
		 * }
		 */
		attributes : []
	};
})(jQuery);<|endoftext|>


<commit_before>'use strict';

/* eslint-disable no-unused-vars */

const Assert = require('chai').assert;
const request = require('../support/request');
const sdapi = require('../support/sdapi');
const { defineSupportCode } = require('cucumber');

const TIMEOUT = 240 * 1000;

defineSupportCode(({ Before, Given, When, Then }) => {
    Before({
        tags: '@sd-step'
    }, function hook() {
        this.repoOrg = this.testOrg;
        this.repoName = 'functional-shared-steps';
        this.pipelineId = null;
        this.jwt = null;
        this.image = null;
        this.expectedImage = null;
        this.commands = null;
    });

    Given(/^an existing pipeline with (.*) image and (.*) package$/,
        { timeout: TIMEOUT }, function step(image, pkg) {
            return this.getJwt(this.apiToken)
                .then((response) => {
                    this.jwt = response.body.token;
                    this.expectedImage = image;

                    return request({
                        uri: `${this.instance}/${this.namespace}/pipelines`,
                        method: 'POST',
                        auth: {
                            bearer: this.jwt
                        },
                        body: {
                            checkoutUrl:
                                `git@${this.scmHostname}:${this.repoOrg}/${this.repoName}`
                                    + '.git#master'
                        },
                        json: true
                    });
                })
                .then((response) => {
                    Assert.oneOf(response.statusCode, [409, 201]);

                    if (response.statusCode === 201) {
                        this.pipelineId = response.body.id;
                    } else {
                        const str = response.body.message;
                        const id = str.split(': ')[1];

                        this.pipelineId = id;
                    }
                });
        });

    When(/^the (main|tilde|hat|specify) job is started$/,
        { timeout: TIMEOUT }, function step(jobName) {
            return request({
                uri: `${this.instance}/${this.namespace}/pipelines/${this.pipelineId}/jobs`,
                method: 'GET',
                json: true,
                auth: {
                    bearer: this.jwt
                }
            })
                .then((response) => {
                    Assert.equal(response.statusCode, 200);

                    for (let i = 0; i < response.body.length; i += 1) {
                        if (response.body[i].name === jobName) {
                            this.jobId = response.body[i].id;
                            this.image = response.body[i].permutations[0].image;
                            this.commands = response.body[i].permutations[0].commands;
                            break;
                        }
                    }
                    Assert.equal(this.image, this.expectedImage);
                })
                .then(() =>
                    request({
                        uri: `${this.instance}/${this.namespace}/builds`,
                        method: 'POST',
                        body: {
                            jobId: this.jobId
                        },
                        auth: {
                            bearer: this.jwt
                        },
                        json: true
                    }).then((resp) => {
                        Assert.equal(resp.statusCode, 201);

                        this.buildId = resp.body.id;
                    })
                );
        });

    When(/^sd-step command is executed to use (.*) package$/,
        { timeout: TIMEOUT }, function step(pkg) {
            this.commands.forEach((c) => {
                if (c.name === 'sd_step') {
                    Assert.include(c.command, pkg);
                } else if (c.name.match(/^sd_step_/)) {
                    Assert.include(c.command, '--pkg-version');
                }
            });
        });

    When(/^sd-step command is executed to use (.*) package with specified version (.*)$/, {
        timeout: TIMEOUT
    }, function step(pkg, version) {
        this.commands.forEach((c) => {
            if (c.name === 'sd_step') {
                Assert.include(c.command, `--pkg-version "${version}" ${pkg}`);
            }
        });
    });

    Then(/^(.*) package is available via sd-step$/, { timeout: 500 * 1000 }, function step(pkg) {
        return this.waitForBuild(this.buildId).then((response) => {
            Assert.equal(response.statusCode, 200);
            Assert.equal(response.body.status, 'SUCCESS');
        });
    });

    Then(/^(.*) package is available via sd-step with specified version (.*)$/, {
        timeout: TIMEOUT
    }, function step(pkg, version) {
        return this.waitForBuild(this.buildId).then((response) => {
            Assert.equal(response.statusCode, 200);
            Assert.equal(response.body.status, 'SUCCESS');
        });
    });
});
<commit_msg>fix: increase timeout (#1051)<commit_after>'use strict';

/* eslint-disable no-unused-vars */

const Assert = require('chai').assert;
const request = require('../support/request');
const sdapi = require('../support/sdapi');
const { defineSupportCode } = require('cucumber');

const TIMEOUT = 240 * 1000;

defineSupportCode(({ Before, Given, When, Then }) => {
    Before({
        tags: '@sd-step'
    }, function hook() {
        this.repoOrg = this.testOrg;
        this.repoName = 'functional-shared-steps';
        this.pipelineId = null;
        this.jwt = null;
        this.image = null;
        this.expectedImage = null;
        this.commands = null;
    });

    Given(/^an existing pipeline with (.*) image and (.*) package$/,
        { timeout: TIMEOUT }, function step(image, pkg) {
            return this.getJwt(this.apiToken)
                .then((response) => {
                    this.jwt = response.body.token;
                    this.expectedImage = image;

                    return request({
                        uri: `${this.instance}/${this.namespace}/pipelines`,
                        method: 'POST',
                        auth: {
                            bearer: this.jwt
                        },
                        body: {
                            checkoutUrl:
                                `git@${this.scmHostname}:${this.repoOrg}/${this.repoName}`
                                    + '.git#master'
                        },
                        json: true
                    });
                })
                .then((response) => {
                    Assert.oneOf(response.statusCode, [409, 201]);

                    if (response.statusCode === 201) {
                        this.pipelineId = response.body.id;
                    } else {
                        const str = response.body.message;
                        const id = str.split(': ')[1];

                        this.pipelineId = id;
                    }
                });
        });

    When(/^the (main|tilde|hat|specify) job is started$/,
        { timeout: TIMEOUT }, function step(jobName) {
            return request({
                uri: `${this.instance}/${this.namespace}/pipelines/${this.pipelineId}/jobs`,
                method: 'GET',
                json: true,
                auth: {
                    bearer: this.jwt
                }
            })
                .then((response) => {
                    Assert.equal(response.statusCode, 200);

                    for (let i = 0; i < response.body.length; i += 1) {
                        if (response.body[i].name === jobName) {
                            this.jobId = response.body[i].id;
                            this.image = response.body[i].permutations[0].image;
                            this.commands = response.body[i].permutations[0].commands;
                            break;
                        }
                    }
                    Assert.equal(this.image, this.expectedImage);
                })
                .then(() =>
                    request({
                        uri: `${this.instance}/${this.namespace}/builds`,
                        method: 'POST',
                        body: {
                            jobId: this.jobId
                        },
                        auth: {
                            bearer: this.jwt
                        },
                        json: true
                    }).then((resp) => {
                        Assert.equal(resp.statusCode, 201);

                        this.buildId = resp.body.id;
                    })
                );
        });

    When(/^sd-step command is executed to use (.*) package$/,
        { timeout: TIMEOUT }, function step(pkg) {
            this.commands.forEach((c) => {
                if (c.name === 'sd_step') {
                    Assert.include(c.command, pkg);
                } else if (c.name.match(/^sd_step_/)) {
                    Assert.include(c.command, '--pkg-version');
                }
            });
        });

    When(/^sd-step command is executed to use (.*) package with specified version (.*)$/, {
        timeout: TIMEOUT
    }, function step(pkg, version) {
        this.commands.forEach((c) => {
            if (c.name === 'sd_step') {
                Assert.include(c.command, `--pkg-version "${version}" ${pkg}`);
            }
        });
    });

    Then(/^(.*) package is available via sd-step$/, { timeout: 700 * 1000 }, function step(pkg) {
        return this.waitForBuild(this.buildId).then((response) => {
            Assert.equal(response.statusCode, 200);
            Assert.equal(response.body.status, 'SUCCESS');
        });
    });

    Then(/^(.*) package is available via sd-step with specified version (.*)$/, {
        timeout: TIMEOUT
    }, function step(pkg, version) {
        return this.waitForBuild(this.buildId).then((response) => {
            Assert.equal(response.statusCode, 200);
            Assert.equal(response.body.status, 'SUCCESS');
        });
    });
});
<|endoftext|>


<commit_before>/*jslint continue: true, devel: true, evil: true, indent: 2, nomen: true, plusplus: true, regexp: true, rhino: true, sloppy: true, sub: true, unparam: true, vars: true, white: true */
/*global _, HostAdapter, hostAdapter */

function pad(num, length, def) {
  'use strict';
  return _('' + (num || def)).pad(length, '0');
}

function generateResults(recognitionResults, q, context) {
  'use strict';

  var recognitionResult = recognitionResults['com.solveforall.recognition.date.DateRange'];

  if (!recognitionResult || (recognitionResult.length === 0)) {
    console.warn("No recognition result found");
    return [];
  }

  var dateRange = recognitionResult[0];
  var start = dateRange.start;

  if (!start) {
    console.warn("No start date found");
    return [];
  }

  var now = new Date();
  var paddedMonth = pad(start.month, 2, now.getMonth() + 1);
  var paddedDay = pad(start.dayOfMonth, 2, now.getDate());
  var year = '' + (start.year || now.getFullYear());

  return [{
    label: 'Calendar',
    iconUrl: 'http://calendar.google.com/googlecalendar/images/favicon_v2010_8.ico',
    summaryHtml: 'Google Calendar',
    uri: 'https://www.google.com/calendar/render?tab=mc&date=' + year +
      paddedMonth + paddedDay,
    embeddable: false,
    relevance: dateRange.recognitionLevel
  }];
}<commit_msg>Make Google Calendar Answer Generator eligible to be a Quick Link<commit_after>/*jslint continue: true, devel: true, evil: true, indent: 2, nomen: true, plusplus: true, regexp: true, rhino: true, sloppy: true, sub: true, unparam: true, vars: true, white: true */
/*global _, HostAdapter, hostAdapter */

function pad(num, length, def) {
  'use strict';
  return _('' + (num || def)).pad(length, '0');
}

function generateResults(recognitionResults, q, context) {
  'use strict';

  var recognitionResult = recognitionResults['com.solveforall.recognition.date.DateRange'];

  if (!recognitionResult || (recognitionResult.length === 0)) {
    console.warn("No recognition result found");
    return [];
  }

  var dateRange = recognitionResult[0];
  var start = dateRange.start;

  if (!start) {
    console.warn("No start date found");
    return [];
  }

  var now = new Date();
  var paddedMonth = pad(start.month, 2, now.getMonth() + 1);
  var paddedDay = pad(start.dayOfMonth, 2, now.getDate());
  var year = '' + (start.year || now.getFullYear());

  return [{
    label: 'Google Calendar',
    iconUrl: 'http://calendar.google.com/googlecalendar/images/favicon_v2010_8.ico',
    tooltip: 'View a date in Google Calendar',
    uri: 'https://www.google.com/calendar/render?tab=mc&date=' + year +
      paddedMonth + paddedDay,
    embeddable: false,
    relevance: dateRange.recognitionLevel
  }];
}<|endoftext|>