<commit_before>/**
 * @author Gilles Coomans <gilles.coomans@gmail.com>
 */
if(typeof define !== 'function')
	var define = require('amdefine')(module);

define(function(require, exports, module){
	var promise = require("./promise");
	// console.log("Deep-compose init");

	var DeepDecorator = function (stack) {
		this.stack = stack || [];
	};

	function chain(before, after)
	{
		return function () {
			var self = this;
			var args = arguments;
			var def = promise.Deferred();
			var r = before.apply(this, args);
			//console.log("chain.first : result == ", r)

			if(typeof r === 'undefined')
			{
				//console.log("chain.first : result == undefined")
				r = after.apply(self,args);
				//console.log("chain.second : result : ", r)
				if(typeof r === 'undefined')
					return r;
				if(!r.then)
					return r;
				promise.when(r)
				.then(function (suc) {
					def.resolve(suc);
				}, function (error) {
					def.reject(error);
				});
			}
			else if(!r.then)
			{
				r = after.apply(self,[r]);
				if(typeof r === 'undefined')
					return r;
				if(!r.then)
					return r;
				promise.when(r).then(function (suc) {
					//	console.log("chain.second.promise.when : result : ", suc)
					def.resolve(suc);
				}, function (error) {
					def.reject(error);
				});
			}
			else
			{
				//console.log("________________BEFORE promise.when___________");
				promise.when(r).then(function (r)
				{
					//console.log("after : promise.when(first) res : ", r);
					var argus = args ;
					if(typeof r !== 'undefined' )
						argus = [r];
					r = after.apply(self,argus);
					if(typeof r === 'undefined' )
						return	def.resolve(r);
					if(!r.then)
						return def.resolve(r);
					promise.when(r).then(function (suc) {
						def.resolve(suc);
					}, function (error) {
						def.reject(error);
					});
				}, function (error) {
					def.reject(error);
				});
			}
			return promise.promise(def);
		};
	}
	DeepDecorator.prototype = {
		around : function (argument)
		{
			var wrapper = function (previous)
			{
				return argument(previous);
			};
			this.stack.push(wrapper);
			return this;
		},
		after : function (argument)
		{
			var wrapper = function (previous)
			{
				return chain(previous, argument);
			};
			this.stack.push(wrapper);
			return this;
		},
		fail : function (fn)
		{
			var wrapper = function (previous)
			{
				return function()
				{
					var self = this;
					var args = arguments;
					return promise.when(previous.apply(this, args))
					.done(function (res) {
						console.log("compose.fail : previous done : ", res);
						if(res instanceof Error)
							return fn.apply(self, [res]);
						return res;
					})
					.fail(function (error) {
						console.log("compose.fail : previous error : ", error);
						return fn.apply(self, [error]);
					});
				};
			};
			this.stack.push(wrapper);
			return this;
		},
		before : function (argument)
		{
			var wrapper = function (previous)
			{
				return chain(argument, previous);
			};
			this.stack.push(wrapper);
			return this;
		},
		replace : function (argument)
		{
			var wrapper = function (previous)
			{
				return argument;
			};
			this.stack.push(wrapper);
			return this;
		},
		parallele : function (argument)
		{
			var wrapper = function (previous)
			{
				return function ()
				{
					var args = arguments;
					var promises = [argument.apply(this, args), previous.apply(this,args)];
					return promise.all(promises);
				};
			};
			this.stack.push(wrapper);
			return this;
		}
	};
	var createStart = function (decorator)
	{
		decorator = decorator || new DeepDecorator();
		var start = function () {
			if(!decorator.createIfNecessary)
				throw new Error("Decorator not applied ! (start)");
			return compose.wrap(function(){}, decorator).apply(this, arguments);
		};
		start.decorator = decorator;
		start.after = function (argument) {
			decorator.after(argument);
			return start;
		};
		start.before = function (argument) {
			decorator.before(argument);
			return start;
		};
		start.fail = function (argument) {
			decorator.fail(argument);
			return start;
		};
		start.around = function (argument) {
			decorator.around(argument);
			return start;
		};
		start.parallele = function (argument) {
			decorator.parallele(argument);
			return start;
		};
		start.replace = function (argument) {
			decorator.replace(argument);
			return start;
		};
		start.createIfNecessary = function (arg) {
			start.decorator.createIfNecessary = (typeof arg === 'undefined')?true:arg;
			return start;
		};
		start.ifExists = function (arg) {
			start.decorator.ifExists = (typeof arg === 'undefined')?true:arg;
			return start;
		};
		start.condition = function (arg) {
			start.condition = arg;
			return start;
		};
		return start;
	};

	var compose = {
		Decorator:DeepDecorator,
		cloneStart:function (start) {
			var newStack = start.decorator.stack.concat([]);
			var nd = new DeepDecorator(newStack);
			nd.ifExists = start.decorator.ifExists;
			nd.createIfNecessary = start.decorator.createIfNecessary;
			return createStart(nd);
		},
		wrap:function (func, decorator)
		{
			var fin = func;
			decorator.stack.forEach(function (wrapper)
			{
				fin = wrapper(fin);
			});
			return fin;
		},
		createIfNecessary : function ()
		{
			var start = createStart();
			start.decorator.createIfNecessary = true;
			return start;
		},
		ifExists : function ()
		{
			var start = createStart();
			start.decorator.ifExists = true;
			return start;
		},
		condition:function (argument) {
			var start = createStart();
			start.decorator.condition = argument;
			return start;
		},
		up : function (bottom, up)
		{
			if(typeof up !== 'function' || typeof bottom !== 'function')
				throw new Error("DeepDecorator.collide : you could only apply function together");
			if(!up.decorator || !(up.decorator instanceof DeepDecorator))
				return up;
			if(bottom.decorator && bottom.decorator instanceof DeepDecorator)
			{
				bottom.decorator.stack = bottom.decorator.stack.concat(up.decorator.stack);
				return bottom;
			}
			return compose.wrap(bottom,up.decorator);
		},
		bottom : function (bottom, up)
		{
			if(typeof up !== 'function' || typeof bottom !== 'function')
				throw new Error("DeepDecorator.collide : you could only apply function together");
			if(!up.decorator || !(up.decorator instanceof DeepDecorator))
				return up;
			if(bottom.decorator && bottom.decorator instanceof DeepDecorator)
			{
				up.decorator.stack = bottom.decorator.stack.concat(up.decorator.stack);
				return up;
			}
			return compose.wrap(bottom,up.decorator);
		},
		around : function (argument)
		{
			return createStart().around(argument);
		},
		after : function (argument)
		{
			return createStart().after(argument);
		},
		before : function (argument)
		{
			return createStart().before(argument);
		},
		fail : function (argument)
		{
			return createStart().fail(argument);
		},
		parallele : function (argument)
		{
			return createStart().parallele(argument);
		},
		replace : function (argument)
		{
			return createStart().replace(argument);
		}
	};
	// console.log("Deep-compose initialised");

	return compose;
});<commit_msg>remove log in compose.fail<commit_after>/**
 * @author Gilles Coomans <gilles.coomans@gmail.com>
 */
if(typeof define !== 'function')
	var define = require('amdefine')(module);

define(function(require, exports, module){
	var promise = require("./promise");
	// console.log("Deep-compose init");

	var DeepDecorator = function (stack) {
		this.stack = stack || [];
	};

	function chain(before, after)
	{
		return function () {
			var self = this;
			var args = arguments;
			var def = promise.Deferred();
			var r = before.apply(this, args);
			//console.log("chain.first : result == ", r)

			if(typeof r === 'undefined')
			{
				//console.log("chain.first : result == undefined")
				r = after.apply(self,args);
				//console.log("chain.second : result : ", r)
				if(typeof r === 'undefined')
					return r;
				if(!r.then)
					return r;
				promise.when(r)
				.then(function (suc) {
					def.resolve(suc);
				}, function (error) {
					def.reject(error);
				});
			}
			else if(!r.then)
			{
				r = after.apply(self,[r]);
				if(typeof r === 'undefined')
					return r;
				if(!r.then)
					return r;
				promise.when(r).then(function (suc) {
					//	console.log("chain.second.promise.when : result : ", suc)
					def.resolve(suc);
				}, function (error) {
					def.reject(error);
				});
			}
			else
			{
				//console.log("________________BEFORE promise.when___________");
				promise.when(r).then(function (r)
				{
					//console.log("after : promise.when(first) res : ", r);
					var argus = args ;
					if(typeof r !== 'undefined' )
						argus = [r];
					r = after.apply(self,argus);
					if(typeof r === 'undefined' )
						return	def.resolve(r);
					if(!r.then)
						return def.resolve(r);
					promise.when(r).then(function (suc) {
						def.resolve(suc);
					}, function (error) {
						def.reject(error);
					});
				}, function (error) {
					def.reject(error);
				});
			}
			return promise.promise(def);
		};
	}
	DeepDecorator.prototype = {
		around : function (argument)
		{
			var wrapper = function (previous)
			{
				return argument(previous);
			};
			this.stack.push(wrapper);
			return this;
		},
		after : function (argument)
		{
			var wrapper = function (previous)
			{
				return chain(previous, argument);
			};
			this.stack.push(wrapper);
			return this;
		},
		fail : function (fn)
		{
			var wrapper = function (previous)
			{
				return function()
				{
					var self = this;
					var args = arguments;
					return promise.when(previous.apply(this, args))
					.done(function (res) {
						//console.log("compose.fail : previous done : ", res);
						if(res instanceof Error)
							return fn.apply(self, [res]);
						return res;
					})
					.fail(function (error) {
						//console.log("compose.fail : previous error : ", error);
						return fn.apply(self, [error]);
					});
				};
			};
			this.stack.push(wrapper);
			return this;
		},
		before : function (argument)
		{
			var wrapper = function (previous)
			{
				return chain(argument, previous);
			};
			this.stack.push(wrapper);
			return this;
		},
		replace : function (argument)
		{
			var wrapper = function (previous)
			{
				return argument;
			};
			this.stack.push(wrapper);
			return this;
		},
		parallele : function (argument)
		{
			var wrapper = function (previous)
			{
				return function ()
				{
					var args = arguments;
					var promises = [argument.apply(this, args), previous.apply(this,args)];
					return promise.all(promises);
				};
			};
			this.stack.push(wrapper);
			return this;
		}
	};
	var createStart = function (decorator)
	{
		decorator = decorator || new DeepDecorator();
		var start = function () {
			if(!decorator.createIfNecessary)
				throw new Error("Decorator not applied ! (start)");
			return compose.wrap(function(){}, decorator).apply(this, arguments);
		};
		start.decorator = decorator;
		start.after = function (argument) {
			decorator.after(argument);
			return start;
		};
		start.before = function (argument) {
			decorator.before(argument);
			return start;
		};
		start.fail = function (argument) {
			decorator.fail(argument);
			return start;
		};
		start.around = function (argument) {
			decorator.around(argument);
			return start;
		};
		start.parallele = function (argument) {
			decorator.parallele(argument);
			return start;
		};
		start.replace = function (argument) {
			decorator.replace(argument);
			return start;
		};
		start.createIfNecessary = function (arg) {
			start.decorator.createIfNecessary = (typeof arg === 'undefined')?true:arg;
			return start;
		};
		start.ifExists = function (arg) {
			start.decorator.ifExists = (typeof arg === 'undefined')?true:arg;
			return start;
		};
		start.condition = function (arg) {
			start.condition = arg;
			return start;
		};
		return start;
	};

	var compose = {
		Decorator:DeepDecorator,
		cloneStart:function (start) {
			var newStack = start.decorator.stack.concat([]);
			var nd = new DeepDecorator(newStack);
			nd.ifExists = start.decorator.ifExists;
			nd.createIfNecessary = start.decorator.createIfNecessary;
			return createStart(nd);
		},
		wrap:function (func, decorator)
		{
			var fin = func;
			decorator.stack.forEach(function (wrapper)
			{
				fin = wrapper(fin);
			});
			return fin;
		},
		createIfNecessary : function ()
		{
			var start = createStart();
			start.decorator.createIfNecessary = true;
			return start;
		},
		ifExists : function ()
		{
			var start = createStart();
			start.decorator.ifExists = true;
			return start;
		},
		condition:function (argument) {
			var start = createStart();
			start.decorator.condition = argument;
			return start;
		},
		up : function (bottom, up)
		{
			if(typeof up !== 'function' || typeof bottom !== 'function')
				throw new Error("DeepDecorator.collide : you could only apply function together");
			if(!up.decorator || !(up.decorator instanceof DeepDecorator))
				return up;
			if(bottom.decorator && bottom.decorator instanceof DeepDecorator)
			{
				bottom.decorator.stack = bottom.decorator.stack.concat(up.decorator.stack);
				return bottom;
			}
			return compose.wrap(bottom,up.decorator);
		},
		bottom : function (bottom, up)
		{
			if(typeof up !== 'function' || typeof bottom !== 'function')
				throw new Error("DeepDecorator.collide : you could only apply function together");
			if(!up.decorator || !(up.decorator instanceof DeepDecorator))
				return up;
			if(bottom.decorator && bottom.decorator instanceof DeepDecorator)
			{
				up.decorator.stack = bottom.decorator.stack.concat(up.decorator.stack);
				return up;
			}
			return compose.wrap(bottom,up.decorator);
		},
		around : function (argument)
		{
			return createStart().around(argument);
		},
		after : function (argument)
		{
			return createStart().after(argument);
		},
		before : function (argument)
		{
			return createStart().before(argument);
		},
		fail : function (argument)
		{
			return createStart().fail(argument);
		},
		parallele : function (argument)
		{
			return createStart().parallele(argument);
		},
		replace : function (argument)
		{
			return createStart().replace(argument);
		}
	};
	// console.log("Deep-compose initialised");

	return compose;
});<|endoftext|>


<commit_before>"use strict";

/* eslint-disable jsdoc/require-jsdoc */

(function main() {
  // DOM elements
  var markdown = document.getElementById("markdown");
  var markup = document.getElementById("markup");
  var numbered = document.getElementById("numbered");
  var violations = document.getElementById("violations");
  var form = document.getElementsByTagName("form")[0];
  var openFile = document.getElementById("openFile");
  var copyLink = document.getElementById("copyLink");

  // Variables
  var markdownit = window.markdownit({ "html": true });
  var newLineRe = /\r\n|\r|\n/;
  var hashPrefix = "%m";
  var rulesMd = "https://github.com/DavidAnson/markdownlint" +
    "/blob/master/doc/Rules.md";

  // Do-nothing function
  function noop() {}

  // Sanitize string for HTML display
  function sanitize(str) {
    return str
      .replace(/&/g, "&")
      .replace(/</g, "<")
      .replace(/>/g, ">");
  }

  // Handle input
  function onMarkdownInput() {
    // Markdown
    var content = markdown.value;
    // Markup
    markup.innerHTML = markdownit.render(content);
    // Numbered
    var lines = content.split(newLineRe);
    var padding = lines.length.toString().replace(/\d/g, " ");
    numbered.innerHTML = lines
      .map(function mapNumberedLine(line, index) {
        line = sanitize(line);
        index++;
        var paddedIndex = (padding + index).slice(-padding.length);
        return "" + paddedIndex + ": " +
          line + "";
      }).join("\n");
    // Violations
    var options = {
      "strings": {
        "content": content
      },
      "config": {
        "MD013": false
      },
      "handleRuleFailures": true
    };
    var results = window.markdownlint.sync(options);
    violations.innerHTML = results.content.map(function mapResult(result) {
      var ruleName = result.ruleNames[0];
      var ruleRef = rulesMd + "#" + ruleName.toLowerCase() + "---" +
        result.ruleDescription.toLowerCase()
          .replace(/ /g, "-")
          .replace(/[()]/g, "");
      return "" + result.lineNumber +
        " - " + ruleName + " " +
        result.ruleDescription +
        (result.errorDetail ?
          " [" +
            sanitize(result.errorDetail) +
            "]" :
          "") +
        (result.errorContext ?
          " [Context: \"" +
            sanitize(result.errorContext) +
            "\"]" :
          "");
      // + (result.errorRange ?
      //     " " +
      //       lines[result.lineNumber - 1].substr(
      //         result.errorRange[0] - 1, result.errorRange[1]) +
      //     "" :
      //     "");
    }).join("
");
  }

  // Load from a string or File object
  function loadMarkdown(source) {
    // Reset input element
    form.reset();
    if (typeof source === "string") {
      // Update from string
      markdown.value = source;
      onMarkdownInput();
    } else {
      // Update from File object
      var reader = new FileReader();
      reader.onload = function onload(e) {
        markdown.value = e.target.result;
        onMarkdownInput();
      };
      reader.readAsText(source);
    }
  }

  // Handle drag-and-drop
  function onDragOver(e) {
    if (e.dataTransfer && e.dataTransfer.dropEffect) {
      e.dataTransfer.dropEffect = "link";
      e.preventDefault();
    }
  }
  function onDrop(e) {
    if (e.dataTransfer && e.dataTransfer.files) {
      loadMarkdown(e.dataTransfer.files[0]);
      e.preventDefault();
    }
  }

  // Handle file open
  function onOpenFileChange(e) {
    if (e.target && e.target.files) {
      loadMarkdown(e.target.files[0]);
    }
  }

  // Handle violation navigation
  function onLineNumberClick(e) {
    var line = document.getElementById("l" + e.target.textContent);
    if (line) {
      var highlighted = document.getElementsByClassName("highlight");
      Array.prototype.forEach.call(highlighted, function forElement(element) {
        element.classList.remove("highlight");
      });
      line.classList.add("highlight");
      line.scrollIntoView();
      e.preventDefault();
    }
  }

  // Updates the URL hash and copies the URL to the clipboard
  function onCopyLinkClick(e) {
    window.location.hash = encodeURIComponent(hashPrefix + markdown.value);
    /* eslint-disable-next-line no-unused-expressions */
    navigator.clipboard && navigator.clipboard.writeText &&
      navigator.clipboard.writeText(window.location).then(noop, noop);
    e.preventDefault();
  }

  // Add event listeners
  document.body.addEventListener("dragover", onDragOver);
  document.body.addEventListener("drop", onDrop);
  openFile.addEventListener("change", onOpenFileChange);
  markdown.addEventListener("input", onMarkdownInput);
  violations.addEventListener("click", onLineNumberClick, true);
  copyLink.addEventListener("click", onCopyLinkClick);

  /* eslint-disable max-len */
  markdown.value = [
    "## Introduction",
    "",
    "`markdownlint` is a [Node.js](https://nodejs.org/) style checker and lint tool for [Markdown](https://en.wikipedia.org/wiki/Markdown)/[CommonMark](https://commonmark.org/) files to automatically validate content, prevent rendering problems, and promote consistency.",
    "This page offers an easy way to try it out interactively!",
    "",
    "####  Instructions",
    "",
    "Type or paste `Markdown ` content in the upper-left box, drag-and-drop a file, or open one with the chooser at the top.",
    "Content gets parsed and displayed in the upper-right box; rule violations (if any) show up in the lower-right box.",
    "Click a violation for information about it or click its line number to highlighted it in the lower-left box.",
    "",
    "> *Note*: [All rules](https://github.com/DavidAnson/markdownlint/blob/master/doc/Rules.md) are enabled except [MD013/line-length](https://github.com/DavidAnson/markdownlint/blob/master/doc/Rules.md#md013) and [MD002/first-heading-h1](https://github.com/DavidAnson/markdownlint/blob/master/doc/Rules.md#md002) (deprecated). ",
    "",
    "",
    "#### Resources",
    "* [`markdownlint` on GitHub](https://github.com/DavidAnson/markdownlint)",
    "* [`markdownlint` on npm](https://www.npmjs.com/package/markdownlint)",
    "* [Markdown specification](https://daringfireball.net/projects/markdown/)",
    "*\t[CommonMark specification](https://commonmark.org/)",
    "",
    "#### Thanks",
    "",
    "[`markdownlint/Ruby`](https://github.com/markdownlint/markdownlint) for the inspiration and [`markdown-it`](https://github.com/markdown-it/markdown-it) for the parser and interactive demo idea!",
    ""
  ].join("\n");
  /* eslint-enable max-len */

  // Update Markdown from hash (if present)
  if (window.location.hash) {
    try {
      const decodedHash = decodeURIComponent(window.location.hash.substring(1));
      if (hashPrefix === decodedHash.substring(0, hashPrefix.length)) {
        markdown.value = decodedHash.substring(hashPrefix.length);
      }
    } catch (ex) {
      // Invalid
    }
  }

  // Detect legacy browsers
  try {
    /* eslint-disable-next-line no-new */
    new URL(rulesMd);
  } catch (ex) {
    markdown.value = [
      "# Sorry",
      "",
      "This browser is not supported."
    ].join("\n");
  }

  // Initialize
  onMarkdownInput();
}());
<commit_msg>Add fallback for demo "Copy Link" functionality on browsers that do not support navigator.clipboard.<commit_after>"use strict";

/* eslint-disable jsdoc/require-jsdoc */

(function main() {
  // DOM elements
  var markdown = document.getElementById("markdown");
  var markup = document.getElementById("markup");
  var numbered = document.getElementById("numbered");
  var violations = document.getElementById("violations");
  var form = document.getElementsByTagName("form")[0];
  var openFile = document.getElementById("openFile");
  var copyLink = document.getElementById("copyLink");

  // Variables
  var markdownit = window.markdownit({ "html": true });
  var newLineRe = /\r\n|\r|\n/;
  var hashPrefix = "%m";
  var rulesMd = "https://github.com/DavidAnson/markdownlint" +
    "/blob/master/doc/Rules.md";

  // Do-nothing function
  function noop() {}

  // Sanitize string for HTML display
  function sanitize(str) {
    return str
      .replace(/&/g, "&")
      .replace(/</g, "<")
      .replace(/>/g, ">");
  }

  // Handle input
  function onMarkdownInput() {
    // Markdown
    var content = markdown.value;
    // Markup
    markup.innerHTML = markdownit.render(content);
    // Numbered
    var lines = content.split(newLineRe);
    var padding = lines.length.toString().replace(/\d/g, " ");
    numbered.innerHTML = lines
      .map(function mapNumberedLine(line, index) {
        line = sanitize(line);
        index++;
        var paddedIndex = (padding + index).slice(-padding.length);
        return "" + paddedIndex + ": " +
          line + "";
      }).join("\n");
    // Violations
    var options = {
      "strings": {
        "content": content
      },
      "config": {
        "MD013": false
      },
      "handleRuleFailures": true
    };
    var results = window.markdownlint.sync(options);
    violations.innerHTML = results.content.map(function mapResult(result) {
      var ruleName = result.ruleNames[0];
      var ruleRef = rulesMd + "#" + ruleName.toLowerCase() + "---" +
        result.ruleDescription.toLowerCase()
          .replace(/ /g, "-")
          .replace(/[()]/g, "");
      return "" + result.lineNumber +
        " - " + ruleName + " " +
        result.ruleDescription +
        (result.errorDetail ?
          " [" +
            sanitize(result.errorDetail) +
            "]" :
          "") +
        (result.errorContext ?
          " [Context: \"" +
            sanitize(result.errorContext) +
            "\"]" :
          "");
      // + (result.errorRange ?
      //     " " +
      //       lines[result.lineNumber - 1].substr(
      //         result.errorRange[0] - 1, result.errorRange[1]) +
      //     "" :
      //     "");
    }).join("
");
  }

  // Load from a string or File object
  function loadMarkdown(source) {
    // Reset input element
    form.reset();
    if (typeof source === "string") {
      // Update from string
      markdown.value = source;
      onMarkdownInput();
    } else {
      // Update from File object
      var reader = new FileReader();
      reader.onload = function onload(e) {
        markdown.value = e.target.result;
        onMarkdownInput();
      };
      reader.readAsText(source);
    }
  }

  // Handle drag-and-drop
  function onDragOver(e) {
    if (e.dataTransfer && e.dataTransfer.dropEffect) {
      e.dataTransfer.dropEffect = "link";
      e.preventDefault();
    }
  }
  function onDrop(e) {
    if (e.dataTransfer && e.dataTransfer.files) {
      loadMarkdown(e.dataTransfer.files[0]);
      e.preventDefault();
    }
  }

  // Handle file open
  function onOpenFileChange(e) {
    if (e.target && e.target.files) {
      loadMarkdown(e.target.files[0]);
    }
  }

  // Handle violation navigation
  function onLineNumberClick(e) {
    var line = document.getElementById("l" + e.target.textContent);
    if (line) {
      var highlighted = document.getElementsByClassName("highlight");
      Array.prototype.forEach.call(highlighted, function forElement(element) {
        element.classList.remove("highlight");
      });
      line.classList.add("highlight");
      line.scrollIntoView();
      e.preventDefault();
    }
  }

  // Updates the URL hash and copies the URL to the clipboard
  function onCopyLinkClick(e) {
    window.location.hash = encodeURIComponent(hashPrefix + markdown.value);
    if (navigator.clipboard && navigator.clipboard.writeText) {
      navigator.clipboard.writeText(window.location).then(noop, noop);
    } else {
      /* eslint-disable-next-line no-alert */
      alert("Document URL updated, select and copy it now.");
    }
    e.preventDefault();
  }

  // Add event listeners
  document.body.addEventListener("dragover", onDragOver);
  document.body.addEventListener("drop", onDrop);
  openFile.addEventListener("change", onOpenFileChange);
  markdown.addEventListener("input", onMarkdownInput);
  violations.addEventListener("click", onLineNumberClick, true);
  copyLink.addEventListener("click", onCopyLinkClick);

  /* eslint-disable max-len */
  markdown.value = [
    "## Introduction",
    "",
    "`markdownlint` is a [Node.js](https://nodejs.org/) style checker and lint tool for [Markdown](https://en.wikipedia.org/wiki/Markdown)/[CommonMark](https://commonmark.org/) files to automatically validate content, prevent rendering problems, and promote consistency.",
    "This page offers an easy way to try it out interactively!",
    "",
    "####  Instructions",
    "",
    "Type or paste `Markdown ` content in the upper-left box, drag-and-drop a file, or open one with the chooser at the top.",
    "Content gets parsed and displayed in the upper-right box; rule violations (if any) show up in the lower-right box.",
    "Click a violation for information about it or click its line number to highlighted it in the lower-left box.",
    "",
    "> *Note*: [All rules](https://github.com/DavidAnson/markdownlint/blob/master/doc/Rules.md) are enabled except [MD013/line-length](https://github.com/DavidAnson/markdownlint/blob/master/doc/Rules.md#md013) and [MD002/first-heading-h1](https://github.com/DavidAnson/markdownlint/blob/master/doc/Rules.md#md002) (deprecated). ",
    "",
    "",
    "#### Resources",
    "* [`markdownlint` on GitHub](https://github.com/DavidAnson/markdownlint)",
    "* [`markdownlint` on npm](https://www.npmjs.com/package/markdownlint)",
    "* [Markdown specification](https://daringfireball.net/projects/markdown/)",
    "*\t[CommonMark specification](https://commonmark.org/)",
    "",
    "#### Thanks",
    "",
    "[`markdownlint/Ruby`](https://github.com/markdownlint/markdownlint) for the inspiration and [`markdown-it`](https://github.com/markdown-it/markdown-it) for the parser and interactive demo idea!",
    ""
  ].join("\n");
  /* eslint-enable max-len */

  // Update Markdown from hash (if present)
  if (window.location.hash) {
    try {
      const decodedHash = decodeURIComponent(window.location.hash.substring(1));
      if (hashPrefix === decodedHash.substring(0, hashPrefix.length)) {
        markdown.value = decodedHash.substring(hashPrefix.length);
      }
    } catch (ex) {
      // Invalid
    }
  }

  // Detect legacy browsers
  try {
    /* eslint-disable-next-line no-new */
    new URL(rulesMd);
  } catch (ex) {
    markdown.value = [
      "# Sorry",
      "",
      "This browser is not supported."
    ].join("\n");
  }

  // Initialize
  onMarkdownInput();
}());
<|endoftext|>


<commit_before>"use strict";

// Create the json representation of the knowledge graph
var resources = [
  {
    label: 'Knowledge map introduction',
    teaches: ['What a knowledge map is'],
    content: [{
      text: "Knowledge maps are like a roadmap for pieces of knowledge. They can be used to show others how to navigate from their current set of knowledge to a particular goal. Or they can be used to find people who know something you haven't learnt yet.",
    }]
  },
  {
    label: 'Learn how to view a knowledge map',
    requires: ['What a knowledge map is'],
    teaches: ['How to view a knowledge map'],
    content: [{
      text: "You're doing it right now! Each of the labelled points on the page is called a 'concept' and the arrows joining them are called 'dependencies'. Concepts are pieces of information that can be learned if you have learned all of the concepts which point to it. That is, if you want to learn a concept learn all of its dependencies!",
    }]
  },
  {
    label: 'Learning using knowledge maps',
    requires: ['How to view a knowledge map'],
    teaches: ['Learning with knowledge maps'],
    content: [{
      text: "You can learn by using the resources attached to a concept or by contacting people who know the concept. The best knowledge maps will give you lots of different resources to try and learn each concept.",
    }]
  },
  {
    label: 'Create your own knowledge map',
    requires: ['What a knowledge map is', 'How to view a knowledge map'],
    teaches: ['Creating knowledge maps'],
    content: [{
      text: "If you want to share how to do or learn something then create your own map! This concept links to an interactive demonstration that will allow you to create your own knowledge map.",
    }, {
      description: "If you want to share how to do or learn something then create your own map! This concept links to an interactive demonstration that will allow you to create your own knowledge map.",
      title: "Graph editing demo",
      link: "/demo/edit.html"
    }, {
      description: "If you want to share how to do or learn something then create your own map! This concept links to an interactive demonstration that will allow you to create your own knowledge map.",
      title: "Graph editing demo",
      link: "/demo/edit.html"
    }]
  },
  {
    label: 'Sharing your new knowledge map',
    requires: ['Creating knowledge maps'],
    teaches: ['Sharing knowledge maps'],
    content: [{
      text: "Once you've created your own knowledge map you can share it in various ways. You can embed the knowledge map in your website or save it as an image.",
    }]
  }
];

// Create graph that visualises the knowledge
var km = knowledgeMap.create({
  resources: resources,
  plugins: ['hamburger-nodes'],
});

km.defineConcept({
  id: 'what-is-a-km',
  label: 'Blah!'
});
<commit_msg>Update example.<commit_after>"use strict";

// Create the json representation of the knowledge graph
var resources = [
  {
    label: 'Knowledge map introduction',
    teaches: ['What a knowledge map is'],
    content: [{
      text: "Knowledge maps are like a roadmap for pieces of knowledge. They can be used to show others how to navigate from their current set of knowledge to a particular goal. Or they can be used to find people who know something you haven't learnt yet.",
    }]
  },
  {
    label: 'Learn how to view a knowledge map',
    requires: ['What a knowledge map is'],
    teaches: ['How to view a knowledge map'],
    content: [{
      text: "You're doing it right now! Each of the labelled points on the page is called a 'concept' and the arrows joining them are called 'dependencies'. Concepts are pieces of information that can be learned if you have learned all of the concepts which point to it. That is, if you want to learn a concept learn all of its dependencies!",
    }]
  },
  {
    label: 'Learning using knowledge maps',
    requires: ['How to view a knowledge map'],
    teaches: ['Learning with knowledge maps'],
    content: [{
      text: "You can learn by using the resources attached to a concept or by contacting people who know the concept. The best knowledge maps will give you lots of different resources to try and learn each concept.",
    }]
  },
  {
    label: 'Create your own knowledge map',
    requires: ['What a knowledge map is', 'How to view a knowledge map'],
    teaches: ['Creating knowledge maps'],
    content: [{
      text: "If you want to share how to do or learn something then create your own map! This concept links to an interactive demonstration that will allow you to create your own knowledge map.",
    }, {
      description: "If you want to share how to do or learn something then create your own map! This concept links to an interactive demonstration that will allow you to create your own knowledge map.",
      title: "Graph editing demo",
      link: "/demo/edit.html"
    }, {
      description: "If you want to share how to do or learn something then create your own map! This concept links to an interactive demonstration that will allow you to create your own knowledge map.",
      title: "Graph editing demo",
      link: "/demo/edit.html"
    }]
  },
  {
    label: 'Sharing your new knowledge map',
    requires: ['Creating knowledge maps'],
    teaches: ['Sharing knowledge maps'],
    content: [{
      text: "Once you've created your own knowledge map you can share it in various ways. You can embed the knowledge map in your website or save it as an image.",
    }]
  }
];

// Create graph that visualises the knowledge
var km = knowledgeMap.create({
  resources: resources,
  plugins: ['hamburger-nodes'],
});

km.onPreLayout(function(config) {
  config.rankSep(75);
});
km.render();

km.defineConcept({
  id: 'what-a-knowledge-map-is',
  label: 'Blah!'
});
<|endoftext|>


<commit_before>(function(window, document) {
  var createGIFButton = document.querySelector('#create-gif'),
    gifSource = document.querySelector('#GIFSource'),
    gifType = document.querySelector('#GIFType'),
    interval = document.querySelector("#interval"),
    numFrames = document.querySelector("#numFrames"),
    gifHeight = document.querySelector("#gifHeight"),
    gifWidth = document.querySelector("#gifWidth"),
    progressBar = document.querySelector("progress"),
    text = document.querySelector('#gifText'),
    fontWeight = document.querySelector('#fontWeight'),
    fontSize = document.querySelector('#fontSize'),
    fontFamily = document.querySelector('#fontFamily'),
    fontColor = document.querySelector('#fontColor'),
    textAlign = document.querySelector('#textAlign'),
    textBaseline = document.querySelector('#textBaseline'),
    sampleInterval = document.querySelector('#sampleInterval'),
    numWorkers = document.querySelector('#numWorkers'),
    gifshotImagePreview = document.querySelector('.gifshot-image-preview-section'),
    placeholderDiv = document.querySelector('.placeholder-div'),
    placeholderDivDimensions = document.querySelector('.placeholder-div-dimensions'),
    gifshotCode = document.querySelector('.gifshot-code'),
    gifshotCodeTemplate = document.querySelector('.gifshot-code-template'),
    getSelectedOptions = function() {
      return {
        'gifWidth': +gifWidth.value,
        'gifHeight': +gifHeight.value,
        'images': gifSource.value === 'images' ? ['http://i.imgur.com/2OO33vX.jpg', 'http://i.imgur.com/qOwVaSN.png', 'http://i.imgur.com/Vo5mFZJ.gif'] : false,
        'video': gifSource.value === 'video' ? ['example.mp4', 'example.ogv'] : false,
        'interval': +interval.value,
        'numFrames': +numFrames.value,
        'text': text.value,
        'fontWeight': fontWeight.value,
        'fontSize': fontSize.value,
        'fontFamily': fontFamily.value,
        'fontColor': fontColor.value,
        'textAlign': textAlign.value,
        'textBaseline': textBaseline.value,
        'sampleInterval': +sampleInterval.value,
        'numWorkers': +numWorkers.value
      }
    },
    passedOptions,
    updateCodeBlock = function(obj) {
      obj = obj || {};
      var targetElem = obj.targetElem,
        selectedOptions = getSelectedOptions(),
        options = (function() {
          var obj = {};

          _.each(selectedOptions, function(val, key) {
            if(val) {
              obj[key] = val;
            }
          });

          return obj;
        }()),
        template = _.template(gifshotCodeTemplate.innerHTML, {
          gifshot: window.gifshot,
          selectedOptions: options,
          method: gifType.value === 'snapshot' ? 'takeSnapShot' : 'createGIF'
        }),
        code = escodegen.generate(esprima.parse(template), {
          format: {
            safeConcatenation: true
          }
        });

      gifshotCode.innerHTML = code;

      Prism.highlightElement(gifshotCode);

      if (targetElem && (targetElem.id === 'gifWidth' || targetElem.id === 'gifHeight')) {
        if(selectedOptions.gifHeight && selectedOptions.gifWidth) {
          gifshotImagePreview.innerHTML = '';
          placeholderDiv.style.height = selectedOptions.gifHeight + 'px';
          placeholderDiv.style.width = selectedOptions.gifWidth + 'px';
          placeholderDivDimensions.innerHTML = selectedOptions.gifWidth + ' x ' + selectedOptions.gifHeight;
          if(selectedOptions.gifWidth < 60 || selectedOptions.gifHeight < 20) {
            placeholderDivDimensions.classList.add('hidden');
          } else {
            placeholderDivDimensions.classList.remove('hidden');
          }
          placeholderDiv.classList.remove('hidden');
        } else {
          placeholderDiv.classList.add('hidden');
        }
      }
    },
    bindEvents = function() {
      createGIFButton.addEventListener('click', function(e) {
        passedOptions = _.merge(_.clone(getSelectedOptions()), {
          'progressCallback': function(captureProgress) {
            gifshotImagePreview.innerHTML = '';
            placeholderDiv.classList.add('hidden');
            progressBar.classList.remove('hidden');
            progressBar.value = captureProgress;
          }
        });

        var method = gifType.value === 'snapshot' ? 'takeSnapShot' : 'createGIF';

        gifshot[method](passedOptions, function(obj) {
          if (!obj.error) {
            var image = obj.image,
              animatedImage = document.createElement('img');
            animatedImage.src = image;

            progressBar.classList.add('hidden');
            progressBar.value = 0;

            gifshotImagePreview.appendChild(animatedImage);
          } else {
            console.log('obj.error', obj.error);
            console.log('obj.errorCode', obj.errorCode);
            console.log('obj.errorMsg', obj.errorMsg);
          }
        });
      }, false);

      document.addEventListener('change', function(e) {
        updateCodeBlock({
          targetElem: e.target
        });
      });

      document.addEventListener('keyup', function(e) {
        updateCodeBlock({
          targetElem: e.target
        });
      });
    };

    bindEvents();
    updateCodeBlock({
      targetElem: gifWidth
    });
}(window, document));<commit_msg>Fixed minor bug<commit_after>(function(window, document) {
  var createGIFButton = document.querySelector('#create-gif'),
    gifSource = document.querySelector('#GIFSource'),
    gifType = document.querySelector('#GIFType'),
    interval = document.querySelector("#interval"),
    numFrames = document.querySelector("#numFrames"),
    gifHeight = document.querySelector("#gifHeight"),
    gifWidth = document.querySelector("#gifWidth"),
    progressBar = document.querySelector("progress"),
    text = document.querySelector('#gifText'),
    fontWeight = document.querySelector('#fontWeight'),
    fontSize = document.querySelector('#fontSize'),
    fontFamily = document.querySelector('#fontFamily'),
    fontColor = document.querySelector('#fontColor'),
    textAlign = document.querySelector('#textAlign'),
    textBaseline = document.querySelector('#textBaseline'),
    sampleInterval = document.querySelector('#sampleInterval'),
    numWorkers = document.querySelector('#numWorkers'),
    gifshotImagePreview = document.querySelector('.gifshot-image-preview-section'),
    placeholderDiv = document.querySelector('.placeholder-div'),
    placeholderDivDimensions = document.querySelector('.placeholder-div-dimensions'),
    gifshotCode = document.querySelector('.gifshot-code'),
    gifshotCodeTemplate = document.querySelector('.gifshot-code-template'),
    getSelectedOptions = function() {
      return {
        'gifWidth': +gifWidth.value,
        'gifHeight': +gifHeight.value,
        'images': gifSource.value === 'images' ? ['http://i.imgur.com/2OO33vX.jpg', 'http://i.imgur.com/qOwVaSN.png', 'http://i.imgur.com/Vo5mFZJ.gif'] : false,
        'video': gifSource.value === 'video' ? ['example.mp4', 'example.ogv'] : false,
        'interval': +interval.value,
        'numFrames': +numFrames.value,
        'text': text.value,
        'fontWeight': fontWeight.value,
        'fontSize': fontSize.value,
        'fontFamily': fontFamily.value,
        'fontColor': fontColor.value,
        'textAlign': textAlign.value,
        'textBaseline': textBaseline.value,
        'sampleInterval': +sampleInterval.value,
        'numWorkers': +numWorkers.value
      }
    },
    passedOptions,
    updateCodeBlock = function(obj) {
      obj = obj || {};
      var targetElem = obj.targetElem,
        selectedOptions = getSelectedOptions(),
        options = (function() {
          var obj = {};

          _.each(selectedOptions, function(val, key) {
            if(val) {
              obj[key] = val;
            }
          });

          return obj;
        }()),
        template = _.template(gifshotCodeTemplate.innerHTML, {
          gifshot: window.gifshot,
          selectedOptions: options,
          method: gifType.value === 'snapshot' ? 'takeSnapShot' : 'createGIF'
        }),
        code = escodegen.generate(esprima.parse(template), {
          format: {
            safeConcatenation: true
          }
        });

      gifshotCode.innerHTML = code;

      Prism.highlightElement(gifshotCode);

      if (targetElem && (targetElem.id === 'gifWidth' || targetElem.id === 'gifHeight')) {
        if(selectedOptions.gifHeight && selectedOptions.gifWidth) {
          gifshotImagePreview.innerHTML = '';
          placeholderDiv.style.height = selectedOptions.gifHeight + 'px';
          placeholderDiv.style.width = selectedOptions.gifWidth + 'px';
          placeholderDivDimensions.innerHTML = selectedOptions.gifWidth + ' x ' + selectedOptions.gifHeight;
          if(selectedOptions.gifWidth < 60 || selectedOptions.gifHeight < 20) {
            placeholderDivDimensions.classList.add('hidden');
          } else {
            placeholderDivDimensions.classList.remove('hidden');
          }
          placeholderDiv.classList.remove('hidden');
        } else {
          placeholderDiv.classList.add('hidden');
        }
      }
    },
    bindEvents = function() {
      createGIFButton.addEventListener('click', function(e) {
        passedOptions = _.merge(_.clone(getSelectedOptions()), {
          'progressCallback': function(captureProgress) {
            gifshotImagePreview.innerHTML = '';
            placeholderDiv.classList.add('hidden');
            progressBar.classList.remove('hidden');
            progressBar.value = captureProgress;
          }
        });

        var method = gifType.value === 'snapshot' ? 'takeSnapShot' : 'createGIF';

        gifshot[method](passedOptions, function(obj) {
          if (!obj.error) {
            var image = obj.image,
              animatedImage = document.createElement('img');
            animatedImage.src = image;

            progressBar.classList.add('hidden');
            progressBar.value = 0;

            gifshotImagePreview.innerHTML = '';
            gifshotImagePreview.appendChild(animatedImage);
          } else {
            console.log('obj.error', obj.error);
            console.log('obj.errorCode', obj.errorCode);
            console.log('obj.errorMsg', obj.errorMsg);
          }
        });
      }, false);

      document.addEventListener('change', function(e) {
        updateCodeBlock({
          targetElem: e.target
        });
      });

      document.addEventListener('keyup', function(e) {
        updateCodeBlock({
          targetElem: e.target
        });
      });
    };

    bindEvents();
    updateCodeBlock({
      targetElem: gifWidth
    });
}(window, document));<|endoftext|>


<commit_before>import React, { Component } from 'react';
import { compose } from 'recompose';
import { Provider, connect } from 'react-redux';
import classNames from 'classnames';
import {
  ConfigureFlopFlip,
  withFeatureToggle,
  injectFeatureToggle,
  FeatureToggled,
} from '@flopflip/react-redux';
// change to `from '@flopflip/react-broadcast'` and everything will just work wtihout redux
import {
  increment,
  incrementAsync,
  decrement,
  decrementAsync,
} from './modules/counter';
import logo from './logo.svg';
import store from './store';
import './App.css';
import * as flags from './flags';

const UntoggledFeature =
Disabled Feature
;

const IncrementAsyncButton = props => (
  <button onClick={props.incrementAsync} disabled={props.isIncrementing}>
    Increment Async
  </button>
);
const FeatureToggledIncrementAsyncButton = compose(
  withFeatureToggle(flags.INCREMENT_ASYNC_BUTTON, () => UntoggledFeature)
)(IncrementAsyncButton);

const IncrementSyncButton = props => (
  <button
    className={classNames({
      'incrementSyncButton--disabled': props.syncButtonStyle === false,
      'incrementSyncButton--yellow': props.syncButtonStyle === 'yellow',
      'incrementSyncButton--blue': props.syncButtonStyle === 'blue',
      'incrementSyncButton--purple': props.syncButtonStyle === 'purple',
    })}
    onClick={props.increment}
    disabled={props.isIncrementing}
  >
    Increment
  </button>
);
const FeatureToggledIncrementSyncButton = injectFeatureToggle(
  flags.INCREMENT_SYNC_BUTTON,
  'syncButtonStyle'
)(IncrementSyncButton);

const Counter = props => (

Count around

Count: {props.count}

      <FeatureToggledIncrementSyncButton
        increment={props.increment}
        disabled={props.isIncrementing}
      />

      <FeatureToggledIncrementAsyncButton
        incrementAsync={props.incrementAsync}
        isIncrementing={props.isIncrementing}
      />

      <button onClick={props.decrement} disabled={props.isDecrementing}>
        Decrementing
      </button>

      <FeatureToggled
        flag={flags.DECREMENT_ASYNC_BUTTON}
        untoggledComponent={
Disabled Feature
}
      >
        <button onClick={props.decrementAsync} disabled={props.isDecrementing}>
          Decrement Async
        </button>
      </FeatureToggled>

);

const mapStateToProps = state => ({
  count: state.counter.count,
  isIncrementing: state.counter.isIncrementing,
  isDecrementing: state.counter.isDecrementing,
});

const mapDispatchToProps = {
  increment,
  incrementAsync,
  decrement,
  decrementAsync,
};

const ConnectedCounter = connect(mapStateToProps, mapDispatchToProps)(Counter);

const defaultFlags = { 'aDefault-Flag': true };
class App extends Component {
  render() {
    return (
      <Provider store={store}>
        <ConfigureFlopFlip
          clientSideId="596788417a20200c2b70c89e"
          user={{ key: 'ld-2@tdeekens.name' }}
          defaultFlags={defaultFlags}
          shouldChangeUserContext={true}
        >

Welcome to flopflip

            <ConnectedCounter />

        </ConfigureFlopFlip>
      </Provider>
    );
  }
}

export default App;
<commit_msg>docs: update demo<commit_after>import React, { Component } from 'react';
import { compose } from 'recompose';
import { Provider, connect } from 'react-redux';
import classNames from 'classnames';
import {
  ConfigureFlopFlip,
  withFeatureToggle,
  injectFeatureToggle,
  FeatureToggled,
} from '@flopflip/react-redux';
// change to `from '@flopflip/react-broadcast'` and everything will just work wtihout redux
import {
  increment,
  incrementAsync,
  decrement,
  decrementAsync,
} from './modules/counter';
import logo from './logo.svg';
import store from './store';
import './App.css';
import * as flags from './flags';

const UntoggledFeature =
Disabled Feature
;

const IncrementAsyncButton = props => (
  <button onClick={props.incrementAsync} disabled={props.isIncrementing}>
    Increment Async
  </button>
);
const FeatureToggledIncrementAsyncButton = compose(
  withFeatureToggle(
    { flag: flags.INCREMENT_ASYNC_BUTTON },
    () => UntoggledFeature
  )
)(IncrementAsyncButton);

const IncrementSyncButton = props => (
  <button
    className={classNames({
      'incrementSyncButton--disabled': props.syncButtonStyle === false,
      'incrementSyncButton--yellow': props.syncButtonStyle === 'yellow',
      'incrementSyncButton--blue': props.syncButtonStyle === 'blue',
      'incrementSyncButton--purple': props.syncButtonStyle === 'purple',
    })}
    onClick={props.increment}
    disabled={props.isIncrementing}
  >
    Increment
  </button>
);
const FeatureToggledIncrementSyncButton = injectFeatureToggle(
  flags.INCREMENT_SYNC_BUTTON,
  'syncButtonStyle'
)(IncrementSyncButton);

const Counter = props => (

Count around

Count: {props.count}

      <FeatureToggledIncrementSyncButton
        increment={props.increment}
        disabled={props.isIncrementing}
      />

      <FeatureToggledIncrementAsyncButton
        incrementAsync={props.incrementAsync}
        isIncrementing={props.isIncrementing}
      />

      <button onClick={props.decrement} disabled={props.isDecrementing}>
        Decrementing
      </button>

      <FeatureToggled
        flag={flags.DECREMENT_ASYNC_BUTTON}
        untoggledComponent={
Disabled Feature
}
      >
        <button onClick={props.decrementAsync} disabled={props.isDecrementing}>
          Decrement Async
        </button>
      </FeatureToggled>

);

const mapStateToProps = state => ({
  count: state.counter.count,
  isIncrementing: state.counter.isIncrementing,
  isDecrementing: state.counter.isDecrementing,
});

const mapDispatchToProps = {
  increment,
  incrementAsync,
  decrement,
  decrementAsync,
};

const ConnectedCounter = connect(mapStateToProps, mapDispatchToProps)(Counter);

const defaultFlags = { 'aDefault-Flag': true };
class App extends Component {
  render() {
    return (
      <Provider store={store}>
        <ConfigureFlopFlip
          clientSideId="596788417a20200c2b70c89e"
          user={{ key: 'ld-2@tdeekens.name' }}
          defaultFlags={defaultFlags}
          shouldChangeUserContext={true}
        >

Welcome to flopflip

            <ConnectedCounter />

        </ConfigureFlopFlip>
      </Provider>
    );
  }
}

export default App;
<|endoftext|>


<commit_before>MODEL({
  name: 'A',
  properties: [
    'id',
    'a',
    {
      model_: 'ArrayProperty',
      name: 'bs',
      subType: 'B',
      view: 'DAOListView',
      factory: function() { return [B.create({id: 1, b:'b1'})].dao; }
    }
  ]
});

MODEL({
  name: 'B',
  properties: [
    'id',
    'b',
    {
      model_: 'ArrayProperty',
      name: 'cs',
      subType: 'C',
      view: 'DAOListView',
      factory: function() { return [C.create({id: 1, c:'c1'})].dao; }
    }
  ]
});

MODEL({
  name: 'C',
  properties: [
    'id',
    'c'
  ]
});

var dao = EasyDAO.create({model: 'A', daoType: 'MDAO', seqNo: true});

dao.put(A.create({a: 'a1'}));
//dao.put(A.create({a: 'a2'}));

var view1 = DAOListView.create({dao: dao});
var view2 = DAOListView.create({dao: dao});

document.writeln('
View 1
');
view1.write(document);

document.writeln('
View 2
');
view2.write(document);<commit_msg>Added nested Object to nested.html demo.<commit_after>MODEL({
  name: 'C',
  properties: [
    'id',
    'c'
  ]
});

MODEL({
  name: 'B',
  properties: [
    'id',
    'b',
    {
      model_: 'ArrayProperty',
      name: 'cs',
      subType: 'C',
      view: 'DAOListView',
      factory: function() { return [C.create({id: 1, c:'c1'})]; }
    }
  ]
});

MODEL({
  name: 'A',
  properties: [
    'id',
    'a',
    {
      name: 'b',
      subType: 'B',
      view: { model_: 'DetailView', model: B },
      factory: function() { return B.create({id: 1, b:'nested B'}); }
    },
    {
      model_: 'ArrayProperty',
      name: 'bs',
      subType: 'B',
      view: 'DAOListView',
      factory: function() { return [B.create({id: 1, b:'b1'})]; }
    }
  ]
});

var dao = EasyDAO.create({model: 'A', daoType: 'MDAO', seqNo: true});

dao.put(A.create({a: 'a1'}));
//dao.put(A.create({a: 'a2'}));

var view1 = DAOListView.create({dao: dao});
var view2 = DAOListView.create({dao: dao});

document.writeln('
View 1
');
view1.write(document);

document.writeln('
View 2
');
view2.write(document);<|endoftext|>


<commit_before>'use strict'

const {
  env: {
    GITHUB_RELEASE_OAUTH
  }
} = require('process')

const GitHubAPIs = require('github')

const github = new GitHubAPIs()

github.authenticate({
  type: 'token',
  token: GITHUB_RELEASE_OAUTH
})
<commit_msg>Store first<commit_after>'use strict'

const {
  env: {
    GITHUB_RELEASE_OAUTH,
    GIT_REPO_TAG,
    GIT_REPO_OWNER,
    GIT_REPO_NAME
  },
  stdout,
  stderr,
  exit
} = require('process')

const GitHubAPIs = require('github')

const github = new GitHubAPIs()

github.authenticate({
  type: 'token',
  token: GITHUB_RELEASE_OAUTH
})

const {repos} = github

new Promise(
  (resolve, reject) => {
    const user = GIT_REPO_OWNER
    const repo = GIT_REPO_NAME
    const tag_name = GIT_REPO_TAG
    const name = GIT_REPO_TAG
    repos.editRelease({
      user, repo, tag_name, name
    })
      .then(
        () => {
          repos.uploadAsset()
        }
      )
      .catch(reject)
  }
)
  .then(
    () => {
      stdout.write('Deploying succeed.\n')
      exit(0)
    }
  )
  .catch (
    () => {
      stderr.write('Deploying failed.\n')
      exit(1)
    }
  )
<|endoftext|>


<commit_before>import * as utils from 'src/utils';
import { registerBidder } from 'src/adapters/bidderFactory';

const BIDDER_CODE = 'serverbid';

const CONFIG = {
  'serverbid': {
    'BASE_URI': 'https://e.serverbid.com/api/v2'
  },
  'connectad': {
    'BASE_URI': 'https://i.connectad.io/api/v2'
  },
  'onefiftytwo': {
    'BASE_URI': 'https://e.serverbid.com/api/v2'
  },
  'insticator': {
    'BASE_URI': 'https://e.serverbid.com/api/v2'
  }
};

export const spec = {
  code: BIDDER_CODE,
  aliases: ['connectad', 'onefiftytwo', 'insticator', 'adsparc'],

  /**
   * Determines whether or not the given bid request is valid.
   *
   * @param {BidRequest} bid The bid params to validate.
   * @return boolean True if this is a valid bid, and false otherwise.
   */
  isBidRequestValid: function(bid) {
    return !!(bid.params.networkId && bid.params.siteId);
  },

  /**
   * Make a server request from the list of BidRequests.
   *
   * @param {validBidRequests[]} - an array of bids
   * @return ServerRequest Info describing the request to the server.
   */

  buildRequests: function(validBidRequests) {
    // Do we need to group by bidder? i.e. to make multiple requests for
    // different endpoints.

    let ret = {
      method: 'POST',
      url: '',
      data: '',
      bidRequest: []
    };

    if (validBidRequests.length < 1) {
      return ret;
    }

    let ENDPOINT_URL;

    const data = Object.assign({
      placements: [],
      time: Date.now(),
      user: {},
      url: utils.getTopWindowUrl(),
      referrer: document.referrer,
      enableBotFiltering: true,
      includePricingData: true,
      parallel: true
    }, validBidRequests[0].params);

    validBidRequests.map(bid => {
      let config = CONFIG[bid.bidder];
      ENDPOINT_URL = config.BASE_URI;

      const placement = Object.assign({
        divName: bid.bidId,
        adTypes: bid.adTypes || getSize(bid.sizes)
      }, bid.params);

      if (placement.networkId && placement.siteId) {
        data.placements.push(placement);
      }
    });

    ret.data = JSON.stringify(data);
    ret.bidRequest = validBidRequests;
    ret.url = ENDPOINT_URL;

    return ret;
  },

  /**
   * Unpack the response from the server into a list of bids.
   *
   * @param {*} serverResponse A successful response from the server.
   * @return {Bid[]} An array of bids which were nested inside the server.
   */
  interpretResponse: function(serverResponse, bidRequest) {
    let bid;
    let bids;
    let bidId;
    let bidObj;
    let bidResponses = [];

    bids = bidRequest.bidRequest;

    serverResponse = (serverResponse || {}).body;
    for (let i = 0; i < bids.length; i++) {
      bid = {};
      bidObj = bids[i];
      bidId = bidObj.bidId;

      if (serverResponse) {
        const decision = serverResponse.decisions && serverResponse.decisions[bidId];
        const price = decision && decision.pricing && decision.pricing.clearPrice;

        if (decision && price) {
          bid.requestId = bidId;
          bid.cpm = price;
          bid.width = decision.width;
          bid.height = decision.height;
          bid.ad = retrieveAd(decision);
          bid.currency = 'USD';
          bid.creativeId = decision.adId;
          bid.ttl = 360;
          bid.netRevenue = true;
          bid.referrer = utils.getTopWindowUrl();

          bidResponses.push(bid);
        }
      }
    }

    return bidResponses;
  },

  getUserSyncs: function(syncOptions) {
    return [];
  }
};

const sizeMap = [
  null,
  '120x90',
  '120x90',
  '468x60',
  '728x90',
  '300x250',
  '160x600',
  '120x600',
  '300x100',
  '180x150',
  '336x280',
  '240x400',
  '234x60',
  '88x31',
  '120x60',
  '120x240',
  '125x125',
  '220x250',
  '250x250',
  '250x90',
  '0x0',
  '200x90',
  '300x50',
  '320x50',
  '320x480',
  '185x185',
  '620x45',
  '300x125',
  '800x250'
];

sizeMap[77] = '970x90';
sizeMap[123] = '970x250';
sizeMap[43] = '300x600';

function getSize(sizes) {
  const result = [];
  sizes.forEach(function(size) {
    const index = sizeMap.indexOf(size[0] + 'x' + size[1]);
    if (index >= 0) {
      result.push(index);
    }
  });
  return result;
}

function retrieveAd(decision) {
  return decision.contents && decision.contents[0] && decision.contents[0].body + utils.createTrackPixelHtml(decision.impressionUrl);
}

registerBidder(spec);
<commit_msg>Serverbid bid adapter: update alias config (#1963)<commit_after>import * as utils from 'src/utils';
import { registerBidder } from 'src/adapters/bidderFactory';

const BIDDER_CODE = 'serverbid';

const CONFIG = {
  'serverbid': {
    'BASE_URI': 'https://e.serverbid.com/api/v2'
  },
  'connectad': {
    'BASE_URI': 'https://i.connectad.io/api/v2'
  },
  'onefiftytwo': {
    'BASE_URI': 'https://e.serverbid.com/api/v2'
  },
  'insticator': {
    'BASE_URI': 'https://e.serverbid.com/api/v2'
  },
  'adsparc': {
    'BASE_URI': 'https://e.serverbid.com/api/v2'
  }
};

export const spec = {
  code: BIDDER_CODE,
  aliases: ['connectad', 'onefiftytwo', 'insticator', 'adsparc'],

  /**
   * Determines whether or not the given bid request is valid.
   *
   * @param {BidRequest} bid The bid params to validate.
   * @return boolean True if this is a valid bid, and false otherwise.
   */
  isBidRequestValid: function(bid) {
    return !!(bid.params.networkId && bid.params.siteId);
  },

  /**
   * Make a server request from the list of BidRequests.
   *
   * @param {validBidRequests[]} - an array of bids
   * @return ServerRequest Info describing the request to the server.
   */

  buildRequests: function(validBidRequests) {
    // Do we need to group by bidder? i.e. to make multiple requests for
    // different endpoints.

    let ret = {
      method: 'POST',
      url: '',
      data: '',
      bidRequest: []
    };

    if (validBidRequests.length < 1) {
      return ret;
    }

    let ENDPOINT_URL;

    const data = Object.assign({
      placements: [],
      time: Date.now(),
      user: {},
      url: utils.getTopWindowUrl(),
      referrer: document.referrer,
      enableBotFiltering: true,
      includePricingData: true,
      parallel: true
    }, validBidRequests[0].params);

    validBidRequests.map(bid => {
      let config = CONFIG[bid.bidder];
      ENDPOINT_URL = config.BASE_URI;

      const placement = Object.assign({
        divName: bid.bidId,
        adTypes: bid.adTypes || getSize(bid.sizes)
      }, bid.params);

      if (placement.networkId && placement.siteId) {
        data.placements.push(placement);
      }
    });

    ret.data = JSON.stringify(data);
    ret.bidRequest = validBidRequests;
    ret.url = ENDPOINT_URL;

    return ret;
  },

  /**
   * Unpack the response from the server into a list of bids.
   *
   * @param {*} serverResponse A successful response from the server.
   * @return {Bid[]} An array of bids which were nested inside the server.
   */
  interpretResponse: function(serverResponse, bidRequest) {
    let bid;
    let bids;
    let bidId;
    let bidObj;
    let bidResponses = [];

    bids = bidRequest.bidRequest;

    serverResponse = (serverResponse || {}).body;
    for (let i = 0; i < bids.length; i++) {
      bid = {};
      bidObj = bids[i];
      bidId = bidObj.bidId;

      if (serverResponse) {
        const decision = serverResponse.decisions && serverResponse.decisions[bidId];
        const price = decision && decision.pricing && decision.pricing.clearPrice;

        if (decision && price) {
          bid.requestId = bidId;
          bid.cpm = price;
          bid.width = decision.width;
          bid.height = decision.height;
          bid.ad = retrieveAd(decision);
          bid.currency = 'USD';
          bid.creativeId = decision.adId;
          bid.ttl = 360;
          bid.netRevenue = true;
          bid.referrer = utils.getTopWindowUrl();

          bidResponses.push(bid);
        }
      }
    }

    return bidResponses;
  },

  getUserSyncs: function(syncOptions) {
    return [];
  }
};

const sizeMap = [
  null,
  '120x90',
  '120x90',
  '468x60',
  '728x90',
  '300x250',
  '160x600',
  '120x600',
  '300x100',
  '180x150',
  '336x280',
  '240x400',
  '234x60',
  '88x31',
  '120x60',
  '120x240',
  '125x125',
  '220x250',
  '250x250',
  '250x90',
  '0x0',
  '200x90',
  '300x50',
  '320x50',
  '320x480',
  '185x185',
  '620x45',
  '300x125',
  '800x250'
];

sizeMap[77] = '970x90';
sizeMap[123] = '970x250';
sizeMap[43] = '300x600';

function getSize(sizes) {
  const result = [];
  sizes.forEach(function(size) {
    const index = sizeMap.indexOf(size[0] + 'x' + size[1]);
    if (index >= 0) {
      result.push(index);
    }
  });
  return result;
}

function retrieveAd(decision) {
  return decision.contents && decision.contents[0] && decision.contents[0].body + utils.createTrackPixelHtml(decision.impressionUrl);
}

registerBidder(spec);
<|endoftext|>


<commit_before>/**
 * contextMenu.js
 */
"use strict";
{
  const VIEW_SOURCE = "ViewSource";
  const VIEW_MATHML = "ViewMathML";
  const VIEW_SELECTION = "ViewSelection";
  const EDIT_TEXT = "EditText";
  const DATA_ID = "data-with_ex_editor_id";
  const CONTROLS = `${DATA_ID}_controls`;
  const ELEMENT_NODE = 1;
  const TEXT_NODE = 3;

  /* namespace URI */
  const nsURI = {
    extended: false,
    ns: {
      html: "http://www.w3.org/1999/xhtml",
      math: "http://www.w3.org/1998/Math/MathML",
      svg: "http://www.w3.org/2000/svg",
      xmlns: "http://www.w3.org/2000/xmlns/"
    }
  };

  /**
   * get namespace of node from ancestor
   * @param {Object} node - element node
   * @return {Object} - namespace data
   */
  const getNodeNS = node => {
    const ns = {node: null, name: null, uri: null};
    if (node.namespaceURI) {
      ns.node = node;
      ns.name = node.localName;
      ns.uri = node.namespaceURI;
    }
    else {
      while (node && node.parentNode && !ns.node) {
        const obj = node.parentNode;
        node.namespaceURI ? (
          ns.node = node,
          ns.name = node.localName,
          ns.uri = node.namespaceURI
        ) :
        /^foreignObject$/.test(obj.localName) &&
        (obj.hasAttributeNS(nsURI.ns.svg, "requiredExtensions") ||
         document.documentElement.localName === "html") ? (
          ns.node = node,
          ns.name = node.localName,
          ns.uri = obj.hasAttributeNS(nsURI.ns.svg, "requiredExtensions") &&
                     obj.getAttributeNS(nsURI.ns.svg, "requiredExtensions") ||
                     nsURI.ns.html
        ) :
        /^(?:math|svg)$/.test(node.localName) ? (
          ns.node = node,
          ns.name = node.localName,
          ns.uri = nsURI.ns[node.localName]
        ) :
          node = obj;
      }
      !ns.node && (
        node = document.documentElement,
        ns.node = node,
        ns.name = node.localName,
        ns.uri = node.hasAttribute("xmlns") && node.getAttribute("xmlns") ||
                 nsURI.ns[node.localName.toLowerCase()] || ""
      );
    }
    return ns;
  };

  /**
   * get namespace URI
   * @param {Object} node - element node or attribute node
   * @param {boolean} bool - use getNodeNS
   * @return {Object} - namespace URI data
   */
  const getNsURI = (node, bool) =>
    node && {
      namespaceURI: node.namespaceURI || node.prefix && nsURI.ns[node.prefix] ||
                    bool && getNodeNS(node).uri || ""
    } || null;

  /**
   * create element NS
   * @param {Object} elm - element
   * @return {Object} - namespaced element
   */
  const createElmNS = elm => {
    const ns = getNsURI(elm, true);
    return ns && document.createElementNS(
             ns.namespaceURI || nsURI.ns.html,
             elm.prefix && `${elm.prefix}:${elm.localName}` || elm.localName
           );
  };

  /**
   * set attribute NS
   * @param {Object} elm - element to append attributes
   * @param {Object} node - node to get attributes from
   * @return {void}
   */
  const setAttrNS = (elm, node) => {
    if (elm && node) {
      const nodeAttr = node.attributes;
      for (let attr of nodeAttr) {
        const ns = getNsURI(attr, false);
        typeof node[attr.name] !== "function" && ns && elm.setAttributeNS(
          ns.namespaceURI || "",
          attr.prefix && `${attr.prefix}:${attr.localName}` || attr.localName,
          attr.value
        );
      }
    }
  };

  /**
   * create namespaced element
   * @param {Object} node - element node to create element from
   * @param {boolean} bool - append child nodes
   * @return {Object} - namespaced element or text node
   */
  const getElement = (node, bool = false) => {
    /**
     * append child nodes
     * @param {Object} nodes - child nodes
     * @return {Object} - document fragment
     */
    const appendChildNodes = nodes => {
      const fragment = document.createDocumentFragment();
      if (nodes instanceof NodeList) {
        for (let child of nodes) {
          child.nodeType === ELEMENT_NODE ? (
            child === child.parentNode.firstChild &&
              fragment.appendChild(document.createTextNode("\n")),
            child = getElement(child, true),
            child instanceof Node && fragment.appendChild(child)
          ) :
          child.nodeType === TEXT_NODE &&
            fragment.appendChild(document.createTextNode(child.nodeValue));
        }
      }
      return fragment;
    };

    let elm;
    node && (elm = createElmNS(node)) && (
      node.attributes && setAttrNS(elm, node),
      bool && node.hasChildNodes() &&
        elm.appendChild(appendChildNodes(node.childNodes))
    );
    return elm || document.createTextNode("");
  };

  /**
   * create DOM
   * @param {Object} nodes - child nodes
   * @return {Object} - document fragment
   */
  const createDom = nodes => {
    const fragment = document.createDocumentFragment();
    if (nodes instanceof NodeList) {
      const l = nodes.length;
      let i = 0;
      while (i < l) {
        let obj = nodes[i];
        obj.nodeType === ELEMENT_NODE ?
          (obj = getElement(obj, true)) && obj instanceof Node && (
            i === 0 && fragment.appendChild(document.createTextNode("\n")),
            fragment.appendChild(obj),
            i === l - 1 && fragment.appendChild(document.createTextNode("\n"))
          ) :
        obj.nodeType === TEXT_NODE &&
          fragment.appendChild(document.createTextNode(obj.nodeValue));
        i++;
      }
    }
    return fragment;
  };

  /**
   * create DOM tree
   * @param {Object} elm - container element of the DOM tree
   * @param {Object} node - node containing child nodes to append
   * @return {Object} - DOM tree or text node
   */
  const getDomTree = (elm, node = null) => {
    elm = getElement(elm);
    elm.nodeType === 1 && node && node.hasChildNodes() &&
      elm.appendChild(createDom(node.childNodes));
    return elm;
  };

  /**
   * create DOM of MathML
   * @param {Object} node - element node of MathML
   * @return {?string} - serialized node string
   */
  const onViewMathML = node => {
    let elm, range;
    while (node && node.parentNode && !elm) {
      node.localName === "math" && (elm = node);
      node = node.parentNode;
    }
    elm && (
      range = document.createRange(),
      range.selectNodeContents(elm),
      elm = getDomTree(elm, range.cloneContents())
    );
    return elm && elm.hasChildNodes() && window.XMLSerializer &&
             (new XMLSerializer()).serializeToString(elm) || null;
  };

  /**
   * create DOM from selection range
   * @param {Object} sel - selection
   * @return {?string} - serialized node string
   */
  const onViewSelection = sel => {
    let fragment = document.createDocumentFragment();
    if (sel && sel.rangeCount) {
      const l = sel.rangeCount;
      let i = 0, obj;
      while (i < l) {
        const range = sel.getRangeAt(i);
        const ancestor = range.commonAncestorContainer;
        l > 1 && fragment.appendChild(document.createTextNode("\n"));
        if (ancestor.nodeType === ELEMENT_NODE) {
          obj = getNodeNS(ancestor);
          if (/^(?:svg|math)$/.test(obj.name)) {
            if (obj.node === document.documentElement) {
              fragment = null;
              break;
            }
            else {
              obj.node.parentNode && (
                obj = obj.node.parentNode,
                range.setStart(obj, 0),
                range.setEnd(obj, obj.childNodes.length)
              );
            }
          }
          (obj = getDomTree(ancestor, range.cloneContents())) &&
          obj instanceof Node &&
            fragment.appendChild(obj);
        }
        else {
          ancestor.nodeType === TEXT_NODE &&
          (obj = getElement(ancestor.parentNode)) &&
          obj instanceof Node && (
            obj.appendChild(range.cloneContents()),
            fragment.appendChild(obj)
          );
        }
        fragment.appendChild(document.createTextNode("\n"));
        l > 1 && i < l - 1 &&
          fragment.appendChild(document.createComment("Next Range"));
        i++;
      }
      l > 1 && fragment.hasChildNodes() &&
      (obj = getElement(document.documentElement)) && obj instanceof Node && (
        obj.appendChild(fragment),
        fragment = document.createDocumentFragment(),
        fragment.appendChild(obj),
        fragment.appendChild(document.createTextNode("\n"))
      );
    }
    return fragment && fragment.hasChildNodes() && window.XMLSerializer &&
             (new XMLSerializer()).serializeToString(fragment) || null;
  };

  /**
   * get text node
   * @param {Object} nodes - child nodes
   * @return {string} - text
   */
  const getTextNode = nodes => {
    const arr = [];
    if (nodes instanceof NodeList) {
      for (let node of nodes) {
        node.nodeType === TEXT_NODE ? arr.push(node.nodeValue) :
        node.nodeType === ELEMENT_NODE && (
          node.localName === "br" ? arr.push("\n") :
          node.hasChildNodes() && arr.push(getTextNode(node.childNodes))
        );
      }
    }
    return arr.join("");
  };

  /**
   * get text node from editable content
   * @param {Object} node - node
   * @return {string} - text
   */
  const onContentEditable = node =>
    node && node.hasChildNodes() && getTextNode(node.childNodes) || "";

  /**
   * post temporary ID value
   * @param {Object} evt - event
   * @return {void}
   */
  const postTemporaryId = evt => {
    const elm = evt && evt.target === evt.currentTarget && evt.target;
    let attr = elm && (
                 elm.hasAttributeNS("", DATA_ID) &&
                 elm.getAttributeNS("", DATA_ID) ||
                 elm.hasAttributeNS("", CONTROLS) &&
                 elm.getAttributeNS("", CONTROLS)
               );
    if (attr) {
      attr = attr.split(" ");
      for (let value of attr) {
        window.self.postMessage(value);
      }
    }
  };

  /**
   * set temporary ID to the target element and set event listener
   * @param {Object} elm - target element
   * @return {?string} - ID
   */
  const getId = elm => {
    let id = null;
    if (elm) {
      const html = !elm.namespaceURI || elm.namespaceURI === nsURI.ns.html;
      const ns = !html && nsURI.ns.html || "";
      elm.hasAttributeNS(ns, DATA_ID) ?
        id = elm.getAttributeNS(ns, DATA_ID) : (
        id = `withExEditor${window.performance.now()}`.replace(/\./, "_"),
        !html &&
          elm.setAttributeNS(nsURI.ns.xmlns, "xmlns:html", nsURI.ns.html),
        elm.setAttributeNS(ns, html ? DATA_ID : `html:${DATA_ID}`, id),
        html && elm.addEventListener("focus", postTemporaryId, false)
      );
    }
    return id;
  };

  /**
   * get isContentEditable node from ancestor
   * @param {Object} node - element node
   * @return {boolean}
   */
  const getIsContentEditableNode = node => {
    let bool = false, elm = node;
    while (elm && elm.parentNode) {
      if (typeof elm.isContentEditable === "boolean" &&
          (!elm.namespaceURI || elm.namespaceURI === nsURI.ns.html)) {
        bool = elm.isContentEditable;
        break;
      }
      elm = elm.parentNode;
    }
    if (bool) {
      const id = getId(node);
      const arr = elm.hasAttributeNS("", CONTROLS) &&
                    (elm.getAttributeNS("", CONTROLS)).split(" ");
      id && (
        arr ? (
          arr.push(id),
          elm.setAttributeNS(
            "",
            CONTROLS,
            (arr.filter((v, i, o) => o.indexOf(v) === i)).join(" ")
          )
        ) : (
          elm.setAttributeNS("", CONTROLS, id),
          elm.addEventListener("focus", postTemporaryId, false)
        )
      );
    }
    return bool;
  };

  /**
   * node content is editable or not
   * @param {Object} node - element node
   * @return {boolean}
   */
  const nodeContentIsEditable = node => {
    let isText = false;
    if (node && node.namespaceURI && node.namespaceURI !== nsURI.ns.html &&
        node.hasChildNodes()) {
      const nodes = node.childNodes;
      for (let child of nodes) {
        isText = child.nodeType === TEXT_NODE;
        if (!isText) {
          break;
        }
      }
    }
    return isText && getIsContentEditableNode(node);
  };

  /* set context menu item label */
  window.self.on("context", elm => {
    const sel = window.getSelection();
    window.self.postMessage(
      /^input$/.test(elm.localName) && elm.hasAttribute("type") &&
      /^(?:(?:emai|te|ur)l|search|text)$/.test(elm.getAttribute("type")) ||
      /^textarea$/.test(elm.localName) || elm.isContentEditable ||
      sel.anchorNode === sel.focusNode && nodeContentIsEditable(elm) ?
        EDIT_TEXT :
      sel.isCollapsed ?
      getNodeNS(elm).uri === nsURI.ns.math ?
        VIEW_MATHML :
        VIEW_SOURCE :
        VIEW_SELECTION
    );
    return true;
  });

  /* switch mode by context */
  window.self.on("click", (elm, data) => {
    const mode = {
      mode: VIEW_SOURCE,
      charset: window.top.document.characterSet,
      target: null,
      value: null,
      namespace: null
    };
    const sel = window.getSelection();
    let obj;
    !nsURI.extended && data && (
      nsURI.ns = JSON.parse(data),
      nsURI.extended = true
    );
    sel.isCollapsed ?
      (/^input$/.test(elm.localName) && elm.hasAttribute("type") &&
       /^(?:(?:emai|te|ur)l|search|text)$/.test(elm.getAttribute("type")) ||
       /^textarea$/.test(elm.localName)) && (obj = getId(elm)) ? (
        mode.mode = EDIT_TEXT,
        mode.target = obj,
        mode.value = elm.value || ""
      ) :
      (elm.isContentEditable || nodeContentIsEditable(elm)) &&
      (obj = getId(elm)) ? (
        mode.mode = EDIT_TEXT,
        mode.target = obj,
        mode.value = onContentEditable(elm),
        mode.namespace = getNodeNS(elm).uri
      ) :
      getNodeNS(elm).uri === nsURI.ns.math && (obj = onViewMathML(elm)) && (
        mode.mode = VIEW_MATHML,
        mode.value = obj
      ) :
    (sel.anchorNode !== sel.focusNode ||
     sel.anchorNode.parentNode !== document.documentElement) && (
      sel.rangeCount === 1 &&
      (elm.isContentEditable ||
       sel.anchorNode === sel.focusNode && nodeContentIsEditable(elm)) &&
      (obj = getId(elm)) ? (
        mode.mode = EDIT_TEXT,
        mode.target = obj,
        mode.value = onContentEditable(elm),
        mode.namespace = getNodeNS(elm).uri
      ) :
      (obj = onViewSelection(sel)) && (
        mode.mode = VIEW_SELECTION,
        mode.value = obj
      )
    );
    window.self.postMessage(JSON.stringify(mode));
  });
}
<commit_msg>Removed unnecessary detection<commit_after>/**
 * contextMenu.js
 */
"use strict";
{
  const VIEW_SOURCE = "ViewSource";
  const VIEW_MATHML = "ViewMathML";
  const VIEW_SELECTION = "ViewSelection";
  const EDIT_TEXT = "EditText";
  const DATA_ID = "data-with_ex_editor_id";
  const CONTROLS = `${DATA_ID}_controls`;
  const ELEMENT_NODE = 1;
  const TEXT_NODE = 3;

  /* namespace URI */
  const nsURI = {
    extended: false,
    ns: {
      html: "http://www.w3.org/1999/xhtml",
      math: "http://www.w3.org/1998/Math/MathML",
      svg: "http://www.w3.org/2000/svg",
      xmlns: "http://www.w3.org/2000/xmlns/"
    }
  };

  /**
   * get namespace of node from ancestor
   * @param {Object} node - element node
   * @return {Object} - namespace data
   */
  const getNodeNS = node => {
    const ns = {node: null, name: null, uri: null};
    if (node.namespaceURI) {
      ns.node = node;
      ns.name = node.localName;
      ns.uri = node.namespaceURI;
    }
    else {
      while (node && node.parentNode && !ns.node) {
        const obj = node.parentNode;
        node.namespaceURI ? (
          ns.node = node,
          ns.name = node.localName,
          ns.uri = node.namespaceURI
        ) :
        /^foreignObject$/.test(obj.localName) &&
        (obj.hasAttributeNS(nsURI.ns.svg, "requiredExtensions") ||
         document.documentElement.localName === "html") ? (
          ns.node = node,
          ns.name = node.localName,
          ns.uri = obj.hasAttributeNS(nsURI.ns.svg, "requiredExtensions") &&
                     obj.getAttributeNS(nsURI.ns.svg, "requiredExtensions") ||
                     nsURI.ns.html
        ) :
        /^(?:math|svg)$/.test(node.localName) ? (
          ns.node = node,
          ns.name = node.localName,
          ns.uri = nsURI.ns[node.localName]
        ) :
          node = obj;
      }
      !ns.node && (
        node = document.documentElement,
        ns.node = node,
        ns.name = node.localName,
        ns.uri = node.hasAttribute("xmlns") && node.getAttribute("xmlns") ||
                 nsURI.ns[node.localName.toLowerCase()] || ""
      );
    }
    return ns;
  };

  /**
   * get namespace URI
   * @param {Object} node - element node or attribute node
   * @param {boolean} bool - use getNodeNS
   * @return {Object} - namespace URI data
   */
  const getNsURI = (node, bool) =>
    node && {
      namespaceURI: node.namespaceURI || node.prefix && nsURI.ns[node.prefix] ||
                    bool && getNodeNS(node).uri || ""
    } || null;

  /**
   * create element NS
   * @param {Object} elm - element
   * @return {Object} - namespaced element
   */
  const createElmNS = elm => {
    const ns = getNsURI(elm, true);
    return ns && document.createElementNS(
             ns.namespaceURI || nsURI.ns.html,
             elm.prefix && `${elm.prefix}:${elm.localName}` || elm.localName
           );
  };

  /**
   * set attribute NS
   * @param {Object} elm - element to append attributes
   * @param {Object} node - node to get attributes from
   * @return {void}
   */
  const setAttrNS = (elm, node) => {
    if (elm && node) {
      const nodeAttr = node.attributes;
      for (let attr of nodeAttr) {
        const ns = getNsURI(attr, false);
        typeof node[attr.name] !== "function" && ns && elm.setAttributeNS(
          ns.namespaceURI || "",
          attr.prefix && `${attr.prefix}:${attr.localName}` || attr.localName,
          attr.value
        );
      }
    }
  };

  /**
   * create namespaced element
   * @param {Object} node - element node to create element from
   * @param {boolean} bool - append child nodes
   * @return {Object} - namespaced element or text node
   */
  const getElement = (node, bool = false) => {
    /**
     * append child nodes
     * @param {Object} nodes - child nodes
     * @return {Object} - document fragment
     */
    const appendChildNodes = nodes => {
      const fragment = document.createDocumentFragment();
      if (nodes instanceof NodeList) {
        for (let child of nodes) {
          child.nodeType === ELEMENT_NODE ? (
            child === child.parentNode.firstChild &&
              fragment.appendChild(document.createTextNode("\n")),
            child = getElement(child, true),
            child instanceof Node && fragment.appendChild(child)
          ) :
          child.nodeType === TEXT_NODE &&
            fragment.appendChild(document.createTextNode(child.nodeValue));
        }
      }
      return fragment;
    };

    let elm;
    node && (elm = createElmNS(node)) && (
      node.attributes && setAttrNS(elm, node),
      bool && node.hasChildNodes() &&
        elm.appendChild(appendChildNodes(node.childNodes))
    );
    return elm || document.createTextNode("");
  };

  /**
   * create DOM
   * @param {Object} nodes - child nodes
   * @return {Object} - document fragment
   */
  const createDom = nodes => {
    const fragment = document.createDocumentFragment();
    if (nodes instanceof NodeList) {
      const l = nodes.length;
      let i = 0;
      while (i < l) {
        let obj = nodes[i];
        obj.nodeType === ELEMENT_NODE ?
          (obj = getElement(obj, true)) && obj instanceof Node && (
            i === 0 && fragment.appendChild(document.createTextNode("\n")),
            fragment.appendChild(obj),
            i === l - 1 && fragment.appendChild(document.createTextNode("\n"))
          ) :
        obj.nodeType === TEXT_NODE &&
          fragment.appendChild(document.createTextNode(obj.nodeValue));
        i++;
      }
    }
    return fragment;
  };

  /**
   * create DOM tree
   * @param {Object} elm - container element of the DOM tree
   * @param {Object} node - node containing child nodes to append
   * @return {Object} - DOM tree or text node
   */
  const getDomTree = (elm, node = null) => {
    elm = getElement(elm);
    elm.nodeType === 1 && node && node.hasChildNodes() &&
      elm.appendChild(createDom(node.childNodes));
    return elm;
  };

  /**
   * create DOM of MathML
   * @param {Object} node - element node of MathML
   * @return {?string} - serialized node string
   */
  const onViewMathML = node => {
    let elm, range;
    while (node && node.parentNode && !elm) {
      node.localName === "math" && (elm = node);
      node = node.parentNode;
    }
    elm && (
      range = document.createRange(),
      range.selectNodeContents(elm),
      elm = getDomTree(elm, range.cloneContents())
    );
    return elm && elm.hasChildNodes() &&
             (new XMLSerializer()).serializeToString(elm) || null;
  };

  /**
   * create DOM from selection range
   * @param {Object} sel - selection
   * @return {?string} - serialized node string
   */
  const onViewSelection = sel => {
    let fragment = document.createDocumentFragment();
    if (sel && sel.rangeCount) {
      const l = sel.rangeCount;
      let i = 0, obj;
      while (i < l) {
        const range = sel.getRangeAt(i);
        const ancestor = range.commonAncestorContainer;
        l > 1 && fragment.appendChild(document.createTextNode("\n"));
        if (ancestor.nodeType === ELEMENT_NODE) {
          obj = getNodeNS(ancestor);
          if (/^(?:svg|math)$/.test(obj.name)) {
            if (obj.node === document.documentElement) {
              fragment = null;
              break;
            }
            else {
              obj.node.parentNode && (
                obj = obj.node.parentNode,
                range.setStart(obj, 0),
                range.setEnd(obj, obj.childNodes.length)
              );
            }
          }
          (obj = getDomTree(ancestor, range.cloneContents())) &&
          obj instanceof Node &&
            fragment.appendChild(obj);
        }
        else {
          ancestor.nodeType === TEXT_NODE &&
          (obj = getElement(ancestor.parentNode)) &&
          obj instanceof Node && (
            obj.appendChild(range.cloneContents()),
            fragment.appendChild(obj)
          );
        }
        fragment.appendChild(document.createTextNode("\n"));
        l > 1 && i < l - 1 &&
          fragment.appendChild(document.createComment("Next Range"));
        i++;
      }
      l > 1 && fragment.hasChildNodes() &&
      (obj = getElement(document.documentElement)) && obj instanceof Node && (
        obj.appendChild(fragment),
        fragment = document.createDocumentFragment(),
        fragment.appendChild(obj),
        fragment.appendChild(document.createTextNode("\n"))
      );
    }
    return fragment && fragment.hasChildNodes() &&
             (new XMLSerializer()).serializeToString(fragment) || null;
  };

  /**
   * get text node
   * @param {Object} nodes - child nodes
   * @return {string} - text
   */
  const getTextNode = nodes => {
    const arr = [];
    if (nodes instanceof NodeList) {
      for (let node of nodes) {
        node.nodeType === TEXT_NODE ? arr.push(node.nodeValue) :
        node.nodeType === ELEMENT_NODE && (
          node.localName === "br" ? arr.push("\n") :
          node.hasChildNodes() && arr.push(getTextNode(node.childNodes))
        );
      }
    }
    return arr.join("");
  };

  /**
   * get text node from editable content
   * @param {Object} node - node
   * @return {string} - text
   */
  const onContentEditable = node =>
    node && node.hasChildNodes() && getTextNode(node.childNodes) || "";

  /**
   * post temporary ID value
   * @param {Object} evt - event
   * @return {void}
   */
  const postTemporaryId = evt => {
    const elm = evt && evt.target === evt.currentTarget && evt.target;
    let attr = elm && (
                 elm.hasAttributeNS("", DATA_ID) &&
                 elm.getAttributeNS("", DATA_ID) ||
                 elm.hasAttributeNS("", CONTROLS) &&
                 elm.getAttributeNS("", CONTROLS)
               );
    if (attr) {
      attr = attr.split(" ");
      for (let value of attr) {
        window.self.postMessage(value);
      }
    }
  };

  /**
   * set temporary ID to the target element and set event listener
   * @param {Object} elm - target element
   * @return {?string} - ID
   */
  const getId = elm => {
    let id = null;
    if (elm) {
      const html = !elm.namespaceURI || elm.namespaceURI === nsURI.ns.html;
      const ns = !html && nsURI.ns.html || "";
      elm.hasAttributeNS(ns, DATA_ID) ?
        id = elm.getAttributeNS(ns, DATA_ID) : (
        id = `withExEditor${window.performance.now()}`.replace(/\./, "_"),
        !html &&
          elm.setAttributeNS(nsURI.ns.xmlns, "xmlns:html", nsURI.ns.html),
        elm.setAttributeNS(ns, html ? DATA_ID : `html:${DATA_ID}`, id),
        html && elm.addEventListener("focus", postTemporaryId, false)
      );
    }
    return id;
  };

  /**
   * get isContentEditable node from ancestor
   * @param {Object} node - element node
   * @return {boolean}
   */
  const getIsContentEditableNode = node => {
    let bool = false, elm = node;
    while (elm && elm.parentNode) {
      if (typeof elm.isContentEditable === "boolean" &&
          (!elm.namespaceURI || elm.namespaceURI === nsURI.ns.html)) {
        bool = elm.isContentEditable;
        break;
      }
      elm = elm.parentNode;
    }
    if (bool) {
      const id = getId(node);
      const arr = elm.hasAttributeNS("", CONTROLS) &&
                    (elm.getAttributeNS("", CONTROLS)).split(" ");
      id && (
        arr ? (
          arr.push(id),
          elm.setAttributeNS(
            "",
            CONTROLS,
            (arr.filter((v, i, o) => o.indexOf(v) === i)).join(" ")
          )
        ) : (
          elm.setAttributeNS("", CONTROLS, id),
          elm.addEventListener("focus", postTemporaryId, false)
        )
      );
    }
    return bool;
  };

  /**
   * node content is editable or not
   * @param {Object} node - element node
   * @return {boolean}
   */
  const nodeContentIsEditable = node => {
    let isText = false;
    if (node && node.namespaceURI && node.namespaceURI !== nsURI.ns.html &&
        node.hasChildNodes()) {
      const nodes = node.childNodes;
      for (let child of nodes) {
        isText = child.nodeType === TEXT_NODE;
        if (!isText) {
          break;
        }
      }
    }
    return isText && getIsContentEditableNode(node);
  };

  /* set context menu item label */
  window.self.on("context", elm => {
    const sel = window.getSelection();
    window.self.postMessage(
      /^input$/.test(elm.localName) && elm.hasAttribute("type") &&
      /^(?:(?:emai|te|ur)l|search|text)$/.test(elm.getAttribute("type")) ||
      /^textarea$/.test(elm.localName) || elm.isContentEditable ||
      sel.anchorNode === sel.focusNode && nodeContentIsEditable(elm) ?
        EDIT_TEXT :
      sel.isCollapsed ?
      getNodeNS(elm).uri === nsURI.ns.math ?
        VIEW_MATHML :
        VIEW_SOURCE :
        VIEW_SELECTION
    );
    return true;
  });

  /* switch mode by context */
  window.self.on("click", (elm, data) => {
    const mode = {
      mode: VIEW_SOURCE,
      charset: window.top.document.characterSet,
      target: null,
      value: null,
      namespace: null
    };
    const sel = window.getSelection();
    let obj;
    !nsURI.extended && data && (
      nsURI.ns = JSON.parse(data),
      nsURI.extended = true
    );
    sel.isCollapsed ?
      (/^input$/.test(elm.localName) && elm.hasAttribute("type") &&
       /^(?:(?:emai|te|ur)l|search|text)$/.test(elm.getAttribute("type")) ||
       /^textarea$/.test(elm.localName)) && (obj = getId(elm)) ? (
        mode.mode = EDIT_TEXT,
        mode.target = obj,
        mode.value = elm.value || ""
      ) :
      (elm.isContentEditable || nodeContentIsEditable(elm)) &&
      (obj = getId(elm)) ? (
        mode.mode = EDIT_TEXT,
        mode.target = obj,
        mode.value = onContentEditable(elm),
        mode.namespace = getNodeNS(elm).uri
      ) :
      getNodeNS(elm).uri === nsURI.ns.math && (obj = onViewMathML(elm)) && (
        mode.mode = VIEW_MATHML,
        mode.value = obj
      ) :
    (sel.anchorNode !== sel.focusNode ||
     sel.anchorNode.parentNode !== document.documentElement) && (
      sel.rangeCount === 1 &&
      (elm.isContentEditable ||
       sel.anchorNode === sel.focusNode && nodeContentIsEditable(elm)) &&
      (obj = getId(elm)) ? (
        mode.mode = EDIT_TEXT,
        mode.target = obj,
        mode.value = onContentEditable(elm),
        mode.namespace = getNodeNS(elm).uri
      ) :
      (obj = onViewSelection(sel)) && (
        mode.mode = VIEW_SELECTION,
        mode.value = obj
      )
    );
    window.self.postMessage(JSON.stringify(mode));
  });
}
<|endoftext|>