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

// Provides control sap.m.ObjectIdentifier.
sap.ui.define([
	'./library',
	'./Link',
	'./Text',
	'sap/ui/core/Control',
	'sap/ui/core/IconPool',
	'sap/ui/core/InvisibleText',
	'sap/ui/core/library',
	'sap/ui/Device',
	'sap/ui/base/ManagedObject',
	'./ObjectIdentifierRenderer',
	"sap/ui/events/KeyCodes"
],
function(
	library,
	Link,
	Text,
	Control,
	IconPool,
	InvisibleText,
	coreLibrary,
	Device,
	ManagedObject,
	ObjectIdentifierRenderer,
	KeyCodes
	) {
	"use strict";

	// shortcut for sap.ui.core.TextDirection
	var TextDirection = coreLibrary.TextDirection;

	// shortcut for sap.m.EmptyIndicator
	var EmptyIndicatorMode = library.EmptyIndicatorMode;

	/**
	 * Constructor for a new ObjectIdentifier.
	 *
	 * @param {string} [sId] ID for the new control, generated automatically if no ID is given
	 * @param {object} [mSettings] Initial settings for the new control
	 *
	 * @class
	 * The ObjectIdentifier is a display control that enables the user to easily identify a specific object. The ObjectIdentifier title is the key identifier of the object and additional text can be used to further distinguish it from other objects.
	 *
     * Note: This control should not be used with {@link sap.m.Label} or in Forms along with {@link sap.m.Label}.
	 * @extends sap.ui.core.Control
	 * @version ${version}
	 *
	 * @constructor
	 * @public
	 * @since 1.12
	 * @alias sap.m.ObjectIdentifier
	 * @see {@link fiori:https://experience.sap.com/fiori-design-web/object-display-elements/#-object-status Object Identifier}
	 * @ui5-metamodel This control/element also will be described in the UI5 (legacy) designtime metamodel
	 */
	var ObjectIdentifier = Control.extend("sap.m.ObjectIdentifier", /** @lends sap.m.ObjectIdentifier.prototype */ { metadata : {

		library : "sap.m",
		designtime: "sap/m/designtime/ObjectIdentifier.designtime",
		properties : {

			/**
			 * Defines the object title.
			 */
			title : {type : "string", group : "Misc", defaultValue : null},

			/**
			 * Defines the object text.
			 */
			text : {type : "string", group : "Misc", defaultValue : null},

			/**
			 * Indicates whether or not the notes icon is displayed.
			 * @deprecated as of version 1.24.0. There is no replacement for the moment.
			 */
			badgeNotes : {type : "boolean", group : "Misc", defaultValue : null, deprecated: true},

			/**
			 * Indicates whether or not the address book icon is displayed.
			 * @deprecated as of version 1.24.0. There is no replacement for the moment.
			 */
			badgePeople : {type : "boolean", group : "Misc", defaultValue : null, deprecated: true},

			/**
			 * Indicates whether or not the attachments icon is displayed.
			 * @deprecated as of version 1.24.0. There is no replacement for the moment.
			 */
			badgeAttachments : {type : "boolean", group : "Misc", defaultValue : null, deprecated: true},

			/**
			 * Indicates if the ObjectIdentifier is visible. An invisible ObjectIdentifier is not being rendered.
			 */
			visible : {type : "boolean", group : "Appearance", defaultValue : true},

			/**
			 * Indicates if the ObjectIdentifier's title is clickable.
			 * @since 1.26
			 */
			titleActive : {type : "boolean", group : "Misc", defaultValue : false},

			/**
			 * Specifies the element's text directionality with enumerated options. By default, the control inherits text direction from the DOM.
			 * @since 1.28.0
			 */
			textDirection : {type : "sap.ui.core.TextDirection", group : "Appearance", defaultValue : TextDirection.Inherit},

			/**
			 * Specifies if an empty indicator should be displayed when there is no text.
			 *
			 * @since 1.89
			 */
			emptyIndicatorMode: { type: "sap.m.EmptyIndicatorMode", group: "Appearance", defaultValue: EmptyIndicatorMode.Off }
		},
		aggregations : {

			/**
			 * Control to display the object title (can be either Text or Link).
			 *
			 * @private
			 */
			_titleControl : {type : "sap.ui.core.Control", multiple : false, visibility : "hidden"},

			/**
			 * Text control to display the object text.
			 *
			 * @private
			 */
			_textControl : {type : "sap.ui.core.Control", multiple : false, visibility : "hidden"}
		},
		events : {

			/**
			 * Fires when the title is active and the user taps/clicks on it.
			 * @since 1.26
			 */
			titlePress : {
				parameters : {

					/**
					 * DOM reference of the object identifier's title.
					 */
					domRef : {type : "object"}
				}
			}
		},
		associations: {
			/**
			 * Association to controls / IDs, which label this control (see WAI-ARIA attribute aria-labelledby).
			 */
			ariaLabelledBy: {type: "sap.ui.core.Control", multiple: true, singularName: "ariaLabelledBy"}
		},
		dnd: { draggable: true, droppable: false }
	}});

	/**
	 * Initializes the control
	 *
	 * @private
	 */
	ObjectIdentifier.prototype.init = function() {
		var oLibraryResourceBundle = sap.ui.getCore().getLibraryResourceBundle("sap.m");

		if (sap.ui.getCore().getConfiguration().getAccessibility()) {
			ObjectIdentifier.OI_ARIA_ROLE = oLibraryResourceBundle.getText("OI_ARIA_ROLE");
		}
	};

	/**
	 * Called when the control is destroyed.
	 *
	 * @private
	 */
	ObjectIdentifier.prototype.exit = function() {

		if (this._attachmentsIcon) {
			this._attachmentsIcon.destroy();
			this._attachmentsIcon = null;
		}

		if (this._peopleIcon) {
			this._peopleIcon.destroy();
			this._peopleIcon = null;
		}

		if (this._notesIcon) {
			this._notesIcon.destroy();
			this._notesIcon = null;
		}
	};

	/**
	 * Lazy loads attachments icon.
	 * @returns {object} The attachments icon
	 * @private
	 */
	ObjectIdentifier.prototype._getAttachmentsIcon = function() {

		if (!this._attachmentsIcon) {
			this._attachmentsIcon = this._getIcon(IconPool.getIconURI("attachment"), this.getId() + "-attachments");
		}

		return this._attachmentsIcon;
	};

	/**
	 * Lazy loads people icon.
	 * @returns {object} The people icon
	 * @private
	 */
	ObjectIdentifier.prototype._getPeopleIcon = function() {

		if (!this._peopleIcon) {
			this._peopleIcon = this._getIcon(IconPool.getIconURI("group"), this.getId() + "-people");
		}

		return this._peopleIcon;
	};

	/**
	 * Lazy loads notes icon.
	 * @returns {object} The notes icon
	 * @private
	 */
	ObjectIdentifier.prototype._getNotesIcon = function() {

		if (!this._notesIcon ) {
			this._notesIcon  = this._getIcon(IconPool.getIconURI("notes"), this.getId() + "-notes");
		}

		return this._notesIcon;
	};

	/**
	 * Creates icon image.
	 * @param {string} sURI The URL of the icon image
	 * @param {string} sImageId The ID of the icon image
	 * @returns {object} The icon image
	 * @private
	 */
	ObjectIdentifier.prototype._getIcon = function(sURI, sImageId) {

		var sSize = Device.system.phone ? "1em" : "1em";
		var oImage;

		oImage = this._icon || IconPool.createControlByURI({
			src : sURI,
			id : sImageId + "-icon",
			size : sSize,
			useIconTooltip : false
		}, sap.m.Image);

		oImage.setSrc(sURI);

		return oImage;
	};

	/**
	 * Gets the proper control for the title.
	 * @returns {sap.m.Control} The control for the title
	 * @private
	 */
	ObjectIdentifier.prototype._getTitleControl = function() {
		var oTitleControl = this.getAggregation("_titleControl"),
			sId = this.getId(),
			sTitle = ManagedObject.escapeSettingsValue(this.getProperty("title"));

		if (!oTitleControl) {
			// Lazy initialization
			if (this.getProperty("titleActive")) {
				oTitleControl = new Link({
					id : sId + "-link",
					text: sTitle,
					//Add a custom hidden role "ObjectIdentifier" with hidden text
					ariaLabelledBy: InvisibleText.getStaticId("sap.m", "OI_ARIA_ROLE")
				});
				oTitleControl.addAssociation("ariaLabelledBy", sId + "-text", true);
			} else {
				oTitleControl = new Text({
					id : sId + "-txt",
					text: sTitle
				});
			}
			this.setAggregation("_titleControl", oTitleControl, true);
		}

		return oTitleControl;
	};

	/**
	 * Lazy loads _textControl aggregation.
	 * @returns {sap.m.Control} The control for the text
	 * @private
	 */
	ObjectIdentifier.prototype._getTextControl = function() {

		var oTextControl = this.getAggregation("_textControl");

		if (!oTextControl) {
			oTextControl = new Text({
				text: ManagedObject.escapeSettingsValue(this.getProperty("text"))
			});
			this.setAggregation("_textControl", oTextControl, true);
		}

		oTextControl.setTextDirection(this.getTextDirection());

		return oTextControl;
	};

	/**
	 * Sets the title.
	 * Default value is empty/undefined.
	 * @public
	 * @param {string} sTitle New value for property title
	 * @returns {this} this to allow method chaining
	 */
	ObjectIdentifier.prototype.setTitle = function (sTitle) {
		if (sTitle) {
			this._getTitleControl().setProperty("text", sTitle);
		}

		return this.setProperty("title", sTitle);
	};

	/**
	 * Sets text.
	 * Default value is empty/undefined.
	 * @public
	 * @param {string} sText New value for property text
	 * @returns {this} this to allow method chaining
	 */
	ObjectIdentifier.prototype.setText = function(sText) {
		if (sText) {
			this._getTextControl().setProperty("text", sText);
		}

		return this.setProperty("text", sText);
	};

	/**
	 * Sets property titleActive.
	 * Default value is false.
	 * @public
	 * @param {boolean} bValue new value for property titleActive
	 * @returns {this} this to allow method chaining
	 */
	ObjectIdentifier.prototype.setTitleActive = function(bValue) {
		var bPrevValue = this.getTitleActive();

		this.setProperty("titleActive", bValue);

		if (bPrevValue != bValue) {
			this.destroyAggregation("_titleControl");
			this._getTitleControl();
		}

		return this;
	};

	/**
	 * Function is called when ObjectIdentifier's title is triggered.
	 *
	 * @param {jQuery.Event} oEvent The fired event
	 * @private
	 */
	ObjectIdentifier.prototype._handlePress = function(oEvent) {
		var oClickedItem = oEvent.target;
		if (this.getTitleActive() && this.$("title")[0].firstChild == oClickedItem) { // checking if the title is clicked
			this.fireTitlePress({
				domRef: oClickedItem
			});

			// mark the event that it is handled by the control
			oEvent.setMarked();
		}
	};

	/**
	 * Event handler called when the enter key is pressed.
	 *
	 * @param {jQuery.Event} oEvent The fired event
	 * @private
	 */
	ObjectIdentifier.prototype.onsapenter = function(oEvent) {
		ObjectIdentifier.prototype._handlePress.apply(this, arguments);
	};

	/**
	 * Event handler called when the space key is pressed.
	 *
	 * @param {jQuery.Event} oEvent The fired event
	 * @private
	 */
	ObjectIdentifier.prototype.onkeyup = function(oEvent) {
		if (oEvent && oEvent.which === KeyCodes.SPACE) {
			ObjectIdentifier.prototype._handlePress.apply(this, arguments);
		}
	};

	/**
	 * Event handler called when the title is clicked/taped.
	 *
	 * @param {jQuery.Event} oEvent The fired event
	 * @private
	 */
	ObjectIdentifier.prototype.ontap = function(oEvent) {
		ObjectIdentifier.prototype._handlePress.apply(this, arguments);
	};

	ObjectIdentifier.prototype.addAssociation = function(sAssociationName, sId, bSuppressInvalidate) {
		var oTitle = this.getAggregation("_titleControl");

		if (sAssociationName === "ariaLabelledBy") {
			if (this.getTitleActive() && oTitle instanceof Link) {
				oTitle.addAssociation("ariaLabelledBy", sId, true);
			}
		}

		return Control.prototype.addAssociation.apply(this, arguments);
	};

	ObjectIdentifier.prototype.removeAssociation = function(sAssociationName, vObject, bSuppressInvalidate) {
		var oTitle = this.getAggregation("_titleControl");

		if (sAssociationName === "ariaLabelledBy") {
			if (this.getTitleActive() && oTitle instanceof Link) {
				oTitle.removeAssociation("ariaLabelledBy", vObject, true);
			}
		}

		return Control.prototype.removeAssociation.apply(this, arguments);
	};

	/**
	 * @see sap.ui.core.Control#getAccessibilityInfo
	 * @returns {object} Current accessibility state of the control
	 * @protected
	 */
	ObjectIdentifier.prototype.getAccessibilityInfo = function() {
		// first get accessibility info from the title control, which can be Text or Link
		var oTitleInfo = this.getAggregation("_titleControl")
			? this.getAggregation("_titleControl").getAccessibilityInfo()
			: {
				type: "",
				description: ""
			},
			oType = (ObjectIdentifier.OI_ARIA_ROLE + " " + (oTitleInfo.type || "")).trim();

		// add ObjectIdentifier type to the title type
		if (this.getTitle() || this.getText()) {
			oTitleInfo.type = oType;
		}
		// add ObjectIdentifier text to the description of the title
		oTitleInfo.description = oTitleInfo.description + " " + this.getText();

		// return the modified Object containing all needed information about the control
		return oTitleInfo;
	};

	ObjectIdentifier.prototype._hasTopRow = function() {
		return this.getTitle() || this.getBadgeNotes() || this.getBadgePeople() || this.getBadgeAttachments();
	};

	return ObjectIdentifier;

});
<commit_msg>[INTERNAL] ObjectIdentifier: Use the public API of the inner controls<commit_after>/*!
 * ${copyright}
 */

// Provides control sap.m.ObjectIdentifier.
sap.ui.define([
	'./library',
	'./Link',
	'./Text',
	'sap/ui/core/Control',
	'sap/ui/core/IconPool',
	'sap/ui/core/InvisibleText',
	'sap/ui/core/library',
	'sap/ui/Device',
	'sap/ui/base/ManagedObject',
	'./ObjectIdentifierRenderer',
	"sap/ui/events/KeyCodes"
],
function(
	library,
	Link,
	Text,
	Control,
	IconPool,
	InvisibleText,
	coreLibrary,
	Device,
	ManagedObject,
	ObjectIdentifierRenderer,
	KeyCodes
	) {
	"use strict";

	// shortcut for sap.ui.core.TextDirection
	var TextDirection = coreLibrary.TextDirection;

	// shortcut for sap.m.EmptyIndicator
	var EmptyIndicatorMode = library.EmptyIndicatorMode;

	/**
	 * Constructor for a new ObjectIdentifier.
	 *
	 * @param {string} [sId] ID for the new control, generated automatically if no ID is given
	 * @param {object} [mSettings] Initial settings for the new control
	 *
	 * @class
	 * The ObjectIdentifier is a display control that enables the user to easily identify a specific object. The ObjectIdentifier title is the key identifier of the object and additional text can be used to further distinguish it from other objects.
	 *
     * Note: This control should not be used with {@link sap.m.Label} or in Forms along with {@link sap.m.Label}.
	 * @extends sap.ui.core.Control
	 * @version ${version}
	 *
	 * @constructor
	 * @public
	 * @since 1.12
	 * @alias sap.m.ObjectIdentifier
	 * @see {@link fiori:https://experience.sap.com/fiori-design-web/object-display-elements/#-object-status Object Identifier}
	 * @ui5-metamodel This control/element also will be described in the UI5 (legacy) designtime metamodel
	 */
	var ObjectIdentifier = Control.extend("sap.m.ObjectIdentifier", /** @lends sap.m.ObjectIdentifier.prototype */ { metadata : {

		library : "sap.m",
		designtime: "sap/m/designtime/ObjectIdentifier.designtime",
		properties : {

			/**
			 * Defines the object title.
			 */
			title : {type : "string", group : "Misc", defaultValue : null},

			/**
			 * Defines the object text.
			 */
			text : {type : "string", group : "Misc", defaultValue : null},

			/**
			 * Indicates whether or not the notes icon is displayed.
			 * @deprecated as of version 1.24.0. There is no replacement for the moment.
			 */
			badgeNotes : {type : "boolean", group : "Misc", defaultValue : null, deprecated: true},

			/**
			 * Indicates whether or not the address book icon is displayed.
			 * @deprecated as of version 1.24.0. There is no replacement for the moment.
			 */
			badgePeople : {type : "boolean", group : "Misc", defaultValue : null, deprecated: true},

			/**
			 * Indicates whether or not the attachments icon is displayed.
			 * @deprecated as of version 1.24.0. There is no replacement for the moment.
			 */
			badgeAttachments : {type : "boolean", group : "Misc", defaultValue : null, deprecated: true},

			/**
			 * Indicates if the ObjectIdentifier is visible. An invisible ObjectIdentifier is not being rendered.
			 */
			visible : {type : "boolean", group : "Appearance", defaultValue : true},

			/**
			 * Indicates if the ObjectIdentifier's title is clickable.
			 * @since 1.26
			 */
			titleActive : {type : "boolean", group : "Misc", defaultValue : false},

			/**
			 * Specifies the element's text directionality with enumerated options. By default, the control inherits text direction from the DOM.
			 * @since 1.28.0
			 */
			textDirection : {type : "sap.ui.core.TextDirection", group : "Appearance", defaultValue : TextDirection.Inherit},

			/**
			 * Specifies if an empty indicator should be displayed when there is no text.
			 *
			 * @since 1.89
			 */
			emptyIndicatorMode: { type: "sap.m.EmptyIndicatorMode", group: "Appearance", defaultValue: EmptyIndicatorMode.Off }
		},
		aggregations : {

			/**
			 * Control to display the object title (can be either Text or Link).
			 *
			 * @private
			 */
			_titleControl : {type : "sap.ui.core.Control", multiple : false, visibility : "hidden"},

			/**
			 * Text control to display the object text.
			 *
			 * @private
			 */
			_textControl : {type : "sap.ui.core.Control", multiple : false, visibility : "hidden"}
		},
		events : {

			/**
			 * Fires when the title is active and the user taps/clicks on it.
			 * @since 1.26
			 */
			titlePress : {
				parameters : {

					/**
					 * DOM reference of the object identifier's title.
					 */
					domRef : {type : "object"}
				}
			}
		},
		associations: {
			/**
			 * Association to controls / IDs, which label this control (see WAI-ARIA attribute aria-labelledby).
			 */
			ariaLabelledBy: {type: "sap.ui.core.Control", multiple: true, singularName: "ariaLabelledBy"}
		},
		dnd: { draggable: true, droppable: false }
	}});

	/**
	 * Initializes the control
	 *
	 * @private
	 */
	ObjectIdentifier.prototype.init = function() {
		var oLibraryResourceBundle = sap.ui.getCore().getLibraryResourceBundle("sap.m");

		if (sap.ui.getCore().getConfiguration().getAccessibility()) {
			ObjectIdentifier.OI_ARIA_ROLE = oLibraryResourceBundle.getText("OI_ARIA_ROLE");
		}
	};

	/**
	 * Called when the control is destroyed.
	 *
	 * @private
	 */
	ObjectIdentifier.prototype.exit = function() {

		if (this._attachmentsIcon) {
			this._attachmentsIcon.destroy();
			this._attachmentsIcon = null;
		}

		if (this._peopleIcon) {
			this._peopleIcon.destroy();
			this._peopleIcon = null;
		}

		if (this._notesIcon) {
			this._notesIcon.destroy();
			this._notesIcon = null;
		}
	};

	/**
	 * Lazy loads attachments icon.
	 * @returns {object} The attachments icon
	 * @private
	 */
	ObjectIdentifier.prototype._getAttachmentsIcon = function() {

		if (!this._attachmentsIcon) {
			this._attachmentsIcon = this._getIcon(IconPool.getIconURI("attachment"), this.getId() + "-attachments");
		}

		return this._attachmentsIcon;
	};

	/**
	 * Lazy loads people icon.
	 * @returns {object} The people icon
	 * @private
	 */
	ObjectIdentifier.prototype._getPeopleIcon = function() {

		if (!this._peopleIcon) {
			this._peopleIcon = this._getIcon(IconPool.getIconURI("group"), this.getId() + "-people");
		}

		return this._peopleIcon;
	};

	/**
	 * Lazy loads notes icon.
	 * @returns {object} The notes icon
	 * @private
	 */
	ObjectIdentifier.prototype._getNotesIcon = function() {

		if (!this._notesIcon ) {
			this._notesIcon  = this._getIcon(IconPool.getIconURI("notes"), this.getId() + "-notes");
		}

		return this._notesIcon;
	};

	/**
	 * Creates icon image.
	 * @param {string} sURI The URL of the icon image
	 * @param {string} sImageId The ID of the icon image
	 * @returns {object} The icon image
	 * @private
	 */
	ObjectIdentifier.prototype._getIcon = function(sURI, sImageId) {

		var sSize = Device.system.phone ? "1em" : "1em";
		var oImage;

		oImage = this._icon || IconPool.createControlByURI({
			src : sURI,
			id : sImageId + "-icon",
			size : sSize,
			useIconTooltip : false
		}, sap.m.Image);

		oImage.setSrc(sURI);

		return oImage;
	};

	/**
	 * Gets the proper control for the title.
	 * @returns {sap.m.Control} The control for the title
	 * @private
	 */
	ObjectIdentifier.prototype._getTitleControl = function() {
		var oTitleControl = this.getAggregation("_titleControl"),
			sId = this.getId(),
			sTitle = ManagedObject.escapeSettingsValue(this.getProperty("title"));

		if (!oTitleControl) {
			// Lazy initialization
			if (this.getProperty("titleActive")) {
				oTitleControl = new Link({
					id : sId + "-link",
					text: sTitle,
					//Add a custom hidden role "ObjectIdentifier" with hidden text
					ariaLabelledBy: InvisibleText.getStaticId("sap.m", "OI_ARIA_ROLE")
				});
				oTitleControl.addAriaLabelledBy(sId + "-text");
			} else {
				oTitleControl = new Text({
					id : sId + "-txt",
					text: sTitle
				});
			}
			this.setAggregation("_titleControl", oTitleControl, true);
		}

		return oTitleControl;
	};

	/**
	 * Lazy loads _textControl aggregation.
	 * @returns {sap.m.Control} The control for the text
	 * @private
	 */
	ObjectIdentifier.prototype._getTextControl = function() {

		var oTextControl = this.getAggregation("_textControl");

		if (!oTextControl) {
			oTextControl = new Text({
				text: ManagedObject.escapeSettingsValue(this.getProperty("text"))
			});
			this.setAggregation("_textControl", oTextControl, true);
		}

		oTextControl.setTextDirection(this.getTextDirection());

		return oTextControl;
	};

	/**
	 * Sets the title.
	 * Default value is empty/undefined.
	 * @public
	 * @param {string} sTitle New value for property title
	 * @returns {this} this to allow method chaining
	 */
	ObjectIdentifier.prototype.setTitle = function (sTitle) {
		if (sTitle) {
			this._getTitleControl().setProperty("text", sTitle);
		}

		return this.setProperty("title", sTitle);
	};

	/**
	 * Sets text.
	 * Default value is empty/undefined.
	 * @public
	 * @param {string} sText New value for property text
	 * @returns {this} this to allow method chaining
	 */
	ObjectIdentifier.prototype.setText = function(sText) {
		if (sText) {
			this._getTextControl().setProperty("text", sText);
		}

		return this.setProperty("text", sText);
	};

	/**
	 * Sets property titleActive.
	 * Default value is false.
	 * @public
	 * @param {boolean} bValue new value for property titleActive
	 * @returns {this} this to allow method chaining
	 */
	ObjectIdentifier.prototype.setTitleActive = function(bValue) {
		var bPrevValue = this.getTitleActive();

		this.setProperty("titleActive", bValue);

		if (bPrevValue != bValue) {
			this.destroyAggregation("_titleControl");
			this._getTitleControl();
		}

		return this;
	};

	/**
	 * Function is called when ObjectIdentifier's title is triggered.
	 *
	 * @param {jQuery.Event} oEvent The fired event
	 * @private
	 */
	ObjectIdentifier.prototype._handlePress = function(oEvent) {
		var oClickedItem = oEvent.target;
		if (this.getTitleActive() && this.$("title")[0].firstChild == oClickedItem) { // checking if the title is clicked
			this.fireTitlePress({
				domRef: oClickedItem
			});

			// mark the event that it is handled by the control
			oEvent.setMarked();
		}
	};

	/**
	 * Event handler called when the enter key is pressed.
	 *
	 * @param {jQuery.Event} oEvent The fired event
	 * @private
	 */
	ObjectIdentifier.prototype.onsapenter = function(oEvent) {
		ObjectIdentifier.prototype._handlePress.apply(this, arguments);
	};

	/**
	 * Event handler called when the space key is pressed.
	 *
	 * @param {jQuery.Event} oEvent The fired event
	 * @private
	 */
	ObjectIdentifier.prototype.onkeyup = function(oEvent) {
		if (oEvent && oEvent.which === KeyCodes.SPACE) {
			ObjectIdentifier.prototype._handlePress.apply(this, arguments);
		}
	};

	/**
	 * Event handler called when the title is clicked/taped.
	 *
	 * @param {jQuery.Event} oEvent The fired event
	 * @private
	 */
	ObjectIdentifier.prototype.ontap = function(oEvent) {
		ObjectIdentifier.prototype._handlePress.apply(this, arguments);
	};

	ObjectIdentifier.prototype.addAssociation = function(sAssociationName, sId, bSuppressInvalidate) {
		var oTitle = this.getAggregation("_titleControl");

		if (sAssociationName === "ariaLabelledBy") {
			if (this.getTitleActive() && oTitle instanceof Link) {
				oTitle.addAriaLabelledBy(sId);
			}
		}

		return Control.prototype.addAssociation.apply(this, arguments);
	};

	ObjectIdentifier.prototype.removeAssociation = function(sAssociationName, vObject, bSuppressInvalidate) {
		var oTitle = this.getAggregation("_titleControl");

		if (sAssociationName === "ariaLabelledBy") {
			if (this.getTitleActive() && oTitle instanceof Link) {
				oTitle.removeAssociation("ariaLabelledBy", vObject, true);
			}
		}

		return Control.prototype.removeAssociation.apply(this, arguments);
	};

	/**
	 * @see sap.ui.core.Control#getAccessibilityInfo
	 * @returns {object} Current accessibility state of the control
	 * @protected
	 */
	ObjectIdentifier.prototype.getAccessibilityInfo = function() {
		// first get accessibility info from the title control, which can be Text or Link
		var oTitleInfo = this.getAggregation("_titleControl")
			? this.getAggregation("_titleControl").getAccessibilityInfo()
			: {
				type: "",
				description: ""
			},
			oType = (ObjectIdentifier.OI_ARIA_ROLE + " " + (oTitleInfo.type || "")).trim();

		// add ObjectIdentifier type to the title type
		if (this.getTitle() || this.getText()) {
			oTitleInfo.type = oType;
		}
		// add ObjectIdentifier text to the description of the title
		oTitleInfo.description = oTitleInfo.description + " " + this.getText();

		// return the modified Object containing all needed information about the control
		return oTitleInfo;
	};

	ObjectIdentifier.prototype._hasTopRow = function() {
		return this.getTitle() || this.getBadgeNotes() || this.getBadgePeople() || this.getBadgeAttachments();
	};

	return ObjectIdentifier;

});
<|endoftext|>


<commit_before>var gulp = require('gulp');
var clean = require('gulp-clean');
var less = require('gulp-less');
var lessAutoprefix = require('less-plugin-autoprefix');
var gulpStylelint = require('gulp-stylelint');
var variablesOutput = require('less-plugin-variables-output');
var concat = require('gulp-concat');
var fileinclude = require('gulp-file-include');
var header = require('gulp-header');
var shell = require('gulp-shell');
var cleanCSS = require('gulp-clean-css');
var sourcemaps = require('gulp-sourcemaps');
var rename = require('gulp-rename');
const fs = require('fs');
const path = require('path');

var autoprefix = new lessAutoprefix({ browsers: ['IE 11', 'last 2 Safari versions', 'iOS 9.0', 'last 2 Chrome versions', 'Firefox ESR'] });
var exportLessVariablesToJson = new variablesOutput({ filename: 'build/skin-tool/less-variables.json' });

// windows doesn't add the lib subfolder to global prefixes
const lib = process.platform === 'win32' ? '' : 'lib/';

const browserSyncPath = `./scratch/tools/${lib}node_modules/browser-sync`;
const backstopJsPath = `./scratch/tools/${lib}node_modules/backstopjs`;

const browserSync = (() => {
  let browserSyncInstance;
  return () => {
    // must be lazy loaded otherwise browser-sync is required to run _any_ gulp task
    browserSyncInstance = browserSyncInstance || require(browserSyncPath).create();
    return browserSyncInstance;
  }
})();

//
// Lint less files using stylelint
//
gulp.task('lint', function() {
  return gulp.src('./src/less/**/*.less')
    .pipe(gulpStylelint({
      failAfterError: false,
      reporters: [
        {formatter: 'string', console: true}
      ]
    }));
});

//
// Build CSS
//
gulp.task('less', function() {
  return gulp.src('./src/less/skins/**/*.less')
    .pipe(less({
      relativeUrls: true,
      plugins: [autoprefix, exportLessVariablesToJson]
    }))
    .pipe(gulp.dest('./build/skins/'))
});

//
// Compiling CSS for runtime demo (can this be combined with the above without depending on browsersync?)
//
gulp.task('less-serve', function() {
  return gulp.src('./src/less/skins/**/*.less')
    .pipe(less({
      relativeUrls: true,
      plugins: [autoprefix, exportLessVariablesToJson]
    }).on('error', function(err) {
      console.error(err.message);
      browserSync().notify(err.message, 5000); // Display error in the browser
      this.emit('end'); // Prevent gulp from catching the error and exiting the watch process
    }))
    .pipe(gulp.dest('./build/skins/'))
    .pipe(browserSync().stream());
});

//
// Minify CSS
//
gulp.task('minify-css', function() {
  return gulp.src(['./build/skins/**/*.css', '!**/*.min.css'])
    .pipe(sourcemaps.init())
    .pipe(cleanCSS({ rebase: false }))
    .pipe(header(fs.readFileSync('src/text/license-header.css', 'utf8')))
    .pipe(rename({ extname: '.min.css' }))
    .pipe(sourcemaps.write('.'))
    .pipe(gulp.dest('./build/skins'));
});

//
// Build HTML
//
gulp.task('buildHtml', function() {
  // Build HTML
  return gulp.src(['./src/demo/**/*.html'])
    .pipe(fileinclude({
      prefix: '@@',
      basepath: '@file'
    }))
    .pipe(gulp.dest('./build'));
});

//
// Copy Files
//
gulp.task('copyFilesA', function() {
  return gulp.src(['./src/demo/styles.css', './src/demo/scripts.js'])
    .pipe(gulp.dest('./build'));
});

gulp.task('copyFilesB', function() {
  return gulp.src(['./src/demo/skin-tool/*.less', './src/demo/skin-tool/*.css', './src/demo/skin-tool/*.js'])
    .pipe(gulp.dest('./build/skin-tool'));
});

gulp.task('copyFilesC', function() {
  return gulp.src(['./src/less/theme/**'])
    .pipe(gulp.dest('./build/skin-tool/theme/'));
});

gulp.task('copyFilesD', function() {
  return gulp.src(['./src/demo/editor-demos/*.js'])
    .pipe(gulp.dest('./build/editor-demos/'));
});

//
// Concat icon packs and copy iconManager
//
gulp.task('setupIconManager', function() {
  return gulp.src([ 'src/demo/iconManager.js', './node_modules/@tinymce/oxide-icons-*/dist/icons/*/icons.js', './scratch/icons/**/dist/icons/*/icons.js' ])
    .pipe(concat('iconManager.js'))
    .pipe(gulp.dest('./build'));
});

const getDirs = (p) => fs.readdirSync(p).filter(f => fs.statSync(path.join(p, f)).isDirectory());
gulp.task('buildSkinSwitcher', (done) => {
  const uiSkins = getDirs('./build/skins/ui');
  const contentSkins = getDirs('./build/skins/content');
  const data = `uiSkins = ${JSON.stringify(uiSkins)}, contentSkins = ${JSON.stringify(contentSkins)}`;
  const html = fs.readFileSync('./build/index.html', 'utf8');
  fs.writeFileSync('./build/index.html', html.replace('/** ADD_DATA */', data));

  done();
});

gulp.task('copyFiles', gulp.series('copyFilesA', 'copyFilesB', 'copyFilesC', 'copyFilesD', 'setupIconManager'));

//
// Browsersync
//
gulp.task('serve', function() {
  browserSync().init({
    server: './build',
    ghostMode: false, // prevent scrolls and clicks between browsers
    open: false // Don't open a browser by default.
  });

  gulp.watch('./src/**/*.less', gulp.series('lint', 'copyFilesC', 'less-serve', 'minify-css'));
  gulp.watch('./src/demo/**/*.html', gulp.series('buildHtml', 'copyFiles', 'buildSkinSwitcher'));
  gulp.watch(['./src/demo/**/*.css', './src/demo/**/*.js'], gulp.series('buildHtml', 'copyFiles'));
  gulp.watch('./build/**/*.*').on('change', browserSync().reload);
});

//
// clean builds
//
gulp.task('cleanBuild', function () {
  return gulp.src('./build', {
    read: false,
    allowEmpty: true,
  })
  .pipe(clean());
});

const testDeps = ['backstopjs'];
const demoDeps = ['browser-sync'];
const iconPacks = [
  '@ephox/oxide-icons-material',
  '@ephox/oxide-icons-jam'
];

const installTools = (modules, prefix = '--prefix ./scratch/tools') => shell.task(`npm install -g --no-package-lock --no-save ${prefix} ${modules.join(' ')}`);

// cheating a bit, adding the registry to the prefix param
gulp.task('getInternal', installTools(iconPacks, '--prefix ./scratch/icons --registry http://nexus:8081/repository/npm-group/'));

gulp.task('getDemoDeps', installTools(demoDeps));

gulp.task('getTestDeps', installTools(testDeps.concat(demoDeps)));

//
// clean tmp
//
gulp.task('cleanTmp', function () {
  return gulp.src('./tmp', {
    read: false,
    allowEmpty: true,
  })
  .pipe(clean());
});

const runBackstopCommand = (command) => {
  const runner = require('./tools/tasks/run_backstop');
  return (done) => {
    // must be lazy loaded otherwise backstop is required to run _any_ gulp task
    const backstop = require(backstopJsPath);
    runner(backstop, browserSync(), done, command)
  }
}

gulp.task('backstop:test', gulp.series('getTestDeps', runBackstopCommand('test')));

gulp.task('backstop:approve', gulp.series('getTestDeps', runBackstopCommand('approve')));

gulp.task('backstop:reference', gulp.series('getTestDeps', runBackstopCommand('reference')));

//
// clean all the things
//
gulp.task('clean', gulp.series('cleanBuild', 'cleanTmp'));

//
// Build project and watch LESS file changes
//
gulp.task('build', gulp.series('clean', 'buildHtml', 'lint', 'less', 'minify-css', 'copyFiles', 'setupIconManager', 'buildSkinSwitcher'));
gulp.task('default', gulp.series('build', 'getDemoDeps', 'serve'));
<commit_msg>Use icons from @tinymce scope<commit_after>var gulp = require('gulp');
var clean = require('gulp-clean');
var less = require('gulp-less');
var lessAutoprefix = require('less-plugin-autoprefix');
var gulpStylelint = require('gulp-stylelint');
var variablesOutput = require('less-plugin-variables-output');
var concat = require('gulp-concat');
var fileinclude = require('gulp-file-include');
var header = require('gulp-header');
var shell = require('gulp-shell');
var cleanCSS = require('gulp-clean-css');
var sourcemaps = require('gulp-sourcemaps');
var rename = require('gulp-rename');
const fs = require('fs');
const path = require('path');

var autoprefix = new lessAutoprefix({ browsers: ['IE 11', 'last 2 Safari versions', 'iOS 9.0', 'last 2 Chrome versions', 'Firefox ESR'] });
var exportLessVariablesToJson = new variablesOutput({ filename: 'build/skin-tool/less-variables.json' });

// windows doesn't add the lib subfolder to global prefixes
const lib = process.platform === 'win32' ? '' : 'lib/';

const browserSyncPath = `./scratch/tools/${lib}node_modules/browser-sync`;
const backstopJsPath = `./scratch/tools/${lib}node_modules/backstopjs`;

const browserSync = (() => {
  let browserSyncInstance;
  return () => {
    // must be lazy loaded otherwise browser-sync is required to run _any_ gulp task
    browserSyncInstance = browserSyncInstance || require(browserSyncPath).create();
    return browserSyncInstance;
  }
})();

//
// Lint less files using stylelint
//
gulp.task('lint', function() {
  return gulp.src('./src/less/**/*.less')
    .pipe(gulpStylelint({
      failAfterError: false,
      reporters: [
        {formatter: 'string', console: true}
      ]
    }));
});

//
// Build CSS
//
gulp.task('less', function() {
  return gulp.src('./src/less/skins/**/*.less')
    .pipe(less({
      relativeUrls: true,
      plugins: [autoprefix, exportLessVariablesToJson]
    }))
    .pipe(gulp.dest('./build/skins/'))
});

//
// Compiling CSS for runtime demo (can this be combined with the above without depending on browsersync?)
//
gulp.task('less-serve', function() {
  return gulp.src('./src/less/skins/**/*.less')
    .pipe(less({
      relativeUrls: true,
      plugins: [autoprefix, exportLessVariablesToJson]
    }).on('error', function(err) {
      console.error(err.message);
      browserSync().notify(err.message, 5000); // Display error in the browser
      this.emit('end'); // Prevent gulp from catching the error and exiting the watch process
    }))
    .pipe(gulp.dest('./build/skins/'))
    .pipe(browserSync().stream());
});

//
// Minify CSS
//
gulp.task('minify-css', function() {
  return gulp.src(['./build/skins/**/*.css', '!**/*.min.css'])
    .pipe(sourcemaps.init())
    .pipe(cleanCSS({ rebase: false }))
    .pipe(header(fs.readFileSync('src/text/license-header.css', 'utf8')))
    .pipe(rename({ extname: '.min.css' }))
    .pipe(sourcemaps.write('.'))
    .pipe(gulp.dest('./build/skins'));
});

//
// Build HTML
//
gulp.task('buildHtml', function() {
  // Build HTML
  return gulp.src(['./src/demo/**/*.html'])
    .pipe(fileinclude({
      prefix: '@@',
      basepath: '@file'
    }))
    .pipe(gulp.dest('./build'));
});

//
// Copy Files
//
gulp.task('copyFilesA', function() {
  return gulp.src(['./src/demo/styles.css', './src/demo/scripts.js'])
    .pipe(gulp.dest('./build'));
});

gulp.task('copyFilesB', function() {
  return gulp.src(['./src/demo/skin-tool/*.less', './src/demo/skin-tool/*.css', './src/demo/skin-tool/*.js'])
    .pipe(gulp.dest('./build/skin-tool'));
});

gulp.task('copyFilesC', function() {
  return gulp.src(['./src/less/theme/**'])
    .pipe(gulp.dest('./build/skin-tool/theme/'));
});

gulp.task('copyFilesD', function() {
  return gulp.src(['./src/demo/editor-demos/*.js'])
    .pipe(gulp.dest('./build/editor-demos/'));
});

//
// Concat icon packs and copy iconManager
//
gulp.task('setupIconManager', function() {
  return gulp.src([ 'src/demo/iconManager.js', './node_modules/@tinymce/oxide-icons-*/dist/icons/*/icons.js', './scratch/icons/**/dist/icons/*/icons.js' ])
    .pipe(concat('iconManager.js'))
    .pipe(gulp.dest('./build'));
});

const getDirs = (p) => fs.readdirSync(p).filter(f => fs.statSync(path.join(p, f)).isDirectory());
gulp.task('buildSkinSwitcher', (done) => {
  const uiSkins = getDirs('./build/skins/ui');
  const contentSkins = getDirs('./build/skins/content');
  const data = `uiSkins = ${JSON.stringify(uiSkins)}, contentSkins = ${JSON.stringify(contentSkins)}`;
  const html = fs.readFileSync('./build/index.html', 'utf8');
  fs.writeFileSync('./build/index.html', html.replace('/** ADD_DATA */', data));

  done();
});

gulp.task('copyFiles', gulp.series('copyFilesA', 'copyFilesB', 'copyFilesC', 'copyFilesD', 'setupIconManager'));

//
// Browsersync
//
gulp.task('serve', function() {
  browserSync().init({
    server: './build',
    ghostMode: false, // prevent scrolls and clicks between browsers
    open: false // Don't open a browser by default.
  });

  gulp.watch('./src/**/*.less', gulp.series('lint', 'copyFilesC', 'less-serve', 'minify-css'));
  gulp.watch('./src/demo/**/*.html', gulp.series('buildHtml', 'copyFiles', 'buildSkinSwitcher'));
  gulp.watch(['./src/demo/**/*.css', './src/demo/**/*.js'], gulp.series('buildHtml', 'copyFiles'));
  gulp.watch('./build/**/*.*').on('change', browserSync().reload);
});

//
// clean builds
//
gulp.task('cleanBuild', function () {
  return gulp.src('./build', {
    read: false,
    allowEmpty: true,
  })
  .pipe(clean());
});

const testDeps = ['backstopjs'];
const demoDeps = ['browser-sync'];
const iconPacks = [
  '@tinymce/oxide-icons-material',
  '@tinymce/oxide-icons-jam'
];

const installTools = (modules, prefix = '--prefix ./scratch/tools') => shell.task(`npm install -g --no-package-lock --no-save ${prefix} ${modules.join(' ')}`);

// cheating a bit, adding the registry to the prefix param
gulp.task('getInternal', installTools(iconPacks, '--prefix ./scratch/icons --registry http://nexus:8081/repository/npm-group/'));

gulp.task('getDemoDeps', installTools(demoDeps));

gulp.task('getTestDeps', installTools(testDeps.concat(demoDeps)));

//
// clean tmp
//
gulp.task('cleanTmp', function () {
  return gulp.src('./tmp', {
    read: false,
    allowEmpty: true,
  })
  .pipe(clean());
});

const runBackstopCommand = (command) => {
  const runner = require('./tools/tasks/run_backstop');
  return (done) => {
    // must be lazy loaded otherwise backstop is required to run _any_ gulp task
    const backstop = require(backstopJsPath);
    runner(backstop, browserSync(), done, command)
  }
}

gulp.task('backstop:test', gulp.series('getTestDeps', runBackstopCommand('test')));

gulp.task('backstop:approve', gulp.series('getTestDeps', runBackstopCommand('approve')));

gulp.task('backstop:reference', gulp.series('getTestDeps', runBackstopCommand('reference')));

//
// clean all the things
//
gulp.task('clean', gulp.series('cleanBuild', 'cleanTmp'));

//
// Build project and watch LESS file changes
//
gulp.task('build', gulp.series('clean', 'buildHtml', 'lint', 'less', 'minify-css', 'copyFiles', 'setupIconManager', 'buildSkinSwitcher'));
gulp.task('default', gulp.series('build', 'getDemoDeps', 'serve'));
<|endoftext|>


<commit_before>'use strict';

const gulp = require('gulp');
const fileinclude = require('gulp-file-include');
const webpack = require('webpack-stream');
const sass = require('gulp-sass');
const sassImporterTilde = require('node-sass-tilde-importer');
const postcss = require('gulp-postcss');
const autoprefixer = require('autoprefixer');
const cleancss = require('gulp-clean-css');
const imagemin = require('gulp-imagemin');
const cache = require('gulp-cache');
const svgsprite = require('gulp-svg-sprite');
const del = require('del');
const browserSync = require('browser-sync').create();

const packageJson = require('./package.json');
const config = {
    src: './src',
    dest: './dist'
};
Object.assign(config, {
    html: {
        src: config.src,
        dest: config.dest,
        partials: `${config.src}/partials`
    },
    js: {
        src: `${config.src}/js`,
        dest: `${config.dest}/js`
    },
    css: {
        src: `${config.src}/scss`,
        dest: `${config.dest}/css`
    },
    svg: {
        src: `${config.src}/assets/svg`,
        dest: `${config.dest}/assets/svg`
    },
    img: {
        src: `${config.src}/assets/images`,
        dest: `${config.dest}/assets/images`
    },
    fonts: {
        src: `${config.src}/assets/fonts`,
        dest: `${config.dest}/assets/fonts`
    }
});

const isProduction = (process.env.NODE_ENV === 'production') ? true : true;

const clean = () => del(
    [`${config.dest}/**/*`],
    {force: true}
);

const html = () => gulp.src(`${config.html.src}/*.html`)
    .pipe(fileinclude({
        prefix: '@@',
        basepath: '@file'
    }))
    .pipe(gulp.dest(config.html.dest));

const js = () => gulp.src(`${config.js.src}/**/*.js`)
    .pipe(webpack({
        mode: isProduction && 'production' || 'development',
        output: {
            filename: '[name].js',
            chunkFilename: '[name]-chunk.js'
        },
        module: {
            rules: [{
                test: /\.js$/,
                exclude: /node_modules/,
                use: ['babel-loader']
            }]
        }
    }))
    .pipe(gulp.dest(config.js.dest));

const css = () => {
    let stream = gulp.src(`${config.css.src}/**/*.scss`)
        .pipe(sass({
            includePaths: ['./node_modules/'],
            importer: sassImporterTilde
        }).on('error', sass.logError))
        .pipe(postcss([
            autoprefixer()
        ]));

    if (isProduction) stream = stream
        .pipe(cleancss({
            level: 1
        }));

    stream
        .pipe(gulp.dest(config.css.dest))
        .pipe(browserSync.stream());

    return stream;
};

const svgIcons = () => gulp.src([
    `${config.svg.src}/icons/**/*.svg`
])
    .pipe(svgsprite({
        shape: {
            id: { separator: '-', generator: 'icon-%s' },
            dimension: { maxWidth: 32, maxHeight: 32 }
        },
        mode: {
            symbol: { dest: '', sprite: 'icons.svg' }
        }
    }))
    .pipe(gulp.dest(config.svg.dest));

const svg = gulp.series(svgIcons);

const img = () => gulp.src(`${config.img.src}/**/*.+(png|jpg|jpeg|gif|svg)`)
    .pipe(
        cache(
            imagemin({
                interlaced: true
            })
        )
    )
    .pipe(gulp.dest(config.img.dest));

const fonts = () => gulp.src(`${config.fonts.src}/**/*`)
    .pipe(gulp.dest(config.fonts.dest));

const serve = () => browserSync.init({
    server: config.dest,
    port: 4000,
    notify: false,
    reloadDelay: 500,
    ghostMode: false,
    open: true
});

const watch = () => {
    gulp.watch([`${config.html.src}/*.html`, `${config.html.partials}/*.html`])
        .on('change', gulp.series(html));
    gulp.watch(`${config.js.src}/**/*.js`)
        .on('change', gulp.series(js));
    gulp.watch(`${config.css.src}/**/*.scss`)
        .on('change', gulp.series(css));
    gulp.watch(`${config.svg.src}/icons/**/*.svg`)
        .on('change', gulp.series(svgIcons));
    gulp.watch([`${config.dest}/**/*`, `!${config.dest}/**/*.css`])
        .on('change', gulp.series(browserSync.reload));
};

const build = gulp.series(clean, html, js, css, svg, img, fonts);

exports.build = build;
exports.serve = serve;
exports.default = gulp.parallel(
    gulp.series(build, serve),
    watch
);
<commit_msg>feat: adds routing and video<commit_after>'use strict';

const gulp = require('gulp');
const fileinclude = require('gulp-file-include');
const webpack = require('webpack-stream');
const sass = require('gulp-sass');
const sassImporterTilde = require('node-sass-tilde-importer');
const postcss = require('gulp-postcss');
const autoprefixer = require('autoprefixer');
const cleancss = require('gulp-clean-css');
const imagemin = require('gulp-imagemin');
const cache = require('gulp-cache');
const svgsprite = require('gulp-svg-sprite');
const del = require('del');
const browserSync = require('browser-sync').create();

const packageJson = require('./package.json');
const config = {
    src: './src',
    dest: './dist'
};
Object.assign(config, {
    html: {
        src: config.src,
        dest: config.dest,
        partials: `${config.src}/partials`
    },
    js: {
        src: `${config.src}/js`,
        dest: `${config.dest}/js`
    },
    css: {
        src: `${config.src}/scss`,
        dest: `${config.dest}/css`
    },
    svg: {
        src: `${config.src}/assets/svg`,
        dest: `${config.dest}/assets/svg`
    },
    img: {
        src: `${config.src}/assets/images`,
        dest: `${config.dest}/assets/images`
    },
    fonts: {
        src: `${config.src}/assets/fonts`,
        dest: `${config.dest}/assets/fonts`
    },
    video: {
        src: `${config.src}/assets/video`,
        dest: `${config.dest}/assets/video`
    }
});

const isProduction = (process.env.NODE_ENV === 'production') ? true : true;

const clean = () => del(
    [`${config.dest}/**/*`],
    {force: true}
);

const html = () => gulp.src(`${config.html.src}/*.html`)
    .pipe(fileinclude({
        prefix: '@@',
        basepath: '@file'
    }))
    .pipe(gulp.dest(config.html.dest));

const js = () => gulp.src(`${config.js.src}/**/*.js`)
    .pipe(webpack({
        mode: isProduction && 'production' || 'development',
        output: {
            filename: '[name].js',
            chunkFilename: '[name]-chunk.js'
        },
        module: {
            rules: [{
                test: /\.js$/,
                exclude: /node_modules/,
                use: ['babel-loader']
            }]
        }
    }))
    .pipe(gulp.dest(config.js.dest));

const css = () => {
    let stream = gulp.src(`${config.css.src}/**/*.scss`)
        .pipe(sass({
            includePaths: ['./node_modules/'],
            importer: sassImporterTilde
        }).on('error', sass.logError))
        .pipe(postcss([
            autoprefixer()
        ]));

    if (isProduction) stream = stream
        .pipe(cleancss({
            level: 1
        }));

    stream
        .pipe(gulp.dest(config.css.dest))
        .pipe(browserSync.stream());

    return stream;
};

const svgIcons = () => gulp.src([
    `${config.svg.src}/icons/**/*.svg`
])
    .pipe(svgsprite({
        shape: {
            id: { separator: '-', generator: 'icon-%s' },
            dimension: { maxWidth: 32, maxHeight: 32 }
        },
        mode: {
            symbol: { dest: '', sprite: 'icons.svg' }
        }
    }))
    .pipe(gulp.dest(config.svg.dest));

const svg = gulp.series(svgIcons);

const img = () => gulp.src(`${config.img.src}/**/*.+(png|jpg|jpeg|gif|svg)`)
    .pipe(
        cache(
            imagemin({
                interlaced: true
            })
        )
    )
    .pipe(gulp.dest(config.img.dest));

const fonts = () => gulp.src(`${config.fonts.src}/**/*`)
    .pipe(gulp.dest(config.fonts.dest));

const video = () => gulp.src(`${config.video.src}/**/*`)
.pipe(gulp.dest(config.video.dest));

const copyfiles = () => gulp.src([
    //'./src/robots.txt',
    './src/.htaccess'
])
    .pipe(gulp.dest(config.dest));

const serve = () => browserSync.init({
    server: {
        baseDir: config.dest,
        routes: {
            '/about': 'dist/about.html',
            '/work': 'dist/work.html',
            '/cinema': 'dist/cinema.html'
        }
    },
    port: 4000,
    notify: false,
    reloadDelay: 500,
    ghostMode: false,
    open: true
});

const watch = () => {
    gulp.watch([`${config.html.src}/*.html`, `${config.html.partials}/*.html`])
        .on('change', gulp.series(html));
    gulp.watch(`${config.js.src}/**/*.js`)
        .on('change', gulp.series(js));
    gulp.watch(`${config.css.src}/**/*.scss`)
        .on('change', gulp.series(css));
    gulp.watch(`${config.svg.src}/icons/**/*.svg`)
        .on('change', gulp.series(svgIcons));
    gulp.watch([`${config.dest}/**/*`, `!${config.dest}/**/*.css`])
        .on('change', gulp.series(browserSync.reload));
};

const build = gulp.series(clean, html, js, css, svg, img, fonts, video, copyfiles);

exports.build = build;
exports.serve = serve;
exports.default = gulp.parallel(
    gulp.series(build, serve),
    watch
);
<|endoftext|>


<commit_before>/*===============================================================================
************   Virtual List   ************
===============================================================================*/
var VirtualList = function (listBlock, params) {
    var defaults = {
        cols: 1
    };
    params = params || {};
    for (var def in defaults) {
        if (typeof params[def] === 'undefined') {
            params[def] = defaults[def];
        }
    }
    /* @params example:
    {
        items: [] //array of full HTML elements or elements with data if template is specified
        rowsBefore: 10,
        rowsAfter: 10,
        cols:1,
        template: '' //template7 string
        updatableScroll: true/false,
        searchAll: function(query, items) ,
        searchByItem: function(query, index, item) ,
        renderItem: function (item, index) {
            return 'item string'
        }
    }
    */

    // Preparation
    var vl = this;
    vl.listBlock = $(listBlock);
    vl.params = params;
    vl.items = params.items;
    if (params.template) {
        if (typeof params.template === 'string') vl.template = t7.compile(params.template);
        else if (typeof params.template === 'function') vl.template = params.template;
    }
    vl.pageContent = vl.listBlock.parents('.page-content');

    // Bad scroll
    var updatableScroll;
    if (typeof vl.params.updatableScroll !== 'undefined') {
        updatableScroll = vl.params.updatableScroll;
    }
    else {
        updatableScroll = true;
        if (app.device.ios && app.device.osVersion.split('.')[0] < 8) {
            updatableScroll = false;
        }
    }

    // Append

    vl.ul = vl.listBlock.children('ul');
    if (vl.ul.length === 0) {
        vl.listBlock.append('

');
        vl.ul = vl.listBlock.children('ul');
    }

    // DOM cached items
    vl.domCache = {};
    vl.displayDomCache = {};

    // Temporary DOM Element
    vl.tempDomElement = document.createElement('ul');

    // Last repain position
    vl.lastRepaintY = null;

    // Fragment
    vl.fragment = document.createDocumentFragment();

    // Set indexes
    vl.setIndexes = function () {
        for (var i = 0; i < vl.items.length; i++) {
            vl.items[i]._virtualIndex = i;
        }
    };

    // Filter
    vl.filter = function (indexes) {
        vl.filteredItems = [];
        var firstIndex = indexes[0];
        var lastIndex = indexes[indexes.length - 1];
        for (var i = 0; i < indexes.length; i++) {
            vl.filteredItems.push(vl.items[indexes[i]]);
        }
        vl.update();
    };
    vl.resetFilter = function () {
        vl.filteredItems = null;
        delete vl.filteredItems;
        vl.update();
    };

    // Set list size
    vl.setListSize = function () {
        var items = vl.filteredItems || vl.items;
        if (updatableScroll) {
            vl.ul.css({height: items.length * vl.params.height + 'px'});
        }
        vl.pageHeight = vl.pageContent[0].offsetHeight;
        vl.rowsPerScreen = Math.ceil(vl.pageHeight / vl.params.height);
        vl.rowsBefore = vl.params.rowsBefore || vl.rowsPerScreen;
        vl.rowsAfter = vl.params.rowsAfter || vl.rowsPerScreen;
        vl.rowsToRender = (vl.rowsPerScreen + vl.rowsBefore + vl.rowsAfter) * vl.params.cols;
        vl.maxBufferHeight = vl.rowsBefore * vl.params.height;
    };

    // Set items (inser/remove/replace)
    vl.renderItems = function (force) {
        if (force) vl.lastRepaintY = null;
        var scrollTop = vl.pageContent[0].scrollTop;
        var fromPos = parseInt(scrollTop / vl.params.height) - vl.rowsBefore;
        if (fromPos < 0) {
            fromPos = 0;
        }
        if (!vl.lastRepaintY || Math.abs(scrollTop - vl.lastRepaintY) > vl.maxBufferHeight || (!updatableScroll && (scrollTop + vl.pageHeight >= vl.pageContent[0].scrollHeight))) {
            vl.lastRepaintY = scrollTop;
        }
        else {
            return;
        }

        var items = vl.filteredItems || vl.items;
        var finalItem = Math.min(fromPos + vl.rowsToRender, items.length);
        for (var i = fromPos; i < finalItem; i++) {
            var item;
            if (vl.domCache[items[i]._virtualIndex]) {
                item = vl.domCache[items[i]._virtualIndex];
            }
            else {
                if (vl.template) {
                    vl.tempDomElement.innerHTML = vl.template(items[i], {index: items[i]._virtualIndex});
                }
                else if (vl.params.renderItem) {
                    vl.tempDomElement.innerHTML = vl.params.renderItem(items[i], items[i]._virtualIndex);
                }
                else {
                    vl.tempDomElement.innerHTML = items[i];
                }
                item = vl.tempDomElement.childNodes[0];
                vl.domCache[items[i]._virtualIndex] = item;
            }
            item.f7VirtualListIndex = items[i]._virtualIndex;

            item.style.top = (i * vl.params.height) + 'px';
            vl.fragment.appendChild(item);
            if (!updatableScroll) {
                vl.ul[0].style.height = (i + 1) * vl.params.height + 'px';
            }
        }
        vl.ul[0].innerHTML = '';
        vl.ul[0].appendChild(vl.fragment);
    };

    // Handle scroll event
    vl.handleScroll = function (e) {
        vl.renderItems();
    };
    // Handle resize event
    vl.handleResize = function (e) {
        vl.setListSize();
        vl.renderItems(true);
    };

    vl.attachEvents = function (detach) {
        var action = detach ? 'off' : 'on';
        vl.pageContent[action]('scroll', vl.handleScroll);
        $(window)[action]('resize', vl.handleResize);
    };

    // Init Virtual List
    vl.init = function () {
        vl.attachEvents();
        vl.setIndexes();
        vl.setListSize();
        vl.renderItems();
    };

    // Append/Prepend
    vl.appendItems = function (items) {
        for (var i = 0; i < items.length; i++) {
            vl.items.push(items[i]);
        }
        vl.setIndexes();
        vl.update();
    };
    vl.appendItem = function (item) {
        vl.appendItems([item]);
    };
    vl.replaceItem = function (index, item) {
        vl.items[index] = item;
        delete vl.domCache[index];
        vl.setIndexes();
        vl.update();
    };

    vl.prependItems = function (items) {
        for (var i = items.length - 1; i >= 0; i--) {
            vl.items.unshift(items[i]);
        }
        var newCache = {};
        for (var cached in vl.domCache) {
            newCache[parseInt(cached, 10) + items.length] = vl.domCache[cached];
        }
        vl.domCache = newCache;
        vl.setIndexes();
        vl.update();
    };
    vl.prependItem = function (item) {
        vl.prependItems([item]);
    };

    vl.deleteItems = function (indexes) {
        var prevIndex, indexShift = 0;
        for (var i = 0; i < indexes.length; i++) {
            var index = indexes[i];
            if (typeof prevIndex !== 'undefined') {
                if (index > prevIndex) {
                    indexShift = -i;
                }
            }
            index = index + indexShift;
            prevIndex = indexes[i];

            var newCache = {};
            for (var cached in vl.domCache) {
                var cachedIndex = parseInt(cached, 10);
                if (cachedIndex === index) {
                    delete vl.domCache[index];
                }
                else if (parseInt(cached, 10) > index) {
                    newCache[cachedIndex - 1] = vl.domCache[cached];
                }
                else {
                    newCache[cachedIndex] = vl.domCache[cached];
                }
            }
            vl.domCache = newCache;
        }
        vl.setIndexes();
        vl.update();
    };
    vl.deleteItem = function (index) {
        vl.deleteItems([index]);
    };

    // Update Virtual List
    vl.update = function () {
        vl.setListSize();
        vl.renderItems(true);
    };

    // Destroy
    vl.destroy = function () {
        vl.attachEvents(true);
        delete vl.items;
        delete vl.domCache;
    };

    // Init Virtual List
    vl.init();

    // Store vl in container
    vl.listBlock[0].f7VirtualList = vl;
    return vl;
};

// App Method
app.virtualList = function (listBlock, params) {
    return new VirtualList(listBlock, params);
};

app.reinitVirtualList = function (pageContainer) {
    var page = $(pageContainer);
    var vlists = page.find('.virtual-list');
    if (vlists.length === 0) return;
    for (var i = 0; i < vlists.length; i++) {
        var vlistInstance = vlistInstance[0].f7VirtualList;
        if (vlistInstance) {
            vlistInstance.update();
        }
    }
};<commit_msg>Improvements<commit_after>/*===============================================================================
************   Virtual List   ************
===============================================================================*/
var VirtualList = function (listBlock, params) {
    var defaults = {
        cols: 1
    };
    params = params || {};
    for (var def in defaults) {
        if (typeof params[def] === 'undefined') {
            params[def] = defaults[def];
        }
    }
    /* @params example:
    {
        items: [] //array of full HTML elements or elements with data if template is specified
        rowsBefore: 10,
        rowsAfter: 10,
        cols:1,
        template: '' //template7 string
        updatableScroll: true/false,
        searchAll: function(query, items) ,
        searchByItem: function(query, index, item) ,
        renderItem: function (index, item) {
            return 'item string'
        }
    }
    */

    // Preparation
    var vl = this;
    vl.listBlock = $(listBlock);
    vl.params = params;
    vl.items = params.items;
    if (params.template) {
        if (typeof params.template === 'string') vl.template = t7.compile(params.template);
        else if (typeof params.template === 'function') vl.template = params.template;
    }
    vl.pageContent = vl.listBlock.parents('.page-content');

    // Bad scroll
    var updatableScroll;
    if (typeof vl.params.updatableScroll !== 'undefined') {
        updatableScroll = vl.params.updatableScroll;
    }
    else {
        updatableScroll = true;
        if (app.device.ios && app.device.osVersion.split('.')[0] < 8) {
            updatableScroll = false;
        }
    }

    // Append

    vl.ul = vl.listBlock.children('ul');
    if (vl.ul.length === 0) {
        vl.listBlock.append('

');
        vl.ul = vl.listBlock.children('ul');
    }

    // DOM cached items
    vl.domCache = {};
    vl.displayDomCache = {};

    // Temporary DOM Element
    vl.tempDomElement = document.createElement('ul');

    // Last repain position
    vl.lastRepaintY = null;

    // Fragment
    vl.fragment = document.createDocumentFragment();

    // Filter
    vl.filterItems = function (indexes) {
        vl.filteredItems = [];
        var firstIndex = indexes[0];
        var lastIndex = indexes[indexes.length - 1];
        for (var i = 0; i < indexes.length; i++) {
            vl.filteredItems.push(vl.items[indexes[i]]);
        }
        vl.update();
    };
    vl.resetFilter = function () {
        vl.filteredItems = null;
        delete vl.filteredItems;
        vl.update();
    };

    // Set list size
    vl.setListSize = function () {
        var items = vl.filteredItems || vl.items;
        if (updatableScroll) {
            vl.ul.css({height: items.length * vl.params.height + 'px'});
        }
        vl.pageHeight = vl.pageContent[0].offsetHeight;
        vl.rowsPerScreen = Math.ceil(vl.pageHeight / vl.params.height);
        vl.rowsBefore = vl.params.rowsBefore || vl.rowsPerScreen;
        vl.rowsAfter = vl.params.rowsAfter || vl.rowsPerScreen;
        vl.rowsToRender = (vl.rowsPerScreen + vl.rowsBefore + vl.rowsAfter) * vl.params.cols;
        vl.maxBufferHeight = vl.rowsBefore * vl.params.height;
    };

    // Set items (inser/remove/replace)
    vl.render = function (force) {
        if (force) vl.lastRepaintY = null;
        var scrollTop = vl.pageContent[0].scrollTop;
        var fromPos = parseInt(scrollTop / vl.params.height) - vl.rowsBefore;
        if (fromPos < 0) {
            fromPos = 0;
        }
        if (!vl.lastRepaintY || Math.abs(scrollTop - vl.lastRepaintY) > vl.maxBufferHeight || (!updatableScroll && (scrollTop + vl.pageHeight >= vl.pageContent[0].scrollHeight))) {
            vl.lastRepaintY = scrollTop;
        }
        else {
            return;
        }
        var items = vl.filteredItems || vl.items;
        var finalItem = Math.min(fromPos + vl.rowsToRender, items.length);
        for (var i = fromPos; i < finalItem; i++) {
            var item, index;
            // Define real item index
            index = vl.items.indexOf(items[i]);

            // Find items
            if (vl.domCache[index]) {
                item = vl.domCache[index];
            }
            else {
                if (vl.template) {
                    vl.tempDomElement.innerHTML = vl.template(items[i], {index: index});
                }
                else if (vl.params.renderItem) {
                    vl.tempDomElement.innerHTML = vl.params.renderItem(index, items[i]);
                }
                else {
                    vl.tempDomElement.innerHTML = items[i];
                }
                item = vl.tempDomElement.childNodes[0];
                vl.domCache[index] = item;
            }
            item.f7VirtualListIndex = index;

            // Set item top position
            item.style.top = (i * vl.params.height) + 'px';

            // Append item to fragment
            vl.fragment.appendChild(item);

            // Update list height with not updatable scroll
            if (!updatableScroll) {
                vl.ul[0].style.height = (i + 1) * vl.params.height + 'px';
            }
        }

        // Update list html
        vl.ul[0].innerHTML = '';
        vl.ul[0].appendChild(vl.fragment);
    };

    // Handle scroll event
    vl.handleScroll = function (e) {
        vl.render();
    };
    // Handle resize event
    vl.handleResize = function (e) {
        vl.setListSize();
        vl.render(true);
    };

    vl.attachEvents = function (detach) {
        var action = detach ? 'off' : 'on';
        vl.pageContent[action]('scroll', vl.handleScroll);
        $(window)[action]('resize', vl.handleResize);
    };

    // Init Virtual List
    vl.init = function () {
        vl.attachEvents();
        vl.setListSize();
        vl.render();
    };

    // Append/Prepend
    vl.appendItems = function (items) {
        for (var i = 0; i < items.length; i++) {
            vl.items.push(items[i]);
        }
        vl.update();
    };
    vl.appendItem = function (item) {
        vl.appendItems([item]);
    };
    vl.replaceItem = function (index, item) {
        vl.items[index] = item;
        delete vl.domCache[index];
        vl.update();
    };

    vl.prependItems = function (items) {
        for (var i = items.length - 1; i >= 0; i--) {
            vl.items.unshift(items[i]);
        }
        var newCache = {};
        for (var cached in vl.domCache) {
            newCache[parseInt(cached, 10) + items.length] = vl.domCache[cached];
        }
        vl.domCache = newCache;
        vl.update();
    };
    vl.prependItem = function (item) {
        vl.prependItems([item]);
    };

    vl.deleteItems = function (indexes) {
        var prevIndex, indexShift = 0;
        for (var i = 0; i < indexes.length; i++) {
            var index = indexes[i];
            if (typeof prevIndex !== 'undefined') {
                if (index > prevIndex) {
                    indexShift = -i;
                }
            }
            index = index + indexShift;
            prevIndex = indexes[i];
            // Delete item
            var deletedItem = vl.items.splice(index, 1);
            // Delete from filtered
            if (vl.filteredItems && vl.filteredItems.indexOf(deletedItem)) vl.filteredItems.splice(vl.filteredItems.indexOf(deletedItem), 1);
            // Update cache
            var newCache = {};
            for (var cached in vl.domCache) {
                var cachedIndex = parseInt(cached, 10);
                if (cachedIndex === index) {
                    delete vl.domCache[index];
                }
                else if (parseInt(cached, 10) > index) {
                    newCache[cachedIndex - 1] = vl.domCache[cached];
                }
                else {
                    newCache[cachedIndex] = vl.domCache[cached];
                }
            }
            vl.domCache = newCache;
        }
        vl.update();
    };
    vl.deleteItem = function (index) {
        vl.deleteItems([index]);
    };

    // Update Virtual List
    vl.update = function () {
        vl.setListSize();
        vl.render(true);
    };

    // Destroy
    vl.destroy = function () {
        vl.attachEvents(true);
        delete vl.items;
        delete vl.domCache;
    };

    // Init Virtual List
    vl.init();

    // Store vl in container
    vl.listBlock[0].f7VirtualList = vl;
    return vl;
};

// App Method
app.virtualList = function (listBlock, params) {
    return new VirtualList(listBlock, params);
};

app.reinitVirtualList = function (pageContainer) {
    var page = $(pageContainer);
    var vlists = page.find('.virtual-list');
    if (vlists.length === 0) return;
    for (var i = 0; i < vlists.length; i++) {
        var vlistInstance = vlistInstance[0].f7VirtualList;
        if (vlistInstance) {
            vlistInstance.update();
        }
    }
};<|endoftext|>


<commit_before>/*
 * ajax-seo-starter-kit
 *
 * https://github.com/jostw/ajax-seo-starter-kit
 *
 * Copyright (c) 2014 jos
 * Licensed under the MIT license.
 */

"use strict";

var gulp =    require("gulp"),
    wiredep = require("wiredep").stream;

gulp.task("html", function() {
    return gulp.src("views/layouts/index.hbs")
               .pipe(wiredep())
               .pipe(gulp.dest("views/layouts/"));
});

gulp.task("default", ["html"]);
<commit_msg>Add: gulp watch<commit_after>/*
 * ajax-seo-starter-kit
 *
 * https://github.com/jostw/ajax-seo-starter-kit
 *
 * Copyright (c) 2014 jos
 * Licensed under the MIT license.
 */

"use strict";

var gulp =    require("gulp"),
    wiredep = require("wiredep").stream;

gulp.task("html", function() {
    return gulp.src("views/layouts/index.hbs")
               .pipe(wiredep())
               .pipe(gulp.dest("views/layouts/"));
});

gulp.task("watch", function() {
    gulp.watch("views/**/*.hbs", ["html"]);
});

gulp.task("default", ["html", "watch"]);
<|endoftext|>


<commit_before>'use strict';

const del = require('del');
const gulp = require('gulp');
const autoprefixer = require('gulp-autoprefixer');
const sass = require('gulp-sass');
const rename = require('gulp-rename');
const sourcemaps = require('gulp-sourcemaps');
const cssnano = require('gulp-cssnano');
const postcss = require('gulp-postcss');
const stylefmt = require('gulp-stylefmt');
const sorting = require('postcss-sorting');
const torem = require('postcss-pxtorem');
const sortOrder = require('./.postcss-sorting.json');
const pkg = require('./package.json');

// Config
const build = {
	css: './dist/assets/css',
	html: './dist/views/',
	twig: './src/views/',
	data: './src/mock/',
	scss: './src/scss/',
	docs: './docs/_media/',
};

const AUTOPREFIXER_BROWSERS = [
	'ie >= 11',
	'edge >= 12',
	'ff >= 38',
	'chrome >= 35',
	'safari >= 8',
	'opera >= 35',
	'ios >= 8',
];

gulp.task('css', () => {
	const css = gulp
		.src(build.scss + '*.scss')
		.pipe(sourcemaps.init())
		.pipe(sass({
			indentType: 'tab',
			indentWidth: 1,
			outputStyle: 'expanded',
			precision: 10,
			onError: console.error.bind(console, 'Sass error:'),
		}))
		.pipe(autoprefixer(AUTOPREFIXER_BROWSERS))
		.pipe(
			postcss([
				sorting(sortOrder),
				torem({
					rootValue: 16,
					unitPrecision: 7,
					propWhiteList: [
						'font',
						'font-size',
						'margin',
						'margin-left',
						'margin-right',
						'margin-top',
						'margin-bottom',
						'padding',
						'padding-left',
						'padding-right',
						'padding-top',
						'padding-bottom',
					],
					selectorBlackList': [],
					replace': true,
					mediaQuery': false,
					minPixelValue': 0,
				})
			])
		)
		.pipe(stylefmt())
		.pipe(rename({
			suffix: '.' + pkg.version,
			extname: '.css',
		}))
		.pipe(sourcemaps.write('./'))
		.pipe(gulp.dest(build.css));

	return css;
});

gulp.task('clean', () => {
	del(['dist']);
});

gulp.task('minify', gulp.series('css', () => {
	const css = gulp
		.src(build.css + '/*.' + pkg.version + '.css')
		.pipe(sourcemaps.init())
		.pipe(cssnano())
		.pipe(rename({
			suffix: '.min',
			extname: '.css',
		}))
		.pipe(sourcemaps.write('./'))
		.pipe(gulp.dest(build.css));

	return css;
}));

gulp.task('docs:css', () => {
	const css = gulp
		.src(build.docs + '*.scss')
		.pipe(sourcemaps.init())
		.pipe(sass({
			indentType' 'tab',
			indentWidth: 1,
			outputStyle: 'expanded',
			precision: 10,
			onError: console.error.bind(console, 'Sass error:'),
		}))
		.pipe(autoprefixer(AUTOPREFIXER_BROWSERS))
		.pipe(
			postcss([
				sorting(sortOrder),
				torem({
					rootValue: 16,
					unitPrecision: 7,
					propWhiteList: [
						'font',
						'font-size',
						'margin',
						'margin-left',
						'margin-right',
						'margin-top',
						'margin-bottom',
						'padding',
						'padding-left',
						'padding-right',
						'padding-top',
						'padding-bottom',
					],
					selectorBlackList: [],
					replace: true,
					mediaQuery: false,
					minPixelValue: 0,
				})
			])
		)
		.pipe(stylefmt())
		.pipe(cssnano())
		.pipe(rename({
			suffix: '.' + pkg.version + '.min',
			extname: '.css',
		}))
		.pipe(sourcemaps.write('./'))
		.pipe(gulp.dest(build.docs));

	return css;
});

gulp.task('watch', () => {
	gulp.watch('src/scss/**/*.scss', gulp.series('css', 'minify'));
});

gulp.task('serve', gulp.series('watch'));
gulp.task('test', gulp.series('css', 'minify'));
gulp.task('default', gulp.series('css', 'minify', 'watch'));
<commit_msg>fix more xo errors<commit_after>'use strict';

const del = require('del');
const gulp = require('gulp');
const autoprefixer = require('gulp-autoprefixer');
const sass = require('gulp-sass');
const rename = require('gulp-rename');
const sourcemaps = require('gulp-sourcemaps');
const cssnano = require('gulp-cssnano');
const postcss = require('gulp-postcss');
const stylefmt = require('gulp-stylefmt');
const sorting = require('postcss-sorting');
const torem = require('postcss-pxtorem');
const sortOrder = require('./.postcss-sorting.json');
const pkg = require('./package.json');

// Config
const build = {
	css: './dist/assets/css',
	html: './dist/views/',
	twig: './src/views/',
	data: './src/mock/',
	scss: './src/scss/',
	docs: './docs/_media/',
};

const AUTOPREFIXER_BROWSERS = [
	'ie >= 11',
	'edge >= 12',
	'ff >= 38',
	'chrome >= 35',
	'safari >= 8',
	'opera >= 35',
	'ios >= 8',
];

gulp.task('css', () => {
	const css = gulp
		.src(build.scss + '*.scss')
		.pipe(sourcemaps.init())
		.pipe(sass({
			indentType: 'tab',
			indentWidth: 1,
			outputStyle: 'expanded',
			precision: 10,
			onError: console.error.bind(console, 'Sass error:'),
		}))
		.pipe(autoprefixer(AUTOPREFIXER_BROWSERS))
		.pipe(
			postcss([
				sorting(sortOrder),
				torem({
					rootValue: 16,
					unitPrecision: 7,
					propWhiteList: [
						'font',
						'font-size',
						'margin',
						'margin-left',
						'margin-right',
						'margin-top',
						'margin-bottom',
						'padding',
						'padding-left',
						'padding-right',
						'padding-top',
						'padding-bottom',
					],
					selectorBlackList: [],
					replace: true,
					mediaQuery: false,
					minPixelValue: 0,
				}),
			])
		)
		.pipe(stylefmt())
		.pipe(rename({
			suffix: '.' + pkg.version,
			extname: '.css',
		}))
		.pipe(sourcemaps.write('./'))
		.pipe(gulp.dest(build.css));

	return css;
});

gulp.task('clean', () => {
	del([ 'dist', ]);
});

gulp.task('minify', gulp.series('css', () => {
	const css = gulp
		.src(build.css + '/*.' + pkg.version + '.css')
		.pipe(sourcemaps.init())
		.pipe(cssnano())
		.pipe(rename({
			suffix: '.min',
			extname: '.css',
		}))
		.pipe(sourcemaps.write('./'))
		.pipe(gulp.dest(build.css));

	return css;
}));

gulp.task('docs:css', () => {
	const css = gulp
		.src(build.docs + '*.scss')
		.pipe(sourcemaps.init())
		.pipe(sass({
			indentType: 'tab',
			indentWidth: 1,
			outputStyle: 'expanded',
			precision: 10,
			onError: console.error.bind(console, 'Sass error:'),
		}))
		.pipe(autoprefixer(AUTOPREFIXER_BROWSERS))
		.pipe(
			postcss([
				sorting(sortOrder),
				torem({
					rootValue: 16,
					unitPrecision: 7,
					propWhiteList: [
						'font',
						'font-size',
						'margin',
						'margin-left',
						'margin-right',
						'margin-top',
						'margin-bottom',
						'padding',
						'padding-left',
						'padding-right',
						'padding-top',
						'padding-bottom',
					],
					selectorBlackList: [],
					replace: true,
					mediaQuery: false,
					minPixelValue: 0,
				}),
			])
		)
		.pipe(stylefmt())
		.pipe(cssnano())
		.pipe(rename({
			suffix: '.' + pkg.version + '.min',
			extname: '.css',
		}))
		.pipe(sourcemaps.write('./'))
		.pipe(gulp.dest(build.docs));

	return css;
});

gulp.task('watch', () => {
	gulp.watch('src/scss/**/*.scss', gulp.series('css', 'minify'));
});

gulp.task('serve', gulp.series('watch'));
gulp.task('test', gulp.series('css', 'minify'));
gulp.task('default', gulp.series('css', 'minify', 'watch'));
<|endoftext|>


<commit_before>Ext.require([
    'Ext.container.Viewport',
    'Ext.layout.container.Border',
    'GeoExt.tree.Panel',
    'Ext.tree.plugin.TreeViewDragDrop',
    'GeoExt.panel.Map',
    'GeoExt.tree.LayerContainer',
    'GeoExt.data.LayerTreeModel',
    'GeoExt.tree.plugin.LayerTreeView',
    'GeoExt.tree.Column'
]);

var mapPanel, tree;

Ext.application({
    name: 'Tree',
    launch: function() {
        // create a map panel with some layers that we will show in our layer tree
        // below.
        mapPanel = Ext.create('GeoExt.panel.Map', {
            border: true,
            region: "center",
            // we do not want all overlays, to try the OverlayLayerContainer
            map: {allOverlays: false},
            center: [146.1569825, -41.6109735],
            zoom: 6,
            layers: [
                new OpenLayers.Layer.WMS("Global Imagery",
                    "http://maps.opengeo.org/geowebcache/service/wms", {
                        layers: "bluemarble",
                        format: "image/png8"
                    }, {
                        buffer: 0,
                        visibility: false
                    }
                ),
                new OpenLayers.Layer.WMS("Tasmania State Boundaries",
                    "http://demo.opengeo.org/geoserver/wms", {
                        layers: "topp:tasmania_state_boundaries"
                    }, {
                        buffer: 0
                    }
                ),
                new OpenLayers.Layer.WMS("Water",
                    "http://demo.opengeo.org/geoserver/wms", {
                        layers: "topp:tasmania_water_bodies",
                        transparent: true,
                        format: "image/gif"
                    }, {
                        isBaseLayer: false,
                        buffer: 0
                    }
                ),
                new OpenLayers.Layer.WMS("Cities",
                    "http://demo.opengeo.org/geoserver/wms", {
                        layers: "topp:tasmania_cities",
                        transparent: true,
                        format: "image/gif"
                    }, {
                        isBaseLayer: false,
                        buffer: 0
                    }
                ),
                new OpenLayers.Layer.WMS("Tasmania Roads",
                    "http://demo.opengeo.org/geoserver/wms", {
                        layers: "topp:tasmania_roads",
                        transparent: true,
                        format: "image/gif"
                    }, {
                        isBaseLayer: false,
                        buffer: 0,
                        maxResolution: 0.010986328125
                    }
                ),
                // create a group layer (with several layers in the "layers" param)
                // to show how the LayerParamLoader works
                new OpenLayers.Layer.WMS("Tasmania (Group Layer)",
                    "http://demo.opengeo.org/geoserver/wms", {
                        layers: [
                            "topp:tasmania_state_boundaries",
                            "topp:tasmania_water_bodies",
                            "topp:tasmania_cities",
                            "topp:tasmania_roads"
                        ],
                        transparent: true,
                        format: "image/gif"
                    }, {
                        isBaseLayer: false,
                        buffer: 0,
                        // exclude this layer from layer container nodes
                        displayInLayerSwitcher: false,
                        visibility: false
                    }
                )
            ]
        });

        // create our own layer node UI class, using the TreeNodeUIEventMixin
        //var LayerNodeUI = Ext.extend(GeoExt.tree.LayerNodeUI, new GeoExt.tree.TreeNodeUIEventMixin());

        /*var treeConfig = [
            {text: "myplainnode", leaf: true},
            {nodeType: 'gx_layercontainer', layerStore: map.layers}
        {
            nodeType: "gx_baselayercontainer"
        }, {
            nodeType: "gx_overlaylayercontainer",
            expanded: true,
            // render the nodes inside this container with a radio button,
            // and assign them the group "foo".
            loader: {
                baseAttrs: {
                    radioGroup: "foo",
                    uiProvider: "layernodeui"
                }
            }
        }, {
            nodeType: "gx_layer",
            layer: "Tasmania (Group Layer)",
            isLeaf: false,
            // create subnodes for the layers in the LAYERS param. If we assign
            // a loader to a LayerNode and do not provide a loader class, a
            // LayerParamLoader will be assumed.
            loader: {
                param: "LAYERS"
            }
        }];*/

        var store = Ext.create('Ext.data.TreeStore', {
            model: 'GeoExt.data.LayerTreeModel',
            root: {
                expanded: true,
                children: [
                    {text: "A plain node", leaf: true},
                    {plugins: ['gx_layercontainer']},
                    {plugins: [{
                        ptype: 'gx_layercontainer',
                        layers: mapPanel.layers
                    }], text: "My Layers", expanded: true}
                ]
            }
        });

        // create the tree with the configuration from above
        tree = Ext.create('GeoExt.tree.Panel', {
            border: true,
            region: "west",
            title: "Layers",
            width: 200,
            split: true,
            collapsible: true,
            collapseMode: "mini",
            autoScroll: true,
            store: store,
            rootVisible: false,
            lines: false,
            viewConfig: {
                plugins: [{
                    ptype: 'treeviewdragdrop',
                    appendOnly: false
                }, {
                    ptype: 'layertreeview'
                }]
            }
        });

        Ext.create('Ext.Viewport', {
            layout: "fit",
            hideBorders: true,
            items: {
                layout: "border",
                deferredRender: false,
                items: [mapPanel, tree, {
                    contentEl: "desc",
                    region: "east",
                    bodyStyle: {"padding": "5px"},
                    collapsible: true,
                    collapseMode: "mini",
                    split: true,
                    width: 200,
                    title: "Description"
                }]
            }
        });
    }
});
<commit_msg>Add copyright header.<commit_after>/**
 * Copyright (c) 2008-2012 The Open Source Geospatial Foundation
 *
 * Published under the BSD license.
 * See http://svn.geoext.org/core/trunk/geoext/license.txt for the full text
 * of the license.
 */

Ext.require([
    'Ext.container.Viewport',
    'Ext.layout.container.Border',
    'GeoExt.tree.Panel',
    'Ext.tree.plugin.TreeViewDragDrop',
    'GeoExt.panel.Map',
    'GeoExt.tree.LayerContainer',
    'GeoExt.data.LayerTreeModel',
    'GeoExt.tree.plugin.LayerTreeView',
    'GeoExt.tree.Column'
]);

var mapPanel, tree;

Ext.application({
    name: 'Tree',
    launch: function() {
        // create a map panel with some layers that we will show in our layer tree
        // below.
        mapPanel = Ext.create('GeoExt.panel.Map', {
            border: true,
            region: "center",
            // we do not want all overlays, to try the OverlayLayerContainer
            map: {allOverlays: false},
            center: [146.1569825, -41.6109735],
            zoom: 6,
            layers: [
                new OpenLayers.Layer.WMS("Global Imagery",
                    "http://maps.opengeo.org/geowebcache/service/wms", {
                        layers: "bluemarble",
                        format: "image/png8"
                    }, {
                        buffer: 0,
                        visibility: false
                    }
                ),
                new OpenLayers.Layer.WMS("Tasmania State Boundaries",
                    "http://demo.opengeo.org/geoserver/wms", {
                        layers: "topp:tasmania_state_boundaries"
                    }, {
                        buffer: 0
                    }
                ),
                new OpenLayers.Layer.WMS("Water",
                    "http://demo.opengeo.org/geoserver/wms", {
                        layers: "topp:tasmania_water_bodies",
                        transparent: true,
                        format: "image/gif"
                    }, {
                        isBaseLayer: false,
                        buffer: 0
                    }
                ),
                new OpenLayers.Layer.WMS("Cities",
                    "http://demo.opengeo.org/geoserver/wms", {
                        layers: "topp:tasmania_cities",
                        transparent: true,
                        format: "image/gif"
                    }, {
                        isBaseLayer: false,
                        buffer: 0
                    }
                ),
                new OpenLayers.Layer.WMS("Tasmania Roads",
                    "http://demo.opengeo.org/geoserver/wms", {
                        layers: "topp:tasmania_roads",
                        transparent: true,
                        format: "image/gif"
                    }, {
                        isBaseLayer: false,
                        buffer: 0,
                        maxResolution: 0.010986328125
                    }
                ),
                // create a group layer (with several layers in the "layers" param)
                // to show how the LayerParamLoader works
                new OpenLayers.Layer.WMS("Tasmania (Group Layer)",
                    "http://demo.opengeo.org/geoserver/wms", {
                        layers: [
                            "topp:tasmania_state_boundaries",
                            "topp:tasmania_water_bodies",
                            "topp:tasmania_cities",
                            "topp:tasmania_roads"
                        ],
                        transparent: true,
                        format: "image/gif"
                    }, {
                        isBaseLayer: false,
                        buffer: 0,
                        // exclude this layer from layer container nodes
                        displayInLayerSwitcher: false,
                        visibility: false
                    }
                )
            ]
        });

        // create our own layer node UI class, using the TreeNodeUIEventMixin
        //var LayerNodeUI = Ext.extend(GeoExt.tree.LayerNodeUI, new GeoExt.tree.TreeNodeUIEventMixin());

        /*var treeConfig = [
            {text: "myplainnode", leaf: true},
            {nodeType: 'gx_layercontainer', layerStore: map.layers}
        {
            nodeType: "gx_baselayercontainer"
        }, {
            nodeType: "gx_overlaylayercontainer",
            expanded: true,
            // render the nodes inside this container with a radio button,
            // and assign them the group "foo".
            loader: {
                baseAttrs: {
                    radioGroup: "foo",
                    uiProvider: "layernodeui"
                }
            }
        }, {
            nodeType: "gx_layer",
            layer: "Tasmania (Group Layer)",
            isLeaf: false,
            // create subnodes for the layers in the LAYERS param. If we assign
            // a loader to a LayerNode and do not provide a loader class, a
            // LayerParamLoader will be assumed.
            loader: {
                param: "LAYERS"
            }
        }];*/

        var store = Ext.create('Ext.data.TreeStore', {
            model: 'GeoExt.data.LayerTreeModel',
            root: {
                expanded: true,
                children: [
                    {text: "A plain node", leaf: true},
                    {plugins: ['gx_layercontainer']},
                    {plugins: [{
                        ptype: 'gx_layercontainer',
                        layers: mapPanel.layers
                    }], text: "My Layers", expanded: true}
                ]
            }
        });

        // create the tree with the configuration from above
        tree = Ext.create('GeoExt.tree.Panel', {
            border: true,
            region: "west",
            title: "Layers",
            width: 200,
            split: true,
            collapsible: true,
            collapseMode: "mini",
            autoScroll: true,
            store: store,
            rootVisible: false,
            lines: false,
            viewConfig: {
                plugins: [{
                    ptype: 'treeviewdragdrop',
                    appendOnly: false
                }, {
                    ptype: 'layertreeview'
                }]
            }
        });

        Ext.create('Ext.Viewport', {
            layout: "fit",
            hideBorders: true,
            items: {
                layout: "border",
                deferredRender: false,
                items: [mapPanel, tree, {
                    contentEl: "desc",
                    region: "east",
                    bodyStyle: {"padding": "5px"},
                    collapsible: true,
                    collapseMode: "mini",
                    split: true,
                    width: 200,
                    title: "Description"
                }]
            }
        });
    }
});
<|endoftext|>