<commit_before>dojo.provide("dijit.Toaster");

dojo.require("dojo.event.common");
dojo.require("dojo.event.topic");
dojo.require("dojo.lfx.html");
dojo.require("dojo.html.iframe");
dojo.require("dojo.string.extras");

dojo.require("dijit.base.Widget");
dojo.require("dijit.base.TemplatedWidget");

// This is mostly taken from <NAME>'s MessageNotifier.
// Modified by <NAME> to support topics and a variable delay.
// Modified by <NAME> to support 0 duration messages that require user interaction and message stacking

dojo.declare(
	"dijit.Toaster",
	[dijit.base.Widget, dijit.base.TemplatedWidget],
	null,
	{
		// summary
		//		Message that slides in from the corner of the screen, used for notifications
		//		like "new email".
		templateString: '<div dojoAttachPoint="clipNode"><div dojoAttachPoint="containerNode" dojoAttachEvent="onClick:onSelect"><div dojoAttachPoint="contentNode"></div></div></div>',

		// messageTopic: String
		//		Name of topic; anything published to this topic will be displayed as a message.
		//		Message format is either String or an object like
		//		{message: "hello word", type: "error", duration: 500}
		messageTopic: "",
		
		// messageTypes: Enumeration
		//		Possible message types.
		messageTypes: {
			MESSAGE: "message",
			WARNING: "warning",
			ERROR: "error",
			FATAL: "fatal"
		},

		// defaultType: String
		//		If message type isn't specified (see "messageTopic" parameter),
		//		then display message as this type.
		//		Possible values in messageTypes enumeration ("message", "warning", "error", "fatal")
		defaultType: "message",

		// positionDirection: String
		//		Position from which message slides into screen, one of
		//		["br-up", "br-left", "bl-up", "bl-right", "tr-down", "tr-left", "tl-down", "tl-right"]
		positionDirection: "br-up",
		
		// positionDirectionTypes: Array
		//		Possible values for positionDirection parameter
		positionDirectionTypes: ["br-up", "br-left", "bl-up", "bl-right", "tr-down", "tr-left", "tl-down", "tl-right"],

		// duration: Integer
		//		Number of milliseconds to show message
		duration: "2000",

		//separator: String
		//		String used to separate messages if consecutive calls are made to setContent before previous messages go away
		separator: "<hr></hr>",

		postCreate: function(){
			dijit.Toaster.superclass.postCreate.apply(this);
			this.hide();

			dojo.html.setClass(this.clipNode, "dojoToasterClip");
			dojo.html.addClass(this.containerNode, "dojoToasterContainer");
			dojo.html.setClass(this.contentNode, "dojoToasterContent");
			if(this.messageTopic){
				dojo.event.topic.subscribe(this.messageTopic, this, "_handleMessage");
			}
		},

		_handleMessage: function(/*String|Object*/message){
			if(dojo.lang.isString(message)){
				this.setContent(message);
			}else{
				this.setContent(message.message, message.type, message.duration);
			}
		},

		setContent: function(/*String|Node*/message, /*String*/messageType, /*int?*/duration){
			// summary
			//		sets and displays the given message and show duration
			// message:
			//		the message
			// messageType:
			//		type of message; possible values in messageTypes enumeration ("message", "warning", "error", "fatal")
			// duration:
			//		duration in milliseconds to display message before removing it. Widget has default value.
			duration = duration||this.duration;
			// sync animations so there are no ghosted fades and such
			if(this.slideAnim){
				if(this.slideAnim.status() != "playing"){
					this.slideAnim.stop();
				}
				if(this.slideAnim.status() == "playing" || (this.fadeAnim && this.fadeAnim.status() == "playing")){
					dojo.lang.setTimeout(50, dojo.lang.hitch(this, function(){
						this.setContent(message, messageType);
					}));
					return;
				}
			}

			// determine type of content and apply appropriately
			for(var type in this.messageTypes){
				dojo.html.removeClass(this.containerNode, "dojoToaster" + dojo.string.capitalize(this.messageTypes[type]));
			}
			dojo.html.clearOpacity(this.containerNode);

			if(dojo.html.isNode(message)){
				message = dojo.html.getContentAsString(message);
			}

			if(message && this.isVisible){
				message = this.contentNode.innerHTML + this.separator + message;
			}
			this.contentNode.innerHTML = message;

			dojo.html.addClass(this.containerNode, "dojoToaster" + dojo.string.capitalize(messageType || this.defaultType));

			// now do funky animation of widget appearing from
			// bottom right of page and up
			this.show();
			var nodeSize = dojo.html.getMarginBox(this.containerNode);
			
			if(this.isVisible){
				this._placeClip();
			}else{
				var style = this.containerNode.style;
				var pd = this.positionDirection;
				// sets up initial position of container node and slide-out direction
				if(pd.indexOf("-up") >= 0){
					style.left=0+"px";
					style.top=nodeSize.height + 10 + "px";
				}else if(pd.indexOf("-left") >= 0){
					style.left=nodeSize.width + 10 +"px";
					style.top=0+"px";
				}else if(pd.indexOf("-right") >= 0){
					style.left = 0 - nodeSize.width - 10 + "px";
					style.top = 0+"px";
				}else if(pd.indexOf("-down") >= 0){
					style.left = 0+"px";
					style.top = 0 - nodeSize.height - 10 + "px";
				}else{
					dojo.raise(this.widgetId + ".positionDirection is an invalid value: " + pd);
				}

				this.slideAnim = dojo.lfx.html.slideTo(
					this.containerNode,
					{ top: 0, left: 0 },
					450,
					null,
					dojo.lang.hitch(this, function(nodes, anim){
						//we build the fadeAnim here so we dont have to duplicate it later
						// can't do a fadeHide because we're fading the
						// inner node rather than the clipping node
						this.fadeAnim = dojo.lfx.html.fadeOut(
							this.containerNode,
							1000,
							null,
							dojo.lang.hitch(this, function(evt){
								this.isVisible = false;
								this.hide();<commit_msg>Fixes #2662.<commit_after>dojo.provide("dijit.Toaster");

dojo.require("dojo.event.common");
dojo.require("dojo.event.topic");
dojo.require("dojo.lfx.html");
dojo.require("dojo.html.iframe");
dojo.require("dojo.string.extras");

dojo.require("dijit.base.Widget");
dojo.require("dijit.base.TemplatedWidget");

// This is mostly taken from <NAME>'s MessageNotifier.
// Modified by <NAME> to support topics and a variable delay.
// Modified by <NAME> to support 0 duration messages that require user interaction and message stacking

dojo.declare(
	"dijit.Toaster",
	[dijit.base.Widget, dijit.base.TemplatedWidget],
	null,
	{
		// summary
		//		Message that slides in from the corner of the screen, used for notifications
		//		like "new email".
		templateString: '<div dojoAttachPoint="clipNode"><div dojoAttachPoint="containerNode" dojoAttachEvent="onClick:onSelect"><div dojoAttachPoint="contentNode"></div></div></div>',

		// messageTopic: String
		//		Name of topic; anything published to this topic will be displayed as a message.
		//		Message format is either String or an object like
		//		{message: "hello word", type: "error", duration: 500}
		messageTopic: "",
		
		// messageTypes: Enumeration
		//		Possible message types.
		messageTypes: {
			MESSAGE: "message",
			WARNING: "warning",
			ERROR: "error",
			FATAL: "fatal"
		},

		// defaultType: String
		//		If message type isn't specified (see "messageTopic" parameter),
		//		then display message as this type.
		//		Possible values in messageTypes enumeration ("message", "warning", "error", "fatal")
		defaultType: "message",

		// positionDirection: String
		//		Position from which message slides into screen, one of
		//		["br-up", "br-left", "bl-up", "bl-right", "tr-down", "tr-left", "tl-down", "tl-right"]
		positionDirection: "br-up",
		
		// positionDirectionTypes: Array
		//		Possible values for positionDirection parameter
		positionDirectionTypes: ["br-up", "br-left", "bl-up", "bl-right", "tr-down", "tr-left", "tl-down", "tl-right"],

		// duration: Integer
		//		Number of milliseconds to show message
		duration: "2000",

		//separator: String
		//		String used to separate messages if consecutive calls are made to setContent before previous messages go away
		separator: "<hr></hr>",

		postCreate: function(){
			dijit.Toaster.superclass.postCreate.apply(this);
			this.hide();

			dojo.html.setClass(this.clipNode, "dojoToasterClip");
			dojo.html.addClass(this.containerNode, "dojoToasterContainer");
			dojo.html.setClass(this.contentNode, "dojoToasterContent");
			if(this.messageTopic){
				dojo.event.topic.subscribe(this.messageTopic, this, "_handleMessage");
			}
		},

		_handleMessage: function(/*String|Object*/message){
			if(dojo.lang.isString(message)){
				this.setContent(message);
			}else{
				this.setContent(message.message, message.type, message.duration);
			}
		},

		setContent: function(/*String|Node*/message, /*String*/messageType, /*int?*/duration){
			// summary
			//		sets and displays the given message and show duration
			// message:
			//		the message
			// messageType:
			//		type of message; possible values in messageTypes enumeration ("message", "warning", "error", "fatal")
			// duration:
			//		duration in milliseconds to display message before removing it. Widget has default value.
			duration = duration||this.duration;
			// sync animations so there are no ghosted fades and such
			if(this.slideAnim){
				if(this.slideAnim.status() != "playing"){
					this.slideAnim.stop();
				}
				if(this.slideAnim.status() == "playing" || (this.fadeAnim && this.fadeAnim.status() == "playing")){
					dojo.lang.setTimeout(50, dojo.lang.hitch(this, function(){
						this.setContent(message, messageType);
					}));
					return;
				}
			}

			// determine type of content and apply appropriately
			for(var type in this.messageTypes){
				dojo.html.removeClass(this.containerNode, "dojoToaster" + dojo.string.capitalize(this.messageTypes[type]));
			}
			dojo.html.clearOpacity(this.containerNode);

			if(dojo.html.isNode(message)){
				message = dojo.html.getContentAsString(message);
			}

			if(message && this.isVisible){
				message = this.contentNode.innerHTML + this.separator + message;
			}
			this.contentNode.innerHTML = message;

			dojo.html.addClass(this.containerNode, "dojoToaster" + dojo.string.capitalize(messageType || this.defaultType));

			// now do funky animation of widget appearing from
			// bottom right of page and up
			this.show();
			var nodeSize = dojo.html.getMarginBox(this.containerNode);
			
			if(this.isVisible){
				this._placeClip();
			}else{
				var style = this.containerNode.style;
				var pd = this.positionDirection;
				// sets up initial position of container node and slide-out direction
				if(pd.indexOf("-up") >= 0){
					style.left=0+"px";
					style.top=nodeSize.height + 10 + "px";
				}else if(pd.indexOf("-left") >= 0){
					style.left=nodeSize.width + 10 +"px";
					style.top=0+"px";
				}else if(pd.indexOf("-right") >= 0){
					style.left = 0 - nodeSize.width - 10 + "px";
					style.top = 0+"px";
				}else if(pd.indexOf("-down") >= 0){
					style.left = 0+"px";
					style.top = 0 - nodeSize.height - 10 + "px";
				}else{
					dojo.raise(this.id + ".positionDirection is an invalid value: " + pd);
				}

				this.slideAnim = dojo.lfx.html.slideTo(
					this.containerNode,
					{ top: 0, left: 0 },
					450,
					null,
					dojo.lang.hitch(this, function(nodes, anim){
						//we build the fadeAnim here so we dont have to duplicate it later
						// can't do a fadeHide because we're fading the
						// inner node rather than the clipping node
						this.fadeAnim = dojo.lfx.html.fadeOut(
							this.containerNode,
							1000,
							null,
							dojo.lang.hitch(this, function(evt){
								this.isVisible = false;
								this.hide();
{'fraction_non_alphanumeric': 0.1452427849618909, 'fraction_numerical': 0.006679797893294511, 'mean_word_length': 3.4051301395699736, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7000520', 'n_tokens_mistral': 4478, 'n_tokens_neox': 3673, 'n_words': 922}